[Pkg-cli-libs-commits] [powerpack] 01/01: Imported Upstream version 2.0.0.1+git20140911+dfsg

Jo Shields directhex at moszumanska.debian.org
Thu Oct 2 11:36:55 UTC 2014


This is an automated email from the git hooks/post-receive script.

directhex pushed a commit to annotated tag upstream/2.0.0.1+git20140911+dfsg
in repository powerpack.

commit 883d20060676a22e8867a56f15b0b9dd31f454f2
Author: Jo Shields <jo.shields at xamarin.com>
Date:   Thu Oct 2 12:34:59 2014 +0100

    Imported Upstream version 2.0.0.1+git20140911+dfsg
---
 License.html                                       |  209 +
 README.md                                          |   40 +
 .../Fsharp.Compiler.CodeDom.fsproj                 |   54 +
 .../Fsharp.Compiler.CodeDom.fsproj.vspscc          |   10 +
 .../assemblyinfo.FSharp.Compiler.CodeDom.dll.fs    |    7 +
 src/FSharp.Compiler.CodeDom/codedomvisitor.fs      |  101 +
 src/FSharp.Compiler.CodeDom/codeprovider.fs        |  302 +
 src/FSharp.Compiler.CodeDom/codeprovider.fsi       |   15 +
 src/FSharp.Compiler.CodeDom/compiler.fs            |  176 +
 src/FSharp.Compiler.CodeDom/generator.fs           | 1812 ++++++
 src/FSharp.PowerPack.Build.Tasks/FSLex.Build.fs    |  111 +
 src/FSharp.PowerPack.Build.Tasks/FSLex.Build.fsi   |   26 +
 src/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fs   |  124 +
 src/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fsi  |   28 +
 .../FSharp.PowerPack.Build.Tasks.fsproj            |   58 +
 .../FSharp.PowerPack.Build.Tasks.fsproj.vspscc     |   10 +
 .../FSharp.PowerPack.targets                       |   84 +
 ...ssemblyinfo.FSharp.PowerPack.Build.Tasks.dll.fs |    7 +
 src/FSharp.PowerPack.Compatibility/Compat.Array.fs |  110 +
 .../Compat.Array.fsi                               |   81 +
 .../Compat.Array2D.fs                              |   33 +
 .../Compat.Array2D.fsi                             |   27 +
 src/FSharp.PowerPack.Compatibility/Compat.List.fs  |  140 +
 src/FSharp.PowerPack.Compatibility/Compat.List.fsi |  126 +
 src/FSharp.PowerPack.Compatibility/Compat.Seq.fs   |   21 +
 src/FSharp.PowerPack.Compatibility/Compat.Seq.fsi  |   14 +
 .../Compat.String.fs                               |  111 +
 .../Compat.String.fsi                              |   99 +
 .../FSharp.PowerPack.Compatibility.fsproj          |  184 +
 .../FSharp.PowerPack.Compatibility.fsproj.vspscc   |   10 +
 src/FSharp.PowerPack.Compatibility/arg.fs          |   29 +
 src/FSharp.PowerPack.Compatibility/arg.fsi         |   50 +
 src/FSharp.PowerPack.Compatibility/assemblyinfo.fs |   30 +
 src/FSharp.PowerPack.Compatibility/buffer.fs       |   33 +
 src/FSharp.PowerPack.Compatibility/buffer.fsi      |   57 +
 src/FSharp.PowerPack.Compatibility/byte.fs         |   44 +
 src/FSharp.PowerPack.Compatibility/byte.fsi        |   76 +
 src/FSharp.PowerPack.Compatibility/char.fs         |   21 +
 src/FSharp.PowerPack.Compatibility/char.fsi        |   23 +
 src/FSharp.PowerPack.Compatibility/filename.fs     |   52 +
 src/FSharp.PowerPack.Compatibility/filename.fsi    |   63 +
 src/FSharp.PowerPack.Compatibility/float.fs        |   56 +
 src/FSharp.PowerPack.Compatibility/float.fsi       |   55 +
 src/FSharp.PowerPack.Compatibility/hashtbl.fs      |   80 +
 src/FSharp.PowerPack.Compatibility/hashtbl.fsi     |  139 +
 src/FSharp.PowerPack.Compatibility/int16.fs        |   39 +
 src/FSharp.PowerPack.Compatibility/int32.fs        |   60 +
 src/FSharp.PowerPack.Compatibility/int32.fsi       |  105 +
 src/FSharp.PowerPack.Compatibility/int64.fs        |   55 +
 src/FSharp.PowerPack.Compatibility/int64.fsi       |  100 +
 src/FSharp.PowerPack.Compatibility/lazy.fs         |   13 +
 src/FSharp.PowerPack.Compatibility/lazy.fsi        |   29 +
 src/FSharp.PowerPack.Compatibility/lexing.fs       |   68 +
 src/FSharp.PowerPack.Compatibility/lexing.fsi      |   99 +
 src/FSharp.PowerPack.Compatibility/map.fs          |   46 +
 src/FSharp.PowerPack.Compatibility/map.fsi         |   58 +
 src/FSharp.PowerPack.Compatibility/obj.fs          |   16 +
 src/FSharp.PowerPack.Compatibility/obj.fsi         |   38 +
 src/FSharp.PowerPack.Compatibility/parsing.fs      |   43 +
 src/FSharp.PowerPack.Compatibility/parsing.fsi     |   57 +
 src/FSharp.PowerPack.Compatibility/pervasives.fs   |  710 +++
 src/FSharp.PowerPack.Compatibility/pervasives.fsi  |  795 +++
 src/FSharp.PowerPack.Compatibility/printexc.fs     |   18 +
 src/FSharp.PowerPack.Compatibility/printexc.fsi    |   16 +
 src/FSharp.PowerPack.Compatibility/sbyte.fs        |   47 +
 src/FSharp.PowerPack.Compatibility/set.fs          |   96 +
 src/FSharp.PowerPack.Compatibility/set.fsi         |   86 +
 src/FSharp.PowerPack.Compatibility/sys.fs          |   66 +
 src/FSharp.PowerPack.Compatibility/sys.fsi         |   85 +
 src/FSharp.PowerPack.Compatibility/uint32.fs       |   59 +
 src/FSharp.PowerPack.Compatibility/uint32.fsi      |   61 +
 src/FSharp.PowerPack.Compatibility/uint64.fs       |   44 +
 src/FSharp.PowerPack.Compatibility/uint64.fsi      |   55 +
 src/FSharp.PowerPack.Linq/Assembly.fs              |    8 +
 .../FSharp.PowerPack.Linq.fsproj                   |   54 +
 .../FSharp.PowerPack.Linq.fsproj.vspscc            |   10 +
 src/FSharp.PowerPack.Linq/FuncConvertExtensions.fs |   28 +
 .../FuncConvertExtensions.fsi                      |   40 +
 src/FSharp.PowerPack.Linq/Linq.fs                  |  881 +++
 src/FSharp.PowerPack.Linq/Linq.fsi                 |  164 +
 src/FSharp.PowerPack.Linq/LinqQueries.fs           |  781 +++
 src/FSharp.PowerPack.Linq/LinqQueries.fsi          |   62 +
 .../assemblyinfo.FSharp.PowerPack.Linq.dll.fs      |    7 +
 src/FSharp.PowerPack.Metadata/FSComp.fs            | 4243 +++++++++++++
 .../FSharp.PowerPack.Metadata.fsproj               |   84 +
 .../FSharp.PowerPack.Metadata.fsproj.vspscc        |   10 +
 src/FSharp.PowerPack.Metadata/FlatList.fs          |   44 +
 src/FSharp.PowerPack.Metadata/Metadata.fs          | 1315 ++++
 src/FSharp.PowerPack.Metadata/Metadata.fsi         |  470 ++
 src/FSharp.PowerPack.Metadata/Prelude.fs           |  354 ++
 src/FSharp.PowerPack.Metadata/PrettyNaming.fs      |  241 +
 src/FSharp.PowerPack.Metadata/QueueList.fs         |   64 +
 .../assemblyinfo.FSharp.PowerPack.Metadata.dll.fs  |    8 +
 src/FSharp.PowerPack.Metadata/env.fs               |   33 +
 src/FSharp.PowerPack.Metadata/il.fs                | 1671 +++++
 src/FSharp.PowerPack.Metadata/pickle.fs            | 1369 ++++
 src/FSharp.PowerPack.Metadata/tast.fs              | 2694 ++++++++
 src/FSharp.PowerPack.Metadata/tastops.fs           |   61 +
 src/FSharp.PowerPack.Parallel.Seq/Assembly.fs      |    6 +
 .../FSharp.PowerPack.Parallel.Seq.fsproj           |   51 +
 .../FSharp.PowerPack.Parallel.Seq.fsproj.vspscc    |   10 +
 ...semblyinfo.FSharp.PowerPack.Parallel.Seq.dll.fs |    7 +
 src/FSharp.PowerPack.Parallel.Seq/pseq.fs          |  286 +
 src/FSharp.PowerPack.Parallel.Seq/pseq.fsi         |  956 +++
 src/FSharp.PowerPack.Parallel.Seq/pseq.fsx         |   49 +
 .../FSharp.PowerPack.Unittests.v40.fsproj          |   78 +
 .../FSharp.PowerPack.Unittests.v40.fsproj.vspscc   |   10 +
 .../LibraryTestFx.fs                               |   67 +
 src/FSharp.PowerPack.Unittests.v40/SeqModule.fs    |  790 +++
 src/FSharp.PowerPack.Unittests.v40/SeqModule2.fs   | 1210 ++++
 src/FSharp.PowerPack.Unittests.v40/Utilities.fs    |  125 +
 .../ASP.NET/AspNetIntro/App_Code/logic.fs          |   15 +
 .../ASP.NET/AspNetIntro/DataBinding.aspx           |   30 +
 .../ASP.NET/AspNetIntro/DataBinding.aspx.fs        |   22 +
 .../ASP.NET/AspNetIntro/Default.aspx               |   24 +
 .../ASP.NET/AspNetIntro/Default.aspx.fs            |   32 +
 .../ASP.NET/AspNetIntro/web.config                 |   14 +
 .../ASP.NET/AspNetTester.fs                        |  297 +
 .../ASP.NET/PersonalWebSite/Admin/Albums.aspx      |  104 +
 .../ASP.NET/PersonalWebSite/Admin/Albums.aspx.fs   |   19 +
 .../ASP.NET/PersonalWebSite/Admin/Details.aspx     |   42 +
 .../ASP.NET/PersonalWebSite/Admin/Details.aspx.fs  |   24 +
 .../ASP.NET/PersonalWebSite/Admin/Photos.aspx      |  114 +
 .../ASP.NET/PersonalWebSite/Admin/Photos.aspx.fs   |   40 +
 .../ASP.NET/PersonalWebSite/Albums.aspx            |   60 +
 .../ASP.NET/PersonalWebSite/Albums.aspx.fs         |   20 +
 .../PersonalWebSite/App_Code/PhotoManager.fs       |  203 +
 .../ASP.NET/PersonalWebSite/App_Data/ASPNETDB.MDF  |  Bin 0 -> 2293760 bytes
 .../ASP.NET/PersonalWebSite/App_Data/Personal.mdf  |  Bin 0 -> 1310720 bytes
 .../PersonalWebSite/App_Data/Personal_log.ldf      |  Bin 0 -> 516096 bytes
 .../PersonalWebSite/App_Data/aspnetdb_log.ldf      |  Bin 0 -> 516096 bytes
 .../PersonalWebSite/App_Data/personal-add.sql      |  203 +
 .../PersonalWebSite/App_Data/personal-remove.sql   |   55 +
 .../PersonalWebSite/App_Themes/Black/Default.css   |  326 +
 .../PersonalWebSite/App_Themes/Black/Default.skin  |   41 +
 .../App_Themes/Black/Images/album-bstretch.gif     |  Bin 0 -> 90 bytes
 .../App_Themes/Black/Images/album-l1.gif           |  Bin 0 -> 61 bytes
 .../App_Themes/Black/Images/album-l2.gif           |  Bin 0 -> 541 bytes
 .../App_Themes/Black/Images/album-l3.gif           |  Bin 0 -> 159 bytes
 .../App_Themes/Black/Images/album-l4.gif           |  Bin 0 -> 61 bytes
 .../App_Themes/Black/Images/album-lstretch.gif     |  Bin 0 -> 90 bytes
 .../App_Themes/Black/Images/album-mbl.gif          |  Bin 0 -> 301 bytes
 .../App_Themes/Black/Images/album-mbr.gif          |  Bin 0 -> 299 bytes
 .../App_Themes/Black/Images/album-mtl.gif          |  Bin 0 -> 146 bytes
 .../App_Themes/Black/Images/album-mtr.gif          |  Bin 0 -> 297 bytes
 .../App_Themes/Black/Images/album-r1.gif           |  Bin 0 -> 76 bytes
 .../App_Themes/Black/Images/album-r2.gif           |  Bin 0 -> 507 bytes
 .../App_Themes/Black/Images/album-r3.gif           |  Bin 0 -> 166 bytes
 .../App_Themes/Black/Images/album-r4.gif           |  Bin 0 -> 76 bytes
 .../App_Themes/Black/Images/album-rstretch.gif     |  Bin 0 -> 90 bytes
 .../App_Themes/Black/Images/album-tstretch.gif     |  Bin 0 -> 64 bytes
 .../App_Themes/Black/Images/background.gif         |  Bin 0 -> 84 bytes
 .../App_Themes/Black/Images/bullet-1.gif           |  Bin 0 -> 181 bytes
 .../App_Themes/Black/Images/bullet-2.gif           |  Bin 0 -> 184 bytes
 .../App_Themes/Black/Images/button-add.gif         |  Bin 0 -> 545 bytes
 .../App_Themes/Black/Images/button-cancel.gif      |  Bin 0 -> 556 bytes
 .../App_Themes/Black/Images/button-create.gif      |  Bin 0 -> 1078 bytes
 .../App_Themes/Black/Images/button-delete.gif      |  Bin 0 -> 558 bytes
 .../App_Themes/Black/Images/button-download.gif    |  Bin 0 -> 1014 bytes
 .../App_Themes/Black/Images/button-dwn_res.gif     |  Bin 0 -> 1014 bytes
 .../App_Themes/Black/Images/button-edit.gif        |  Bin 0 -> 551 bytes
 .../App_Themes/Black/Images/button-first.jpg       |  Bin 0 -> 882 bytes
 .../App_Themes/Black/Images/button-gallery.jpg     |  Bin 0 -> 1214 bytes
 .../App_Themes/Black/Images/button-import.gif      |  Bin 0 -> 549 bytes
 .../App_Themes/Black/Images/button-insert.gif      |  Bin 0 -> 551 bytes
 .../App_Themes/Black/Images/button-last.jpg        |  Bin 0 -> 815 bytes
 .../App_Themes/Black/Images/button-login.gif       |  Bin 0 -> 1050 bytes
 .../App_Themes/Black/Images/button-next.jpg        |  Bin 0 -> 863 bytes
 .../App_Themes/Black/Images/button-play.jpg        |  Bin 0 -> 669 bytes
 .../App_Themes/Black/Images/button-prev.jpg        |  Bin 0 -> 851 bytes
 .../App_Themes/Black/Images/button-rename.gif      |  Bin 0 -> 574 bytes
 .../App_Themes/Black/Images/button-save.gif        |  Bin 0 -> 487 bytes
 .../App_Themes/Black/Images/button-tog24.jpg       |  Bin 0 -> 1044 bytes
 .../App_Themes/Black/Images/button-tog8.jpg        |  Bin 0 -> 1063 bytes
 .../App_Themes/Black/Images/footer.gif             |  Bin 0 -> 4795 bytes
 .../App_Themes/Black/Images/frame-bot--x.gif       |  Bin 0 -> 68 bytes
 .../App_Themes/Black/Images/frame-bot-x-.gif       |  Bin 0 -> 54 bytes
 .../App_Themes/Black/Images/frame-botx--.gif       |  Bin 0 -> 68 bytes
 .../App_Themes/Black/Images/frame-mid--x.gif       |  Bin 0 -> 54 bytes
 .../App_Themes/Black/Images/frame-midx--.gif       |  Bin 0 -> 54 bytes
 .../App_Themes/Black/Images/frame-top--x.gif       |  Bin 0 -> 68 bytes
 .../App_Themes/Black/Images/frame-top-x-.gif       |  Bin 0 -> 54 bytes
 .../App_Themes/Black/Images/frame-topx--.gif       |  Bin 0 -> 68 bytes
 .../App_Themes/Black/Images/header.gif             |  Bin 0 -> 6082 bytes
 .../App_Themes/Black/Images/photonav.gif           |  Bin 0 -> 10644 bytes
 .../App_Themes/Black/Images/spacer.gif             |  Bin 0 -> 43 bytes
 .../PersonalWebSite/App_Themes/Black/frame.css     |  197 +
 .../PersonalWebSite/App_Themes/White/Default.css   |  325 +
 .../PersonalWebSite/App_Themes/White/Default.skin  |   40 +
 .../PersonalWebSite/App_Themes/White/Frame.css     |  194 +
 .../App_Themes/White/Images/album-bstretch.gif     |  Bin 0 -> 90 bytes
 .../App_Themes/White/Images/album-l1.gif           |  Bin 0 -> 78 bytes
 .../App_Themes/White/Images/album-l2.gif           |  Bin 0 -> 482 bytes
 .../App_Themes/White/Images/album-l3.gif           |  Bin 0 -> 215 bytes
 .../App_Themes/White/Images/album-l4.gif           |  Bin 0 -> 106 bytes
 .../App_Themes/White/Images/album-lstretch.gif     |  Bin 0 -> 90 bytes
 .../App_Themes/White/Images/album-mbl.gif          |  Bin 0 -> 343 bytes
 .../App_Themes/White/Images/album-mbr.gif          |  Bin 0 -> 328 bytes
 .../App_Themes/White/Images/album-mtl.gif          |  Bin 0 -> 157 bytes
 .../App_Themes/White/Images/album-mtr.gif          |  Bin 0 -> 279 bytes
 .../App_Themes/White/Images/album-r1.gif           |  Bin 0 -> 78 bytes
 .../App_Themes/White/Images/album-r2.gif           |  Bin 0 -> 482 bytes
 .../App_Themes/White/Images/album-r3.gif           |  Bin 0 -> 175 bytes
 .../App_Themes/White/Images/album-r4.gif           |  Bin 0 -> 108 bytes
 .../App_Themes/White/Images/album-rstretch.gif     |  Bin 0 -> 90 bytes
 .../App_Themes/White/Images/album-tstretch.gif     |  Bin 0 -> 90 bytes
 .../App_Themes/White/Images/background.gif         |  Bin 0 -> 331 bytes
 .../App_Themes/White/Images/body-repeat-photo.gif  |  Bin 0 -> 397 bytes
 .../App_Themes/White/Images/body-repeat.gif        |  Bin 0 -> 138 bytes
 .../App_Themes/White/Images/bullet-1.gif           |  Bin 0 -> 132 bytes
 .../App_Themes/White/Images/bullet-2.gif           |  Bin 0 -> 192 bytes
 .../App_Themes/White/Images/button-add.gif         |  Bin 0 -> 373 bytes
 .../App_Themes/White/Images/button-cancel.gif      |  Bin 0 -> 388 bytes
 .../App_Themes/White/Images/button-create.gif      |  Bin 0 -> 760 bytes
 .../App_Themes/White/Images/button-delete.gif      |  Bin 0 -> 394 bytes
 .../App_Themes/White/Images/button-download.gif    |  Bin 0 -> 901 bytes
 .../App_Themes/White/Images/button-dwn_res.gif     |  Bin 0 -> 836 bytes
 .../App_Themes/White/Images/button-edit.gif        |  Bin 0 -> 379 bytes
 .../App_Themes/White/Images/button-first.gif       |  Bin 0 -> 436 bytes
 .../App_Themes/White/Images/button-gallery.gif     |  Bin 0 -> 531 bytes
 .../App_Themes/White/Images/button-import.gif      |  Bin 0 -> 399 bytes
 .../App_Themes/White/Images/button-insert.gif      |  Bin 0 -> 384 bytes
 .../App_Themes/White/Images/button-last.gif        |  Bin 0 -> 434 bytes
 .../App_Themes/White/Images/button-login.gif       |  Bin 0 -> 702 bytes
 .../App_Themes/White/Images/button-next.gif        |  Bin 0 -> 425 bytes
 .../App_Themes/White/Images/button-play.gif        |  Bin 0 -> 492 bytes
 .../App_Themes/White/Images/button-prev.gif        |  Bin 0 -> 425 bytes
 .../App_Themes/White/Images/button-rename.gif      |  Bin 0 -> 409 bytes
 .../App_Themes/White/Images/button-save.gif        |  Bin 0 -> 342 bytes
 .../App_Themes/White/Images/button-tog24.gif       |  Bin 0 -> 427 bytes
 .../App_Themes/White/Images/button-tog8.gif        |  Bin 0 -> 453 bytes
 .../App_Themes/White/Images/content-shim-none.gif  |  Bin 0 -> 636 bytes
 .../App_Themes/White/Images/content-shim-photo.gif |  Bin 0 -> 1521 bytes
 .../White/Images/content-shim-stretch.gif          |  Bin 0 -> 65 bytes
 .../App_Themes/White/Images/content-shim.gif       |  Bin 0 -> 755 bytes
 .../App_Themes/White/Images/footer-side.gif        |  Bin 0 -> 176 bytes
 .../App_Themes/White/Images/footer.gif             |  Bin 0 -> 4883 bytes
 .../App_Themes/White/Images/frame-bot--x.gif       |  Bin 0 -> 68 bytes
 .../App_Themes/White/Images/frame-bot-x-.gif       |  Bin 0 -> 50 bytes
 .../App_Themes/White/Images/frame-botx--.gif       |  Bin 0 -> 68 bytes
 .../App_Themes/White/Images/frame-mid--x.gif       |  Bin 0 -> 50 bytes
 .../App_Themes/White/Images/frame-midx--.gif       |  Bin 0 -> 50 bytes
 .../App_Themes/White/Images/frame-top--x.gif       |  Bin 0 -> 68 bytes
 .../App_Themes/White/Images/frame-top-x-.gif       |  Bin 0 -> 50 bytes
 .../App_Themes/White/Images/frame-topx--.gif       |  Bin 0 -> 68 bytes
 .../App_Themes/White/Images/header.gif             |  Bin 0 -> 4717 bytes
 .../App_Themes/White/Images/photonav-bg.gif        |  Bin 0 -> 105 bytes
 .../App_Themes/White/Images/photonav-top-bg.gif    |  Bin 0 -> 46 bytes
 .../App_Themes/White/Images/spacer.gif             |  Bin 0 -> 43 bytes
 .../ASP.NET/PersonalWebSite/Default.aspx           |  100 +
 .../ASP.NET/PersonalWebSite/Default.aspx.fs        |   26 +
 .../ASP.NET/PersonalWebSite/Default.master         |   50 +
 .../ASP.NET/PersonalWebSite/Default.master.fs      |   19 +
 .../ASP.NET/PersonalWebSite/Details.aspx           |   61 +
 .../ASP.NET/PersonalWebSite/Details.aspx.fs        |   26 +
 .../ASP.NET/PersonalWebSite/Doc.html               |   41 +
 .../ASP.NET/PersonalWebSite/Download.aspx          |   40 +
 .../ASP.NET/PersonalWebSite/Download.aspx.fs       |   26 +
 .../ASP.NET/PersonalWebSite/Global.asax            |   20 +
 .../ASP.NET/PersonalWebSite/Handler.ashx           |   50 +
 .../PersonalWebSite/Images/placeholder-100.jpg     |  Bin 0 -> 840 bytes
 .../PersonalWebSite/Images/placeholder-200.jpg     |  Bin 0 -> 1719 bytes
 .../PersonalWebSite/Images/placeholder-600.jpg     |  Bin 0 -> 5334 bytes
 .../PersonalWebSite/Images/resume-photo.jpg        |  Bin 0 -> 1719 bytes
 .../ASP.NET/PersonalWebSite/Links.aspx             |   71 +
 .../ASP.NET/PersonalWebSite/Links.aspx.fs          |   17 +
 .../ASP.NET/PersonalWebSite/PersonalWebSite.sln    |   35 +
 .../ASP.NET/PersonalWebSite/Photos.aspx            |   51 +
 .../ASP.NET/PersonalWebSite/Photos.aspx.fs         |   28 +
 .../ASP.NET/PersonalWebSite/Register.aspx          |   21 +
 .../ASP.NET/PersonalWebSite/Register.aspx.fs       |   17 +
 .../ASP.NET/PersonalWebSite/Resume.aspx            |   79 +
 .../ASP.NET/PersonalWebSite/Resume.aspx.fs         |   17 +
 .../ASP.NET/PersonalWebSite/Welcome.html           |  304 +
 .../ASP.NET/PersonalWebSite/web.config             |   87 +
 .../ASP.NET/PersonalWebSite/web.sitemap            |   18 +
 .../ASP.NET/Time/AsyncTime.aspx                    |   88 +
 .../ASP.NET/Time/AsyncTime2.aspx                   |   28 +
 .../ASP.NET/Time/AsyncTime2.aspx.fs                |   90 +
 .../ASP.NET/Time/Time.aspx                         |   37 +
 .../ASP.NET/Time/Time2.aspx                        |   27 +
 .../ASP.NET/Time/Time2.aspx.fs                     |   25 +
 .../ASP.NET/Time/Web.config                        |   12 +
 .../ASP.NET/VerySimple/App_Code/CodeBehind.fs      |   11 +
 .../ASP.NET/VerySimple/Default.aspx                |    6 +
 .../ASP.NET/VerySimple/Default.aspx.fs             |   17 +
 .../ASP.NET/VerySimple/web.config                  |   61 +
 .../AsyncStreamReaderTest.fs                       |  229 +
 src/FSharp.PowerPack.Unittests/BigRationalTests.fs |  611 ++
 src/FSharp.PowerPack.Unittests/ColllectionTests.fs |  185 +
 src/FSharp.PowerPack.Unittests/CompatTests.fs      |  792 +++
 src/FSharp.PowerPack.Unittests/ControlTests.fs     |  527 ++
 .../FSharp.PowerPack.Unittests.fsproj              |  131 +
 .../FSharp.PowerPack.Unittests.fsproj.vspscc       |   10 +
 src/FSharp.PowerPack.Unittests/HashtblTests.fs     |   93 +
 src/FSharp.PowerPack.Unittests/LazyListTests.fs    |  137 +
 src/FSharp.PowerPack.Unittests/LibraryTestFx.fs    |   47 +
 .../MatrixVectorTests.fs                           | 1686 +++++
 src/FSharp.PowerPack.Unittests/MetadataTests.fs    |  425 ++
 src/FSharp.PowerPack.Unittests/NORTHWND.MDF        |  Bin 0 -> 3932160 bytes
 .../NUnitFrameworkShims.fs                         |   79 +
 src/FSharp.PowerPack.Unittests/NativeArrayTests.fs |  554 ++
 src/FSharp.PowerPack.Unittests/PermutationTests.fs |   44 +
 src/FSharp.PowerPack.Unittests/QueryTests.fs       |  418 ++
 .../QuotationEvalTests.fs                          | 1473 +++++
 src/FSharp.PowerPack.Unittests/SetMapTests.fs      |  245 +
 .../StructuredFormatTests.fs                       |   11 +
 src/FSharp.PowerPack.Unittests/Utilities.fs        |  125 +
 src/FSharp.PowerPack.Unittests/northwnd.cs         | 4136 ++++++++++++
 src/FSharp.PowerPack/Arg.fs                        |  133 +
 src/FSharp.PowerPack/Arg.fsi                       |   50 +
 src/FSharp.PowerPack/AssemblyInfo.fs               |   25 +
 src/FSharp.PowerPack/AsyncOperations.fs            |  167 +
 src/FSharp.PowerPack/AsyncOperations.fsi           |   81 +
 src/FSharp.PowerPack/AsyncStreamReader.fs          |  429 ++
 src/FSharp.PowerPack/AsyncStreamReader.fsi         |   89 +
 src/FSharp.PowerPack/AsyncWorker.fs                |   65 +
 src/FSharp.PowerPack/AsyncWorker.fsi               |   20 +
 src/FSharp.PowerPack/CompilerLocationUtils.fs      |  242 +
 src/FSharp.PowerPack/FSharp.PowerPack.fsproj       |  117 +
 .../FSharp.PowerPack.fsproj.vspscc                 |   10 +
 src/FSharp.PowerPack/HashMultiMap.fs               |  166 +
 src/FSharp.PowerPack/HashMultiMap.fsi              |   84 +
 src/FSharp.PowerPack/HashSet.fs                    |   54 +
 src/FSharp.PowerPack/HashSet.fsi                   |   59 +
 src/FSharp.PowerPack/Lazy.fs                       |    6 +
 src/FSharp.PowerPack/Lazy.fsi                      |    7 +
 src/FSharp.PowerPack/LazyList.fs                   |  262 +
 src/FSharp.PowerPack/LazyList.fsi                  |  189 +
 src/FSharp.PowerPack/Lexing.fs                     |  423 ++
 src/FSharp.PowerPack/Lexing.fsi                    |  151 +
 src/FSharp.PowerPack/Measure.fs                    |   15 +
 src/FSharp.PowerPack/Measure.fsi                   |   25 +
 src/FSharp.PowerPack/NativeArray.fs                |  106 +
 src/FSharp.PowerPack/NativeArray.fsi               |  159 +
 src/FSharp.PowerPack/Parsing.fs                    |  509 ++
 src/FSharp.PowerPack/Parsing.fsi                   |  130 +
 src/FSharp.PowerPack/Permutation.fs                |   56 +
 src/FSharp.PowerPack/Permutation.fsi               |   43 +
 src/FSharp.PowerPack/PhysicalConstants.fs          |   91 +
 src/FSharp.PowerPack/PowerPack.fs                  |   35 +
 src/FSharp.PowerPack/ResizeArray.fs                |  321 +
 src/FSharp.PowerPack/ResizeArray.fsi               |  240 +
 src/FSharp.PowerPack/SI.fs                         |  113 +
 src/FSharp.PowerPack/StructuredFormat.fs           | 1020 +++
 src/FSharp.PowerPack/StructuredFormat.fsi          |  188 +
 src/FSharp.PowerPack/TaggedCollections.fs          | 1179 ++++
 src/FSharp.PowerPack/TaggedCollections.fsi         |  225 +
 src/FSharp.PowerPack/TaggedHash.fs                 |   59 +
 src/FSharp.PowerPack/TaggedHash.fsi                |   89 +
 src/FSharp.PowerPack/math/INumeric.fs              |  241 +
 src/FSharp.PowerPack/math/INumeric.fsi             |   82 +
 src/FSharp.PowerPack/math/NativeArrayExtensions.fs |   51 +
 .../math/NativeArrayExtensions.fsi                 |   27 +
 src/FSharp.PowerPack/math/associations.fs          |   61 +
 src/FSharp.PowerPack/math/associations.fsi         |   28 +
 src/FSharp.PowerPack/math/complex.fs               |  130 +
 src/FSharp.PowerPack/math/complex.fsi              |  136 +
 src/FSharp.PowerPack/math/matrix.fs                | 2563 ++++++++
 src/FSharp.PowerPack/math/matrix.fsi               | 1100 ++++
 src/FSharp.PowerPack/math/q.fs                     |  305 +
 src/FSharp.PowerPack/math/q.fsi                    |   92 +
 src/FSharpPowerPackSource.Settings.targets         |   26 +
 src/FSharpPowerPackSource.targets                  |   36 +
 src/FsHtmlDoc/FsHtmlDoc.fs                         | 1291 ++++
 src/FsHtmlDoc/FsHtmlDoc.fsproj                     |   48 +
 src/FsHtmlDoc/FsHtmlDoc.fsproj.vspscc              |   10 +
 src/FsHtmlDoc/assemblyinfo.fshtmldoc.exe.fs        |    8 +
 src/FsHtmlDoc/msdn.css                             |  229 +
 src/FsLex/FsLex.fsproj                             |   75 +
 src/FsLex/FsLex.fsproj.vspscc                      |   10 +
 src/FsLex/assemblyinfo.fslex.exe.fs                |    8 +
 src/FsLex/fslex.fs                                 |  225 +
 src/FsLex/fslexast.fs                              |  409 ++
 src/FsLex/fslexlex.fsl                             |  208 +
 src/FsLex/fslexpars.fsy                            |   55 +
 src/FsYacc/FsYacc.fsproj                           |   78 +
 src/FsYacc/FsYacc.fsproj.vspscc                    |   10 +
 src/FsYacc/assemblyinfo.fsyacc.exe.fs              |    7 +
 src/FsYacc/fsyacc.fs                               |  531 ++
 src/FsYacc/fsyaccast.fs                            |  965 +++
 src/FsYacc/fsyacclex.fsl                           |  144 +
 src/FsYacc/fsyaccpars.fsy                          |   55 +
 src/MsiInstaller/License.rtf                       |  267 +
 src/MsiInstaller/build-msi.bat                     |   58 +
 src/MsiInstaller/generateWixFileEntries.fsx        |  314 +
 src/MsiInstaller/install.lst                       |   41 +
 src/MsiInstaller/product.wxs                       |  232 +
 src/SilverlightTester/App.xaml                     |    8 +
 src/SilverlightTester/App.xaml.cs                  |   68 +
 src/SilverlightTester/MainPage.xaml                |   13 +
 src/SilverlightTester/MainPage.xaml.cs             |  130 +
 src/SilverlightTester/Properties/AppManifest.xml   |    6 +
 src/SilverlightTester/Properties/AssemblyInfo.cs   |   35 +
 .../Properties/OutOfBrowserSettings.xml            |   10 +
 src/SilverlightTester/SilverlightTester.csproj     |  118 +
 .../SilverlightTester.csproj.user                  |   28 +
 src/SilverlightTester/SilverlightTester.sln        |   20 +
 src/Unittests/UnitTests.PowerPack.fsproj           |   78 +
 src/assemblyinfo.Common.fs                         |    4 +
 src/buildSilverlight.bat                           |   16 +
 src/fsppack.vs2008.sln                             |   86 +
 src/fsppack.vs2010.sln                             |  130 +
 src/fsppack.vs2010.vssscc                          |   10 +
 .../FSharp.SRGen.Build.Tasks.fsproj                |   60 +
 .../FSharp.SRGen.Build.Tasks/FSharp.SRGen.targets  |   65 +
 .../FsSrGen/FSharp.SRGen.Build.Tasks/FsSrGen.fs    |   46 +
 workyard/FsSrGen/FsSrGen/FsSrGen.fsproj            |   60 +
 workyard/FsSrGen/FsSrGen/Program.fs                |  426 ++
 .../charting/FSharp.PowerPack.Plot.Excel.fsproj    |   48 +
 .../charting/FSharp.PowerPack.Plot.Neutral.fsproj  |   42 +
 .../charting/FSharp.PowerPack.Plot.Xceed.fsproj    |   88 +
 workyard/charting/FSharp.PowerPack.Plot.fsproj     |   36 +
 workyard/charting/excel.fs                         |  595 ++
 workyard/charting/neutral.fs                       |  119 +
 workyard/charting/plot.fs                          |  187 +
 workyard/charting/xceed.fs                         |  812 +++
 workyard/linq/FSharp.PowerPack.Linq/Assembly.fs    |    8 +
 .../FSharp.PowerPack.Linq.fsproj                   |   57 +
 .../FSharp.PowerPack.Linq.fsproj.vspscc            |   10 +
 .../FSharp.PowerPack.Linq.xml                      |  959 +++
 .../FSharp.PowerPack.Linq/FuncConvertExtensions.fs |   28 +
 .../FuncConvertExtensions.fsi                      |   40 +
 workyard/linq/FSharp.PowerPack.Linq/Linq.fs        |  936 +++
 workyard/linq/FSharp.PowerPack.Linq/Linq.fsi       |  171 +
 workyard/linq/FSharp.PowerPack.Linq/LinqQueries.fs |  831 +++
 .../linq/FSharp.PowerPack.Linq/LinqQueries.fsi     |   61 +
 .../linq/FSharp.PowerPack.Linq/MutableTuple.fs     |  181 +
 .../linq/FSharp.PowerPack.Linq/QueryExtensions.fs  |  434 ++
 .../assemblyinfo.FSharp.PowerPack.Linq.dll.fs      |    7 +
 .../FSharp.PowerPack.Unittests.v40.fsproj          |   88 +
 .../FSharp.PowerPack.Unittests.v40.fsproj.vspscc   |   10 +
 .../LibraryTestFx.fs                               |   67 +
 .../FSharp.PowerPack.Unittests.v40/SeqModule.fs    |  790 +++
 .../FSharp.PowerPack.Unittests.v40/SeqModule2.fs   | 1210 ++++
 .../FSharp.PowerPack.Unittests.v40/Utilities.fs    |  129 +
 .../AsyncStreamReaderTest.fs                       |  229 +
 .../FSharp.PowerPack.Unittests/BigRationalTests.fs |  611 ++
 .../FSharp.PowerPack.Unittests/ColllectionTests.fs |  185 +
 .../linq/FSharp.PowerPack.Unittests/CompatTests.fs |  792 +++
 .../FSharp.PowerPack.Unittests/ControlTests.fs     |  527 ++
 .../FSharp.PowerPack.Unittests.fsproj              |  119 +
 .../FSharp.PowerPack.Unittests.fsproj.vspscc       |   10 +
 .../FSharp.PowerPack.Unittests/HashtblTests.fs     |   93 +
 .../FSharp.PowerPack.Unittests/LazyListTests.fs    |  137 +
 .../FSharp.PowerPack.Unittests/LibraryTestFx.fs    |   47 +
 .../Entities.Northwind/Entities.Northwind.csproj   |   67 +
 .../Linq/Entities.Northwind/Northwind.Designer.cs  | 6713 ++++++++++++++++++++
 .../Linq/Entities.Northwind/Northwind.edmx         | 1738 +++++
 .../Entities.Northwind/Properties/AssemblyInfo.cs  |   36 +
 .../LinqToSql.Northwind/LinqToSql.Northwind.csproj |   83 +
 .../Linq/LinqToSql.Northwind/Northwind.dbml        |  412 ++
 .../Linq/LinqToSql.Northwind/Northwind.dbml.layout |  271 +
 .../Linq/LinqToSql.Northwind/Northwind.designer.cs | 6397 +++++++++++++++++++
 .../LinqToSql.Northwind/Properties/AssemblyInfo.cs |   36 +
 .../Properties/Settings.Designer.cs                |   38 +
 .../Properties/Settings.settings                   |   14 +
 .../Linq/LinqToSql.Northwind/app.config            |   10 +
 .../MatrixVectorTests.fs                           | 1686 +++++
 .../FSharp.PowerPack.Unittests/MetadataTests.fs    |  425 ++
 .../linq/FSharp.PowerPack.Unittests/NORTHWND.MDF   |  Bin 0 -> 3932160 bytes
 .../FSharp.PowerPack.Unittests/NORTHWND_log.ldf    |  Bin 0 -> 1048576 bytes
 .../NUnitFrameworkShims.fs                         |   79 +
 .../FSharp.PowerPack.Unittests/NativeArrayTests.fs |  554 ++
 .../FSharp.PowerPack.Unittests/PermutationTests.fs |   44 +
 .../linq/FSharp.PowerPack.Unittests/QueryTests.fs  |  451 ++
 .../QuotationEvalTests.fs                          | 1473 +++++
 .../linq/FSharp.PowerPack.Unittests/SetMapTests.fs |  245 +
 .../StructuredFormatTests.fs                       |   11 +
 .../linq/FSharp.PowerPack.Unittests/Utilities.fs   |  129 +
 .../linq/FSharpPowerPackSource.Settings.targets    |   26 +
 workyard/linq/FSharpPowerPackSource.targets        |   36 +
 workyard/linq/assemblyinfo.Common.fs               |    4 +
 .../lapack/FSharp.PowerPack.Math.Providers.fsproj  |   45 +
 workyard/math-provider/lapack/build.bat            |    6 +
 workyard/math-provider/lapack/code_generator.fs    |  611 ++
 workyard/math-provider/lapack/lapack_base.fs       |  131 +
 workyard/math-provider/lapack/lapack_service.fs    |    5 +
 .../math-provider/lapack/lapack_service_mkl.fs     | 1354 ++++
 .../math-provider/lapack/lapack_service_mkl.fsi    |    5 +
 .../math-provider/lapack/lapack_service_netlib.fs  | 1345 ++++
 .../math-provider/lapack/lapack_service_netlib.fsi |    5 +
 .../lapack/lapack_service_template.fs              |   66 +
 workyard/math-provider/lapack/linear_algebra.fs    |  201 +
 workyard/math-provider/lapack/linear_algebra.fsi   |   82 +
 .../math-provider/lapack/linear_algebra_managed.fs |  238 +
 .../math-provider/lapack/linear_algebra_service.fs |  175 +
 workyard/math-provider/lapack/regen.bat            |    3 +
 workyard/math-provider/lapack/service.fs           |  165 +
 workyard/math-provider/lapack/service.fsi          |   19 +
 .../LexAndYaccMiniProject.fsproj                   |   70 +
 workyard/tests/LexAndYaccMiniProject/Lexer.fsl     |   25 +
 workyard/tests/LexAndYaccMiniProject/Parser.fsy    |   27 +
 workyard/tests/LexAndYaccMiniProject/Program.fs    |   32 +
 workyard/tests/codedom/CodeDOM.TestSuite.csproj    |   91 +
 workyard/tests/codedom/CodeDomTest/CDHelper.cs     |  426 ++
 .../codedom/CodeDomTest/CodeDOM.TestCore.csproj    |   57 +
 .../CodeDomTest/CodeDOM.TestCore.csproj.user       |    7 +
 workyard/tests/codedom/CodeDomTest/CodeDomTest.cs  |  490 ++
 .../tests/codedom/CodeDomTest/CodeDomTestTree.cs   |  522 ++
 .../codedom/CodeDomTest/Properties/AssemblyInfo.cs |   29 +
 .../codedom/CodeDomTest/Properties/Resources.resx  |  117 +
 .../CodeDomTest/Properties/Settings.settings       |    7 +
 .../tests/codedom/CodeDomTest/SubsetConformance.cs | 1155 ++++
 workyard/tests/codedom/CodeDomTest/TestTypes.cs    |   11 +
 workyard/tests/codedom/Program.cs                  | 1142 ++++
 workyard/tests/codedom/README.html                 |  478 ++
 workyard/tests/codedom/build.bat                   |   54 +
 .../tests/codedom/notesfortestcasewriters.html     |  191 +
 workyard/tests/codedom/tests/CodeDOM.Tests.csproj  |  105 +
 .../tests/codedom/tests/CodeDOM.Tests.csproj.user  |    7 +
 .../tests/codedom/tests/Properties/AssemblyInfo.cs |   29 +
 .../tests/codedom/tests/Properties/Resources.resx  |  117 +
 .../codedom/tests/Properties/Settings.settings     |    7 +
 workyard/tests/codedom/tests/arraytest.cs          |  288 +
 workyard/tests/codedom/tests/attributestest.cs     |  506 ++
 .../tests/codedom/tests/binaryoperatorstest.cs     |  281 +
 workyard/tests/codedom/tests/callingfieldtest.cs   |  171 +
 workyard/tests/codedom/tests/callmethodtest.cs     |  364 ++
 workyard/tests/codedom/tests/callmethodwdirect.cs  |  129 +
 workyard/tests/codedom/tests/castingcodedom.cs     |  166 +
 workyard/tests/codedom/tests/checksumtest.cs       |  159 +
 workyard/tests/codedom/tests/classtest.cs          |  536 ++
 .../codedom/tests/codeprimitiveexpressiontest.cs   |   95 +
 workyard/tests/codedom/tests/codesnippettest.cs    |   95 +
 workyard/tests/codedom/tests/commenttest.cs        |  288 +
 .../codedom/tests/conditionalstatementtest.cs      |  122 +
 workyard/tests/codedom/tests/constructortest.cs    |  399 ++
 workyard/tests/codedom/tests/createobjecttest.cs   |  156 +
 workyard/tests/codedom/tests/declarefield.cs       |  339 +
 workyard/tests/codedom/tests/declaremethod.cs      |  661 ++
 workyard/tests/codedom/tests/delegatetest.cs       |  224 +
 workyard/tests/codedom/tests/enumtest.cs           |  334 +
 workyard/tests/codedom/tests/eventtest.cs          |  388 ++
 .../tests/codedom/tests/generatorsupportstest.cs   |  750 +++
 workyard/tests/codedom/tests/genericstest.cs       |  210 +
 workyard/tests/codedom/tests/globalkeywordtest.cs  |  219 +
 workyard/tests/codedom/tests/gototest.cs           |  171 +
 .../tests/codedom/tests/implementingstructstest.cs |  268 +
 workyard/tests/codedom/tests/indexerstest.cs       |  199 +
 workyard/tests/codedom/tests/iterationstest.cs     |  170 +
 workyard/tests/codedom/tests/linepragmatest.cs     |   88 +
 workyard/tests/codedom/tests/namespacetest.cs      |  137 +
 workyard/tests/codedom/tests/overloadtest.cs       |   94 +
 workyard/tests/codedom/tests/paramstest.cs         |  135 +
 workyard/tests/codedom/tests/partialclasstest.cs   |  193 +
 workyard/tests/codedom/tests/propertiestest.cs     |  302 +
 .../tests/codedom/tests/regiondirectivetest.cs     |  597 ++
 workyard/tests/codedom/tests/structtest.cs         |  174 +
 workyard/tests/codedom/tests/subsetarraytest.cs    |  174 +
 .../tests/codedom/tests/subsetattributestest.cs    |  321 +
 .../codedom/tests/subsetbinaryoperatorstest.cs     |  225 +
 workyard/tests/codedom/tests/subsetfieldstest.cs   |  146 +
 workyard/tests/codedom/tests/trycatchtest.cs       |  245 +
 workyard/tests/codedom/tests/typeoftest.cs         |  168 +
 workyard/tests/codedom/tests/typetest.cs           |  207 +
 .../tests/codedom/tests/unicodecharescapetest.cs   |   78 +
 .../tests/codedom/tests/verbatimorderingtest.cs    |  332 +
 workyard/tests/fshtmldoc/build.bat                 |   48 +
 workyard/tests/fshtmldoc/msdn.css                  |  229 +
 workyard/tests/fshtmldoc/test.fs                   |   33 +
 workyard/tests/fsyacc/build.bat                    |  123 +
 workyard/tests/fsyacc/example1.fsy                 |   14 +
 workyard/tests/fsyacc/example2.fsy                 |   14 +
 workyard/tests/fsyacc/main-unicode.ml              |   90 +
 workyard/tests/fsyacc/main.ml                      |   59 +
 workyard/tests/fsyacc/repro1885.fsl                |   61 +
 workyard/tests/fsyacc/run.bat                      |   96 +
 workyard/tests/fsyacc/test1-unicode-lex.mll        |   53 +
 workyard/tests/fsyacc/test1-unicode.input1.bsl     |    1 +
 .../tests/fsyacc/test1-unicode.input1.tokens.bsl   |   12 +
 workyard/tests/fsyacc/test1-unicode.input2.bsl     |    2 +
 .../tests/fsyacc/test1-unicode.input3.tokens.bsl   |  244 +
 workyard/tests/fsyacc/test1-unicode.input3.utf8    |    9 +
 workyard/tests/fsyacc/test1-unicode.mly            |   30 +
 workyard/tests/fsyacc/test1.badInput.bsl           |    8 +
 workyard/tests/fsyacc/test1.badInput.tokens.bsl    |  138 +
 workyard/tests/fsyacc/test1.input1                 |    2 +
 workyard/tests/fsyacc/test1.input1.bsl             |    1 +
 workyard/tests/fsyacc/test1.input1.tokens.bsl      |    8 +
 workyard/tests/fsyacc/test1.input2.bsl             |    2 +
 workyard/tests/fsyacc/test1.input2.variation1      |    3 +
 workyard/tests/fsyacc/test1.input2.variation2      |    2 +
 workyard/tests/fsyacc/test1.mly                    |   29 +
 workyard/tests/fsyacc/test1comapt.input1.bsl       |    1 +
 .../tests/fsyacc/test1compat.input1.tokens.bsl     |    8 +
 workyard/tests/fsyacc/test1compat.input2.bsl       |    2 +
 workyard/tests/fsyacc/test1lex.mll                 |   33 +
 workyard/tests/fsyacc/test2.badInput               |   10 +
 workyard/tests/fsyacc/test2.input1                 |    4 +
 workyard/tests/fsyacc/test2.input1.bsl             |    1 +
 workyard/tests/fsyacc/test2.input1.tokens.bsl      |   46 +
 workyard/tests/fsyacc/test2.mly                    |   45 +
 workyard/tests/fsyacc/tree.ml                      |    4 +
 594 files changed, 115346 insertions(+)

diff --git a/License.html b/License.html
new file mode 100644
index 0000000..52e5e7d
--- /dev/null
+++ b/License.html
@@ -0,0 +1,209 @@
+<html>
+<head>
+<title>Apache License, Version 2.0</title>
+</head>
+
+<body>
+
+<div class="section-content">
+<p align="center">
+Apache License<br />
+Version 2.0, January 2004<br />
+<a href="http://www.apache.org/licenses/">http://www.apache.org/licenses/</a>
+</p>
+<p>
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+</p>
+<p><b><a name="definitions">1. Definitions</a></b>.</p>
+<p>
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+</p>
+<p>
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+</p>
+<p>
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+</p>
+<p>
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+</p>
+<p>
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+</p>
+<p>
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+</p>
+<p>
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+</p>
+<p>
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+</p>
+<p>
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+</p>
+<p>
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+</p>
+<p><b><a name="copyright">2. Grant of Copyright License</a></b>.
+Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+</p>
+<p><b><a name="patent">3. Grant of Patent License</a></b>.
+Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+</p>
+<p><b><a name="redistribution">4. Redistribution</a></b>.
+You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+<ol type="a">
+<li>You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+<br /> <br /></li>
+ 
+<li>You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+<br /> <br /></li>
+ 
+<li>You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+<br /> <br /></li>
+ 
+<li>If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.</li>
+</ol>
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+</p>
+<p><b><a name="contributions">5. Submission of Contributions</a></b>.
+Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+</p>
+<p><b><a name="trademarks">6. Trademarks</a></b>.
+This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+</p>
+<p><b><a name="no-warranty">7. Disclaimer of Warranty</a></b>.
+Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+</p>
+<p><b><a name="no-liability">8. Limitation of Liability</a></b>.
+In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+</p>
+<p><b><a name="additional">9. Accepting Warranty or Additional Liability</a></b>.
+While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+</p>
+</div>
+
+</body>
+</html>
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9fe36ea
--- /dev/null
+++ b/README.md
@@ -0,0 +1,40 @@
+This is the F# community repository for the old F# PowerPack library. 
+See http://fsharppowerpack.codeplex.com/ for instructions on use.
+
+The PowerPack functionality is moving.
+
+ * F# CodeDom implementation(s) has moved to an [independent project](http://fsprojects.github.io/FSharp.Compiler.CodeDom)
+
+ * F# Parallel Sequences has moved to an [independent project](http://fsprojects.github.io/FSharp.Collections.ParallelSeq)
+
+ * F# Quotations Evaluator has moved to an [independent project](http://fsprojects.github.io/FSharp.Quotations.Evaluator)
+
+ * FsLex and FsYacc have moved to an [independent project](http://fsprojects.github.io/FsLexYacc/)
+
+ * F# documentation generation is replaced by [FSharp.Formatting](http://tpetricek.github.io/FSharp.Formatting/)
+
+ * F# metadata reader is replaced by [FSharp.Compiler.Service](http://fsharp.github.io/FSharp.Compiler.Service/)
+
+ * These components are replicated in [FSharpx](https://github.com/fsprojects/fsharpx):
+
+   * Quotations to Expression Tree Bridge
+
+   * Async extensions to WebClient, WebRequest and File
+
+   * Lazy module
+
+   * ResizeArray module
+
+   * LazyList
+
+These components are replicated in the F# support in [Math.Net Numerics](http://numerics.mathdotnet.com/):
+
+ * Complex
+ * BigRational
+
+History
+-------
+
+This code is based on the F# PowerPack code drop under the OSS approved Apache 2.0 
+license from the original [F# Power Pack site](http://fsharppowerpack.codeplex.com/).
+
diff --git a/src/FSharp.Compiler.CodeDom/Fsharp.Compiler.CodeDom.fsproj b/src/FSharp.Compiler.CodeDom/Fsharp.Compiler.CodeDom.fsproj
new file mode 100755
index 0000000..f03d4a3
--- /dev/null
+++ b/src/FSharp.Compiler.CodeDom/Fsharp.Compiler.CodeDom.fsproj
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{9EF49218-FD64-43A8-922B-84B1FF576773}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>FSharp.Compiler.CodeDom</AssemblyName>
+    <DocumentationFile>FSharp.Compiler.CodeDom.xml</DocumentationFile>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TreatWarningsAsErrors>
+    </TreatWarningsAsErrors>
+    <!-- 5310 tracks reenabling -->
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="assemblyinfo.FSharp.Compiler.CodeDom.dll.fs">
+      <Link>assemblyinfo.FSharp.Compiler.CodeDom.dll.fs</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\CompilerLocationUtils.fs">
+      <Link>CompilerLocationUtils.fs</Link>
+    </Compile>
+    <Compile Include="codedomvisitor.fs" />
+    <Compile Include="generator.fs" />
+    <Compile Include="compiler.fs" />
+    <Compile Include="codeprovider.fsi" />
+    <Compile Include="codeprovider.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="FSharp.Core" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/src/FSharp.Compiler.CodeDom/Fsharp.Compiler.CodeDom.fsproj.vspscc b/src/FSharp.Compiler.CodeDom/Fsharp.Compiler.CodeDom.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FSharp.Compiler.CodeDom/Fsharp.Compiler.CodeDom.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FSharp.Compiler.CodeDom/assemblyinfo.FSharp.Compiler.CodeDom.dll.fs b/src/FSharp.Compiler.CodeDom/assemblyinfo.FSharp.Compiler.CodeDom.dll.fs
new file mode 100755
index 0000000..a93a22d
--- /dev/null
+++ b/src/FSharp.Compiler.CodeDom/assemblyinfo.FSharp.Compiler.CodeDom.dll.fs
@@ -0,0 +1,7 @@
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("FSharp.Compiler.CodeDom.dll")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("FSharp.Compiler.CodeDom.dll")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
diff --git a/src/FSharp.Compiler.CodeDom/codedomvisitor.fs b/src/FSharp.Compiler.CodeDom/codedomvisitor.fs
new file mode 100755
index 0000000..7b8ed34
--- /dev/null
+++ b/src/FSharp.Compiler.CodeDom/codedomvisitor.fs
@@ -0,0 +1,101 @@
+namespace Microsoft.FSharp.Compiler.CodeDom.Internal
+
+open System
+open System.IO
+open System.Text
+open System.Collections
+open System.CodeDom
+open System.CodeDom.Compiler
+open Microsoft.FSharp.Collections
+
+//---------------------------------------------------------------------------------------------
+// This module contains several utility functions for walking through CodeDom tree
+module Visitor = 
+
+  // Get all relevant CodeDom properties of an object 
+  // - more functions can return properties for one object because of class hierarchy 
+  let memberMap = [
+      (fun (c:obj) -> match c with | :? CodeArrayCreateExpression as co -> [(co.CreateType:>obj); (co.Initializers:>obj); (co.SizeExpression:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeArrayIndexerExpression as co -> [(co.Indices:>obj); (co.TargetObject:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeAssignStatement as co -> [(co.Left:>obj); (co.Right:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeAttachEventStatement as co -> [(co.Event:>obj); (co.Listener:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeAttributeArgument as co -> [(co.Value:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeAttributeDeclaration as co -> [(co.AttributeType:>obj); (co.Arguments:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeBinaryOperatorExpression as co -> [(co.Left:>obj); (co.Operator:>obj); (co.Right:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeCastExpression as co -> [(co.Expression:>obj); (co.TargetType:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeCatchClause as co -> [(co.CatchExceptionType:>obj); (co.Statements:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeCommentStatement as co -> [(co.Comment:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeCompileUnit as co -> [(co.AssemblyCustomAttributes:>obj); (co.EndDirectives:>obj); (co.Namespaces:>obj); (co.StartDirectives:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeConditionStatement as co -> [(co.Condition:>obj); (co.FalseStatements:>obj); (co.TrueStatements:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeConstructor as co -> [(co.BaseConstructorArgs:>obj); (co.ChainedConstructorArgs:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeDefaultValueExpression as co -> [(co.Type:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeDelegateCreateExpression as co -> [(co.TargetObject:>obj); (co.DelegateType:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeDelegateInvokeExpression as co -> [(co.TargetObject:>obj); (co.Parameters:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeDirectionExpression as co -> [(co.Expression:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeEventReferenceExpression as co -> [(co.TargetObject:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeExpressionStatement as co -> [(co.Expression:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeFieldReferenceExpression as co -> [(co.TargetObject:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeIndexerExpression as co -> [(co.Indices:>obj); (co.TargetObject:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeIterationStatement as co -> [(co.IncrementStatement:>obj); (co.InitStatement:>obj); (co.Statements:>obj); (co.TestExpression:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeLabeledStatement as co -> [(co.Statement:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeMemberEvent as co -> [(co.ImplementationTypes:>obj); (co.PrivateImplementationType:>obj); (co.Type:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeMemberField as co -> [(co.InitExpression:>obj); (co.Type:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeMemberMethod as co -> [(co.ImplementationTypes:>obj); (co.Parameters:>obj); (co.PrivateImplementationType:>obj); (co.ReturnType:>obj); (co.ReturnTypeCustomAttributes:>obj); (co.Statements:>obj); (co.TypeParameters:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeMemberProperty as co -> [(co.GetStatements:>obj); (co.ImplementationTypes:>obj); (co.Parameters:>obj); (co.PrivateImplementationType:>obj); (co.SetStatements:>obj); (co.Type:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeMethodInvokeExpression as co -> [(co.Method:>obj); (co.Parameters:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeMethodReferenceExpression as co -> [(co.TargetObject:>obj); (co.TypeArguments:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeMethodReturnStatement as co -> [(co.Expression:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeNamespace as co -> [(co.Comments:>obj); (co.Imports:>obj); (co.Types:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeNamespaceImport as co -> [(co.LinePragma:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeObjectCreateExpression as co -> [(co.CreateType:>obj); (co.Parameters:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeParameterDeclarationExpression as co -> [(co.CustomAttributes:>obj); (co.Direction:>obj); (co.Type:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodePropertyReferenceExpression as co -> [(co.TargetObject:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeRemoveEventStatement as co -> [(co.Event:>obj); (co.Listener:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeStatement as co -> [(co.EndDirectives:>obj); (co.StartDirectives:>obj); (co.LinePragma:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeThrowExceptionStatement as co -> [(co.ToThrow:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeTryCatchFinallyStatement as co -> [(co.CatchClauses:>obj); (co.FinallyStatements:>obj); (co.TryStatements:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeTypeDeclaration as co -> [(co.BaseTypes:>obj); (co.Members:>obj); (co.TypeAttributes:>obj); (co.TypeParameters:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeTypeDelegate as co -> [(co.Parameters:>obj); (co.ReturnType:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeTypeMember as co -> [(co.Attributes:>obj); (co.Comments:>obj); (co.CustomAttributes:>obj); (co.EndDirectives:>obj); (co.LinePragma:>obj); (co.StartDirectives:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeTypeOfExpression as co -> [(co.Type:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeTypeParameter as co -> [(co.Constraints:>obj); (co.CustomAttributes:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeTypeReference as co -> [(co.ArrayElementType:>obj); (co.TypeArguments:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeTypeReferenceExpression as co -> [(co.Type:>obj);] | _ -> []);
+      (fun (c:obj) -> match c with | :? CodeVariableDeclarationStatement as co -> [(co.InitExpression:>obj); (co.Type:>obj);] | _ -> []) ];
+
+  let children o = memberMap |> Seq.collect (fun e -> e o) 
+
+  let rec codeDomFold' f st o = 
+    match box o with 
+      | :? CollectionBase as cl -> 
+           cl |> Seq.cast |> Seq.fold (codeDomFold' f) st;
+      | _ ->
+           let (nst,recurse) = f st o;
+           if (recurse) then
+             o |> children |> Seq.fold (codeDomFold' f) nst;
+           else nst
+
+  let codeDomCallbackWithScope' f  = 
+    let rec callback oscope res o =
+        match box o with 
+          | :? CollectionBase as cl -> 
+              cl |> Seq.cast |> Seq.fold (f callback oscope) res;
+          | _ ->
+              o |> children |> Seq.fold (f callback oscope) res;
+    f callback;
+                       
+  /// Search for members and return flat list of selected members
+  /// Function given as an argument returns tuple - first item specifies
+  /// if the current element should be included in the result, the second
+  /// specifies if we should walk through child members of the current object
+  let codeDomFlatFilter f o = codeDomFold' ( fun st o -> let (inc,rc) = (f o) in if (inc) then (o::st,rc) else (st,rc) ) [] (box o)            
+  
+  /// Walks through the CodeDom tree and keeps current "scope" and the result.
+  /// The result is collected through entire tree, but the modified scope is 
+  /// passed only to sub-nodes of the current node.
+  ///
+  /// First argument is a function that is called for nodes and has a 
+  /// function as a first argument, scope and result as a second and current node as a third.
+  /// The function argument can be used to walk deeper in the tree if wanted.
+  let codeDomCallbackWithScope f scope st o = codeDomCallbackWithScope' f scope st (box o)
+  let codeDomCallBackNoScope f st o = codeDomCallbackWithScope (fun rcall () res x -> f (rcall ()) res x) () st o
diff --git a/src/FSharp.Compiler.CodeDom/codeprovider.fs b/src/FSharp.Compiler.CodeDom/codeprovider.fs
new file mode 100755
index 0000000..740cea8
--- /dev/null
+++ b/src/FSharp.Compiler.CodeDom/codeprovider.fs
@@ -0,0 +1,302 @@
+#nowarn "62" // This construct is for ML compatibility.
+
+//-------------------------------------------------------------------------------------------------
+// Internal members
+
+namespace Microsoft.FSharp.Compiler.CodeDom.Internal
+
+    open System
+    open System.IO
+    open System.Text
+    open System.Collections
+    open System.CodeDom
+    open System.CodeDom.Compiler
+
+    open Microsoft.FSharp.Compiler.CodeDom.Internal
+    module AspNetUtils = 
+      
+        /// Preprocessing of the CodeDom compile unit from ASP.NET
+        let aspNetPreProcessCompileUnit (c:CodeCompileUnit) =
+        
+            // Remove partial calsses from ASP.NET generated code (we can leave empty namespaces)
+            // F# doesn't support partial classes, so we need to remove generated 'second' part of the 
+            // handwritten class that contains fields for all controls - these have to be written 
+            // manually in the handwritten code...
+            (* if false then  *)
+            begin
+                for ns in c.Namespaces do
+                    // Phase 1. Find classes to remove
+                    let toRemove = 
+                        ns.Types 
+                        |> Seq.cast
+                        |> Seq.filter (fun (t:CodeTypeDeclaration)  -> t.IsPartial ) 
+                        |> Seq.toList
+                    // Phase 2. remove (destructive). 
+                    toRemove |> List.iter ns.Types.Remove;
+            end;
+
+            
+            // Fix one very specific bug in ASP.NET generated CodeDom tree.
+            // In one case it generates "<null>.SetStringResourcePointer" instead of
+            // "this.SetStringResourcePointer" (Reported here: 
+            // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=164512)
+            for ns in c.Namespaces do
+              for t in ns.Types do 
+                for m in t.Members do 
+                  match m with 
+                    | :? CodeMemberMethod as meth ->
+                        if (meth.Name = "FrameworkInitialize") then 
+                          for smt in meth.Statements do
+                            match smt with 
+                            | :? CodeExpressionStatement as stm -> 
+                                match stm.Expression with 
+                                  | :? CodeMethodInvokeExpression as inv ->
+                                    if ((inv.Method.TargetObject = null) && (inv.Method.MethodName = "SetStringResourcePointer")) then 
+                                      inv.Method.TargetObject <- new CodeThisReferenceExpression();
+                                  | _ -> ();
+                            | _ -> ();
+                        else ();
+                    | _ -> ();
+              
+
+        // Sorts ASP.NET source files
+        // ASP.NET compiler sends three kinds of files
+        // - CodeDOM generated file from ASPX file
+        // - handwritten file (codebehind for the previous)
+        // - fast factory for creating the first one
+        // 
+        // We need to send them to compiler in following order:
+        // - handwritten, aspx, handwritten, aspx, ..., factory
+        // 
+        // File name is: "Something.num.fs" where num is an index, but the array isn't
+        // sorted so we sort them using the index. Then we find all ASPX and swap 
+        // ASPX and handwritten file. Factory should be the last file.
+        
+
+        /// Does the file contain the given text?
+        let fileContains (text:string) (filename:string) = 
+          try
+            use fs = new IO.StreamReader(filename)
+            let rec testLine () = 
+                let line = fs.ReadLine()
+                (line <> null) && (line.IndexOf(text) <> -1 || testLine())
+            testLine()
+          with _ -> false
+
+        /// Swap two elements of an array
+        let swap (arr:'a[]) i j = 
+            let tmp = arr.[j] 
+            arr.[j] <- arr.[i]
+            arr.[i] <- tmp
+
+
+        /// Compiled forms of ASPX source files always contain "(__initialized:bool)".
+        /// The factory file contains "static member Create_ASP_"
+        let isFactoryFile filename = 
+            fileContains "static member Create_ASP_" filename &&
+            fileContains "FastObjectFactory" filename 
+
+        let isGeneratedFromAspxFile filename = 
+            fileContains "static val mutable private __initialized:bool" filename &&
+            fileContains "<autogenerated>" filename
+
+        let isUserFile filename = 
+            not (isGeneratedFromAspxFile filename)  &&
+            not (isFactoryFile filename) 
+
+          // REVIEW: will "Temporary ASP.NET Files" survive internationalization????
+        let indexOfAspNetFile(el:string) = 
+              let n = 
+                try
+                  let bnum = el.LastIndexOf(".", el.Length - 4)
+                  Int32.Parse(el.Substring(bnum + 1, el.Length - bnum - 4))
+                with _ -> -1
+              if (el.IndexOf("Temporary ASP.NET Files") <> -1) 
+              then n
+              else -1
+      
+          
+        let aspNetSortFiles (files:string array) =
+
+            // Verify that files are from ASP.NET & sort them.
+            let aspFiles = files |> Array.map (fun el -> indexOfAspNetFile el, el)              
+            let allAspNet = aspFiles |> Array.forall (fun (n, a) -> n <> -1)
+            
+            let sortedFiles = 
+                if (allAspNet) then
+                    Array.sortInPlaceWith (fun (n1, _) (n2, _) -> n1 - n2) aspFiles
+                    let filesMod = aspFiles |> Array.map snd 
+                    
+                    //System.Windows.Forms.MessageBox.Show(sprintf "filesMod = %A" filesMod) |> ignore
+                    // Rearrange files
+                    // NOTE: ack! surely there's a nicer way to do this!
+                    let mutable i = 0
+                    while (i < filesMod.Length) do
+                        if  (isGeneratedFromAspxFile filesMod.[i]
+                             && not (isFactoryFile filesMod.[i]) 
+                             && isUserFile filesMod.[i+1]) 
+                        then
+                            swap filesMod i (i+1)
+                            i <- i + 1
+                        i <- i + 1
+                    filesMod
+                else
+                    files
+            //System.Windows.Forms.MessageBox.Show(sprintf "sortedFiles = %A" sortedFiles) |> ignore
+            sortedFiles
+
+    // Generic code generator that can be specialized with preprocessing function and additional 
+    // CodeGenerator configuration options (this is used by ASP.NET generator)
+    //   preprocCu: 
+    module FSharpCodeGenerator = 
+        let Create(preprocCu, addop) = 
+      
+            let usingStringWriter f =
+                let sb = new StringBuilder()
+                use sw = new StringWriter(sb)
+                f (sw :> TextWriter);
+                let res = sb.ToString();
+                res
+          
+            { new ICodeGenerator with
+                // Identifier related functions            
+                member this.CreateEscapedIdentifier (value:string) : string =
+                  Generator.makeEscapedIdentifier value
+                member this.CreateValidIdentifier (value:string) : string =
+                  Generator.makeValidIdentifier value
+                member this.IsValidIdentifier (value:string) : bool =
+                  Generator.isValidIdentifier value; 
+                member this.ValidateIdentifier (value:string) : unit =
+                  if (not (Generator.isValidIdentifier value)) then 
+                    raise (ArgumentException(sprintf "'%s' is not a valid F# identifier!" value))
+      
+                // Implementations of code generation related functions
+                member this.GenerateCodeFromCompileUnit(compileUnit, textWriter, options) =
+                    (Generator.createContext textWriter options addop) 
+                    |> (Generator.generateCompileUnit compileUnit preprocCu) 
+                    |> ignore
+                
+                member this.GenerateCodeFromExpression(codeExpr, textWriter, options) : unit =
+                    (Generator.createContext textWriter options addop) 
+                    |> (Generator.generateExpression codeExpr) 
+                    |> ignore
+                
+                member this.GenerateCodeFromNamespace(codeNamespace, textWriter, options) : unit =
+                    (Generator.createContext textWriter options addop) 
+                    |> (Generator.generateNamespace codeNamespace) 
+                    |> ignore
+                
+                member this.GenerateCodeFromStatement(codeStatement, textWriter, options) : unit =
+                    (Generator.createContext textWriter options addop) 
+                    |> (Generator.generateStatement codeStatement) 
+                    |> ignore
+                    
+                member this.GenerateCodeFromType(codeTypeDecl, textWriter, options) : unit =
+                    (Generator.createContext textWriter options addop) 
+                    |> (Generator.generateTypeDeclOnly codeTypeDecl) 
+                    |> ignore
+                member this.GetTypeOutput (t:CodeTypeReference) : string =
+                    usingStringWriter (fun sw ->
+                      (Generator.createContext sw (CodeGeneratorOptions()) addop) 
+                      |> (Generator.generateTypeRef t) |> ignore)
+
+                member this.Supports (supports:GeneratorSupport) : bool =
+                  (supports &&&  (GeneratorSupport.ReturnTypeAttributes ||| 
+                                  GeneratorSupport.ParameterAttributes ||| 
+                                  GeneratorSupport.AssemblyAttributes ||| 
+                                  GeneratorSupport.StaticConstructors ||| 
+                                  GeneratorSupport.NestedTypes ||| 
+                                  GeneratorSupport.EntryPointMethod |||
+                                  GeneratorSupport.GotoStatements ||| 
+                                  GeneratorSupport.MultipleInterfaceMembers |||
+                                  GeneratorSupport.ChainedConstructorArguments
+                                  ) = enum 0) }
+
+    // Generic code compiler - the argument is a function for sorting files that can be used by
+    // tool-specific providers if needed (like in case of ASP.NET)
+    module FSharpCodeCompiler = 
+        let Create(sortFiles) =
+            { new ICodeCompiler with       
+                member this.CompileAssemblyFromDom (options:CompilerParameters,compileUnit:CodeCompileUnit) : CompilerResults =
+                  this.CompileAssemblyFromDomBatch (options, [|compileUnit|]);
+                member this.CompileAssemblyFromSource (options:CompilerParameters,source:string) : CompilerResults =
+                  this.CompileAssemblyFromSourceBatch (options, [|source|]);                
+                member this.CompileAssemblyFromFile (options:CompilerParameters,fileName:string) : CompilerResults =
+                  this.CompileAssemblyFromFileBatch (options, [|fileName|]);
+                    
+                member this.CompileAssemblyFromDomBatch (options:CompilerParameters,compilationUnits:CodeCompileUnit[]) : CompilerResults =
+                  let res = new CompilerResults(options.TempFiles);
+                  let files = 
+                      compilationUnits 
+                      |> Array.map ( fun cu -> 
+                          let fn = res.TempFiles.AddExtension("fs", false)
+                          use wr = new StreamWriter(fn, false, Encoding.UTF8)
+                          Generator.createContext wr (CodeGeneratorOptions()) Generator.AdditionalOptions.None 
+                              |> (Generator.generateCompileUnit cu (fun _ -> ())) |> ignore
+                          fn)        
+                  Compiler.compileAssemblyFromFileBatch options files res sortFiles
+
+                member this.CompileAssemblyFromSourceBatch (options:CompilerParameters,sources:string[]) : CompilerResults =
+                  let res = new CompilerResults(options.TempFiles);
+                  let files = sources |> Array.map ( fun src -> 
+                      let fn = res.TempFiles.AddExtension("fs", false)
+                      use wr = new StreamWriter(fn)
+                      wr.Write(src) 
+                      fn)
+                  Compiler.compileAssemblyFromFileBatch options files res sortFiles       
+                  
+                member this.CompileAssemblyFromFileBatch (options:CompilerParameters,fileNames:string[]) : CompilerResults =
+                  Compiler.compileAssemblyFromFileBatch options fileNames (new CompilerResults(options.TempFiles)) sortFiles
+            }
+          
+
+//-------------------------------------------------------------------------------------------------
+// Public types
+
+namespace Microsoft.FSharp.Compiler.CodeDom
+
+    open System
+    open System.IO
+    open System.Text
+    open System.Collections
+    open System.CodeDom
+    open System.CodeDom.Compiler
+
+    open Microsoft.FSharp.Compiler.CodeDom.Internal
+
+    type FSharpCodeProvider() = 
+        inherit CodeDomProvider()
+        [<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")>]
+        override this.FileExtension = "fs";
+        
+        [<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")>]
+        override this.CreateCompiler() =
+            FSharpCodeCompiler.Create(AspNetUtils.aspNetSortFiles)
+
+        [<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")>]            
+        override this.CreateGenerator() =
+            FSharpCodeGenerator.Create((fun _ -> ()), Generator.AdditionalOptions.None)
+
+    type FSharpAspNetCodeProvider() = 
+        inherit CodeDomProvider()
+        [<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")>]
+        override this.FileExtension = "fs";
+        
+        [<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")>]
+        override this.CreateCompiler() =
+            FSharpCodeCompiler.Create(AspNetUtils.aspNetSortFiles)
+            
+        [<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")>]
+        override this.CreateGenerator() =
+            
+            // If you set the options to "Generator.AdditionalOptions.UnknonwFieldsAsLocals"
+            // than the generator will treat all fields that are not declared in the class as locals
+            // (and will generated "fld" instead of "this.fld")            
+            // This will make it possible to use implicit class syntax in ASP.NET, but only when
+            // the fields will have non-private visibility (because we need to access them from inherited class
+            
+            // AspNetArrays is workaround for ASP.NET which generates wrong type in array initializers
+            // (according to the CodeDOM test suite it should be "int[]" for [| 1; 2 |], but ASP.NET gives us "int" !! 
+            let opts = Generator.AdditionalOptions.AspNetArrays
+            FSharpCodeGenerator.Create(AspNetUtils.aspNetPreProcessCompileUnit, opts)
+        
diff --git a/src/FSharp.Compiler.CodeDom/codeprovider.fsi b/src/FSharp.Compiler.CodeDom/codeprovider.fsi
new file mode 100755
index 0000000..e659b8c
--- /dev/null
+++ b/src/FSharp.Compiler.CodeDom/codeprovider.fsi
@@ -0,0 +1,15 @@
+namespace Microsoft.FSharp.Compiler.CodeDom
+
+open System.CodeDom.Compiler
+
+/// Implementation of the CodeDomProvider for the F# language.
+/// If you intend to use CodeDom with ASP.NET you should use <c>FSharpAspNetCodeProvider</c> instead.
+type FSharpCodeProvider = 
+    inherit CodeDomProvider 
+    new : unit -> FSharpCodeProvider
+
+/// Implementation of the CodeDomProvider for the F# language.
+/// This is specialized version that can be used with ASP.NET.
+type FSharpAspNetCodeProvider = 
+    inherit CodeDomProvider 
+    new : unit -> FSharpAspNetCodeProvider
diff --git a/src/FSharp.Compiler.CodeDom/compiler.fs b/src/FSharp.Compiler.CodeDom/compiler.fs
new file mode 100755
index 0000000..adbe61e
--- /dev/null
+++ b/src/FSharp.Compiler.CodeDom/compiler.fs
@@ -0,0 +1,176 @@
+namespace Microsoft.FSharp.Compiler.CodeDom.Internal
+
+open System
+open System.IO
+open System.Text
+open System.Text.RegularExpressions
+open System.Collections
+open System.Diagnostics
+open System.CodeDom
+open System.Security
+open System.Security.Permissions
+open System.CodeDom.Compiler
+
+module internal AssemblyAttributes = 
+    //[<assembly: System.Security.SecurityTransparent>]
+    do()
+
+//-------------------------------------------------------------------------------------------------
+module internal Global = 
+    let debugCmdLineArgs = true
+    let (++) x y = Path.Combine(x,y)
+    
+    // search for "fsc.exe"
+    let FscExeBaseName = "fsc.exe"
+
+    let FSharpBinFromEnvironmentVariable = 
+        try match System.Environment.GetEnvironmentVariable("FSHARP_BIN") with 
+            | null -> None
+            | s -> Some(s)
+        with _ -> None
+
+    // Note: this technique is now deprecated by BinFolderOfDefaultFSharpCompiler, which we try first
+    let FSharpBinFromDeprecatedInstallLocationGuess = 
+        try match Internal.Utilities.FSharpEnvironment.FSharpCoreLibRunningVersion with 
+            | Some v -> Some(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) ++ "FSharp-" +  v)
+            | _ -> None
+        with _ -> None
+
+             
+    let FscPath = 
+        let tryFscPath x = 
+            match x with 
+            | None -> None
+            | Some dir -> 
+                 let fscName = dir  ++ FscExeBaseName 
+                 if File.Exists(fscName) then Some(fscName) else None
+
+        let search0 = tryFscPath Internal.Utilities.FSharpEnvironment.BinFolderOfDefaultFSharpCompiler 
+        match search0 with 
+        | Some(res) -> res
+        | None -> 
+        
+        let search1 = tryFscPath FSharpBinFromEnvironmentVariable
+        match search1 with 
+        | Some(res) -> res
+        | None -> 
+            
+        let search2 = tryFscPath FSharpBinFromDeprecatedInstallLocationGuess
+        match search2 with 
+        | Some(res) -> res
+        | None -> 
+        FscExeBaseName
+    
+    // regular expressions for parsing result         
+    let regParseFsOutput = Regex(@"(?<file>[^\(]*)\((?<line>[0-9]*),(?<col>[0-9]*)\):\s(?<type>[^:]*)\s(?<err>[^:]*):\s(?<msg>.*)", RegexOptions.Compiled);
+    let regParseFsOutputNoNum = Regex(@"(?<file>[^\(]*)\((?<line>[0-9]*),(?<col>[0-9]*)\):\s(?<type>[^:]*)\s(?<msg>.*)", RegexOptions.Compiled);
+
+//-------------------------------------------------------------------------------------------------
+module internal Compiler = 
+    let id a = a
+    let (+>) (ctx:StringBuilder) (foo:StringBuilder -> StringBuilder) = foo ctx;
+    let (--) (ctx:StringBuilder) (str:String) = ctx.Append(str)
+    let untypedFold f col st = Seq.fold f st (Seq.cast col)
+     
+    // Generate command-line arguments for FSC
+    let cmdArgsFromParameters (o:CompilerParameters) filenames = 
+      let sb = new StringBuilder(50)
+      (sb 
+        +> if (not o.GenerateExecutable) then (fun ctx -> ctx -- "-a ") else id
+        +> untypedFold (fun ctx e -> ctx -- "-r:\"" -- e -- "\" ") o.ReferencedAssemblies
+        -- "--noframework --nologo -o:\"" -- o.OutputAssembly -- "\" "        
+        +> if (o.IncludeDebugInformation) then (fun ctx -> ctx -- "--debug+ ") else id        
+        +> if (o.Win32Resource <> null) then (fun ctx -> ctx -- "--win32res:\"" -- o.Win32Resource -- "\" ") else id 
+        +> if (o.CompilerOptions <> null) then (fun ctx -> ctx -- o.CompilerOptions -- " ") else id) 
+        
+        // Never treat warnings as errors - this overrides "#nowarn", but the generated code
+        // will contain some warnings in almost any case...
+        //   +> if (o.TreatWarningsAsErrors) then (fun ctx -> ctx -- "--warnaserror ") else id
+        
+        |> ignore  
+        
+      filenames |> Array.iter ( fun (fn:string) ->
+        ignore (sb.AppendFormat(" \"{0}\"", fn)) )
+      sb.ToString();
+
+    // Process FSC output
+    let processMsg msg (res:CompilerResults) = 
+      let m = 
+        let t1 = Global.regParseFsOutput.Match(msg) in
+          if (t1.Success) then t1 else Global.regParseFsOutputNoNum.Match(msg)
+      let ce = 
+        if (m.Success) then 
+          let errNo = (if (m.Groups.Item("err") <> null) then (m.Groups.Item("err")).Value else "") 
+          let ce = CompilerError(m.Groups.Item("file").Value, Int32.Parse(m.Groups.Item("line").Value), 
+                                 Int32.Parse(m.Groups.Item("col").Value), errNo, m.Groups.Item("msg").Value);
+          ce.IsWarning <- ((m.Groups.Item("type")).Value = "warning");
+          ce
+        else new CompilerError("unknown-file", 0, 0, "0", msg);
+      res.Errors.Add(ce) |> ignore      
+      
+    // Invoke FSC compiler and parse output  
+    let compileFiles args (res:CompilerResults) =
+        let p = new Process() in
+        p.StartInfo.FileName <- Global.FscPath;
+        p.StartInfo.UseShellExecute <- false;
+        p.StartInfo.Arguments <- args;
+        p.StartInfo.RedirectStandardError <- true;
+        p.StartInfo.CreateNoWindow <- true;
+        p.Start() |> ignore
+
+        // useful when debugging
+        if (Global.debugCmdLineArgs) then
+          let s = res.TempFiles.AddExtension("cmdargs")
+          use sw = new StreamWriter(s);
+          sw.WriteLine(args);
+        
+        let mutable serr = "" 
+        let mutable smsg = ""
+        while (serr <- p.StandardError.ReadLine(); serr <> null) do 
+          if (serr.Trim().Length = 0 && smsg <> "") then 
+            processMsg smsg res; smsg <- "";
+          else 
+            smsg <- smsg + " " + (serr.Trim());
+        if (smsg <> "") then processMsg smsg res;
+        p.WaitForExit();
+        res.NativeCompilerReturnValue <- p.ExitCode;
+
+    // Compile assembly from given array of files
+    let compileAssemblyFromFileBatch (options:CompilerParameters) (fileNames:string array) 
+                                     (results:CompilerResults) sortf : CompilerResults =
+                                     
+      // Call 'fix' sorting function                                      
+      let fileNames = sortf fileNames
+      let createdAssembly = 
+        if (options.OutputAssembly = null || options.OutputAssembly.Length = 0) then begin
+          let extension = if (options.GenerateExecutable) then "exe" else "dll" 
+          options.OutputAssembly <- results.TempFiles.AddExtension(extension, not options.GenerateInMemory)
+
+          // Create an empty assembly, so the file can be later accessed using current credential.  
+          let fs = new FileStream(options.OutputAssembly, FileMode.Create, FileAccess.ReadWrite) in 
+          fs.Close();
+          true;
+        end else false in
+      ignore(results.TempFiles.AddExtension("pdb"));
+        
+      // Compile..      
+      let args = cmdArgsFromParameters options fileNames 
+      compileFiles args results;
+        
+      if (options.GenerateInMemory) then
+        use fs = new FileStream(options.OutputAssembly, FileMode.Open, FileAccess.Read, FileShare.Read)
+        let count = int32 fs.Length 
+        if (count > 0) then
+          let buffer = (Array.zeroCreate count) 
+          fs.Read(buffer, 0, count) |> ignore
+          (new SecurityPermission(SecurityPermissionFlag.ControlEvidence)).Assert();
+          try
+            results.CompiledAssembly <- System.Reflection.Assembly.Load(buffer, null, options.Evidence);
+          finally
+            CodeAccessPermission.RevertAssert();
+      else 
+        results.PathToAssembly <- options.OutputAssembly;
+
+      // Delete the assembly if we created it
+      if (createdAssembly) then File.Delete(options.OutputAssembly);
+      results      
diff --git a/src/FSharp.Compiler.CodeDom/generator.fs b/src/FSharp.Compiler.CodeDom/generator.fs
new file mode 100755
index 0000000..8a89453
--- /dev/null
+++ b/src/FSharp.Compiler.CodeDom/generator.fs
@@ -0,0 +1,1812 @@
+namespace Microsoft.FSharp.Compiler.CodeDom.Internal
+#nowarn "57" // parametrized active patterns
+#nowarn "62" // This construct is for ML compatibility.
+
+open System
+open System.IO
+open System.Text
+open System.Reflection
+open System.Collections
+open System.Collections.Generic
+open System.CodeDom
+open System.CodeDom.Compiler
+
+open Microsoft.FSharp.Compiler.CodeDom.Internal.Visitor
+
+
+module internal Generator =
+
+    type ResizeArray<'T> = System.Collections.Generic.List<'T> // alias
+  
+    //---------------------------------------------------------------------------------------------
+    // Context and configuration
+    
+    type AdditionalOptions =
+      /// No extra configuration
+      | None = 0                      
+      
+      /// Reference inherited fields using "fld" instead of "this.fld" 
+      /// (could be used in the future to allow implicit classes in ASP.NET?)
+      | UnknonwFieldsAsLocals = 1     
+                                      
+      /// Hacking for ASP.NET incorrect array initializers 
+      /// They generate "string" where codedom test suite uses "string[]"
+      | AspNetArrays = 2              
+                                      
+    
+    type Context = 
+      {
+        /// Some unique ID for every namespace (so we don't have name clashes)
+        UniqueID:string
+        
+        /// Options, output, ...
+        Options:AdditionalOptions
+        Writer:IndentedTextWriter
+        
+        // *** Method/type scope ***
+        
+        /// Names of all type arguments in scope (need to rename T -> 'T etc.)
+        TypeArgumentNames:Set<string>
+        /// Types of all local variables in the method
+        LocalVariableTypes:Map<string,Type>;
+        /// Type of the method 
+        CurrentMethodReturnType:CodeTypeReference option;
+        /// We use exception for returning value when generating complex
+        /// code that returns using imperative "return" statement
+        ReturnUsingException:bool;
+      
+        // *** Information for the current class *** 
+        
+        CurrentType:CodeTypeDeclaration;
+        BaseTypes:CodeTypeReference option * CodeTypeReference list
+        AllFields:Map<string,CodeMemberField>;
+        AllProps:Map<string,CodeMemberProperty>;
+        AllMeths:Map<string,CodeMemberMethod>;
+        AllEvents:Map<string,CodeMemberEvent>;
+        FieldTypes:Map<string,CodeTypeReference>;
+        PropertyTypes:Map<string,CodeTypeReference>;
+        DeclaredEvents:CodeMemberEvent list;
+          
+        // *** Namespace scope ***         
+        
+        // Renamed types (when flattening nested classes)
+        TypeRenames:Map<string,string>
+        // Current namespace (can't be used in the type reference expression)
+        CurrentNamespace:string; 
+        // Set of interface names declared in the current namespace
+        DeclaredInterfaces:Set<string>
+        // A static Main method declared by one of the classes in this namespace
+        MainMethodForCurrentNamespace:(CodeEntryPointMethod * CodeTypeDeclaration) option
+      }
+    
+    /// Create context using specified text writer and options
+    let createContext (wr:TextWriter) (opts:CodeGeneratorOptions) (addopts) = 
+      { UniqueID = (Guid.NewGuid()).ToString("N")
+        Writer = new IndentedTextWriter(wr); TypeRenames = Map.empty; 
+        CurrentType = null; CurrentNamespace = ""; 
+        DeclaredEvents = []; 
+        BaseTypes = (None, []); 
+        AllFields = Map.empty;
+        AllEvents = Map.empty;
+        AllProps = Map.empty;
+        AllMeths = Map.empty;
+        FieldTypes = Map.empty 
+        CurrentMethodReturnType = None; 
+        LocalVariableTypes = Map.empty; 
+        ReturnUsingException = false; 
+        PropertyTypes = Map.empty
+        Options = addopts; 
+        DeclaredInterfaces = Set.empty; 
+        TypeArgumentNames = Set.empty; 
+        MainMethodForCurrentNamespace = None }    
+
+    /// Where are we generating member?
+    type MemberGenerateType = 
+      | InsideInterface = 0
+      | InsideStruct = 1
+      | InsideClass = 2
+      
+    //---------------------------------------------------------------------------------------------
+    // Collections and combinators for generating
+
+    /// Function composition operator
+    let (+>) (ctx:Context -> Context) (foo:Context -> Context) x =
+      foo (ctx x);
+
+    /// Print unique id using: "+> uniqid"
+    let uniqid (c:Context) =
+      c.Writer.Write(c.UniqueID);
+      c;
+
+    /// Break-line and append specified string
+    let (++) (ctx:Context -> Context) (str:String) x =
+      let c = (ctx x)
+      c.Writer.WriteLine();
+      c.Writer.Write(str);
+      c;
+
+    /// Append specified string without line-break
+    let (--) (ctx:Context -> Context) (str:String) x =
+      let c = (ctx x)
+      c.Writer.Write(str);
+      c;
+
+    /// Call function, but give it context as an argument      
+    let withCtxt f x =
+      (f x) x;
+      
+    /// Identity function
+    let id a = a
+
+    /// Print object converted to string
+    let str (o: 'T) (ctx:Context) =
+      ctx.Writer.Write(o :> obj);
+      ctx;
+
+    /// Create closure to do the counting 
+    /// (this is usend when we need indexing during collection processing)
+    let createCounter() =   
+      let i = ref (-1)
+      (fun () -> i := (!i) + 1; !i)
+      
+    /// Perform map and filter operations in one 
+    let rec mapFilter f l =
+      match l with
+      | [] -> [];
+      | a::r -> match (f a) with | None -> (mapFilter f r) | Some el -> el::(mapFilter f r)
+
+    /// Process collection - keeps context through the whole processing
+    /// calls 'f' for every element in sequence and 'fs' between every two elements 
+    /// as a separator
+    let col fs (c:IEnumerable) f (ctx:Context) = 
+      let mutable tryPick = true in
+      let mutable st = ctx
+      let e = c.GetEnumerator()
+      while (e.MoveNext()) do
+        if (tryPick) then tryPick <- false else st <- fs st
+        st <- f (unbox e.Current) st
+      st
+    
+    /// Process collection - keeps context through the whole processing
+    /// calls 'f' for every element in sequence and 'fs' between every two elements 
+    /// as a separator. This is a variant that works on typed collections.
+    let colT fs (c:seq<'T>) f (ctx:Context) =
+      let mutable tryPick = true in
+      let mutable st = ctx
+      let e = c.GetEnumerator();
+      while (e.MoveNext()) do
+        if (tryPick) then tryPick <- false else st <- fs st;
+        st <- f (e.Current) st;
+      st
+        
+    /// Call specified function only on elements of specified type.
+    /// (performs dynamic type test using x.GetType())
+    let colFilterT<'T> fs (c:IEnumerable) (f: 'T -> Context -> Context) ctx =
+      let sq : seq<'T>
+          = c |> Seq.cast |> Seq.filter (fun (o:obj) -> o.GetType() = typeof<'T>) |> Seq.cast
+      colT fs sq f ctx
+
+    let colFilter<'T> fs (c:IEnumerable) (f: 'T -> Context -> Context) ctx =
+      let sq = c |> Seq.cast |> Seq.filter (fun (o:obj) -> o.GetType() = typeof<'T>)
+      col fs sq f ctx
+
+    // Separator functions        
+    let sepDot          = id -- "."
+    let sepWordAnd      = id -- " and "      
+    let sepSpace        = id -- " "      
+    let sepNln          = id ++ ""
+    let sepArgs         = id -- ", "
+    let sepArgsSemi     = id -- "; "
+    let sepNone         = id
+    let sepStar         = id -- " * "
+    let sepNlnSemiSpace = id -- ";" ++ "  "
+    
+    //---------------------------------------------------------------------------------------------
+    // F# keywords and identifiers and also type resolving for standard .NET libraries
+    
+    let fsKeyWords = 
+      new HashSet<_>
+         (["abstract"; "and"; "as"; "assert"; "asr"; "base"; "begin"; "class"; "default"; "delegate"; "do"; "done";
+           "downcast"; "downto"; "elif"; "else"; "end"; "exception"; "extern"; "false"; "finally"; "for"; "fun";
+           "function"; "if"; "in"; "inherit"; "inline"; "interface"; "internal"; "land"; "lazy"; "let"; "lor"; "lsl"; "lsr"; "lxor";
+           "match"; "member"; "method"; "mod"; "module"; "mutable"; "namespace"; "new"; "null"; "of"; "open"; "or"; "override";
+           "private"; "public"; "rec"; "return"; "sig"; "static"; "struct"; "then"; "to"; "true"; "try"; "type"; "upcast"; "use"; "val"; "virtual"; "void"; "when"; 
+           "while"; "with"; "yield";
+           
+           "atomic"; "break"; 
+           "checked"; "component"; "const"; "constraint"; "constructor"; "continue"; 
+           "eager"; 
+           "fixed"; "fori"; "functor"; "global";"recursive";"measure"; 
+           "include";  (* "instance"; *)
+           "mixin"; 
+           "object"; "parallel"; "params";  "process"; "protected"; "pure"; (* "pattern"; *)
+           "sealed"; "trait";  "tailcall";
+           "volatile"; ], HashIdentity.Structural)
+
+    let isValidIdentifier str = 
+      not (fsKeyWords.Contains(str))
+
+    let makeEscapedIdentifier str = 
+      if (fsKeyWords.Contains(str)) then "i'"+str+"'" else str;
+
+    let makeValidIdentifier str = 
+      if (fsKeyWords.Contains(str)) then "_"+str else str;
+      
+    let freshName = 
+      let counter = createCounter ()
+      (fun () -> "UnnamedMethod_" + counter().ToString())
+
+    // List of "known" libraries that we try to search when we need to resolve a type
+    let coreAssemblies = 
+       ["mscorlib"; "System"; "System.Web"; "System.Xml"; 
+        "System.Data"; "System.Deployment"; "System.Design"; "System.DirectoryServices"; 
+        "System.Drawing.Design"; "System.Drawing"; "System.EnterpriseServices"; 
+        "System.Management"; "System.Messaging"; "System.Runtime.Remoting"; 
+        "System.Security"; "System.ServiceProcess"; "System.Transactions"; 
+        "System.Configuration"; "System.Web.Mobile"; "System.Web.RegularExpressions"; 
+        "System.Web.Services"; "System.Windows.Forms"; "System.Core";
+        "PresentationCore"; "PresentationFramework"; "WindowsBase"; "WindowsFormsIntegration"]
+      |> List.map ( fun n -> lazy(try Some(System.Reflection.Assembly.LoadWithPartialName(n)) with _ -> None); );
+
+    let dict = new Dictionary<string, Type>();
+
+    /// Tries to find .NET type for specified type name
+    /// This is used when we need to know type in order to generate something correctly,
+    /// but it's just a fallback case
+    let (|FoundSystemType|_|) s =
+      if (dict.ContainsKey(s)) then Some dict.[s] else
+      let ty = coreAssemblies |> Seq.tryPick ( fun lazyAsm -> 
+        match lazyAsm.Force() with 
+        | None -> None
+        | Some asm -> 
+            match (try asm.GetType(s) with _ -> null) with
+            | null -> None
+            | t -> Some t ) 
+      match ty with | Some t -> dict.Add(s, t) | _ -> ()
+      ty
+
+    //---------------------------------------------------------------------------------------------
+    // Interface recognition magic
+
+    // If the name of the type matches a name of interface declared in this file 
+    // (stored in a set in the context) than we treat it as an interface, otherwise
+    // we rely on .NET naming pattern (starts with I followed by uppercase letter)
+    // We could search known DLLs, but that's useless since all DLLs we could find
+    // follow this naming pattern...
+    let isInterface (t:CodeTypeReference) (ctx:Context) = 
+      let tn = t.BaseType.Substring(t.BaseType.LastIndexOf(".") + 1) 
+      let decLoc = Set.contains tn ctx.DeclaredInterfaces
+      decLoc || (tn.StartsWith("I") && (((tn.ToUpper()).[1]) = (tn.[1])))
+
+
+    // Splits base types into base class and implemented interfaces
+    // using rules described in <c>isInterface</c>
+    // Returns optional base class and list of interfaces
+    let resolveHierarchy (c:CodeTypeDeclaration) ctx =
+      let (interf, bcl) = 
+        c.BaseTypes |> Seq.cast |> Seq.toList
+          |> List.partition ( fun (r:CodeTypeReference) -> isInterface r ctx )
+          
+      if (bcl.Length = 0) then 
+        // All supertypes all interfaces
+        (None, interf)
+      elif (bcl.Length = 1) then 
+        // Exactly one supertype is class, other were recognized as interfaces
+        (Some (List.head bcl), interf) 
+      else 
+        // Fallback case - we found more than one supertypes that look like a class
+        // so we just return the tryPick one and treat other as interfaces
+        (Some (List.head bcl), (List.tail bcl)@interf) 
+        
+    
+    //---------------------------------------------------------------------------------------------
+    // Generating strings and working with context   
+    
+    let incIndent (ctx:Context) = 
+      ctx.Writer.Indent <- ctx.Writer.Indent + 1
+      ctx
+
+    let decIndent (ctx:Context) = 
+      ctx.Writer.Indent <- ctx.Writer.Indent - 1
+      ctx
+
+    /// Output string as a valid F# identifier
+    let (-!) (ctx:Context -> Context) (str:String) x =
+      let c = (ctx x)
+      c.Writer.Write(makeValidIdentifier str);
+      c;
+      
+    //---------------------------------------------------------------------------------------------
+    // Default values, types, generic parameters
+    
+    
+    
+    
+    
+    
+    let generateDefaultValue (t:CodeTypeReference) = 
+      if (t.ArrayElementType <> null) then
+        id -- "Unchecked.defaultof<_>"
+      else
+        match t.BaseType with 
+          | "System.Single" -> id -- "0.0f"
+          | "System.Double" -> id -- "0.0"
+          | "System.Char" -> id -- "'\000'"
+          | "System.Int16" -> id -- "0s"
+          | "System.Int32" -> id -- "0"
+          | "System.Int64" -> id -- "0L"
+          | "System.Byte" -> id -- "0uy"
+          | "System.SByte" -> id -- "0y"
+          | "System.UInt16" -> id -- "0us"
+          | "System.UInt32" -> id -- "0u"
+          | "System.UInt64" -> id -- "0UL"
+          | "System.String" -> id -- "\"\""
+          | "System.Boolean" -> id -- "false"
+          | _ -> id -- "Unchecked.defaultof<_>" 
+    
+    /// Get System.Type of know type (either standard type or resolved)  
+    let tryGetSystemType (cr:CodeTypeReference option) =
+      match cr with 
+        | None -> None
+        | Some cr when (cr.ArrayRank = 0) ->
+          match cr.BaseType with 
+          | "System.Single" -> Some (typeof<float32>)
+          | "System.Double" -> Some (typeof<float>)
+          | "System.Char" -> Some (typeof<char>)
+          | "System.Int16" -> Some (typeof<int16>)
+          | "System.Int32" -> Some (typeof<int>)
+          | "System.Int64" -> Some (typeof<int64>)
+          | "System.UInt16" -> Some (typeof<uint16>)
+          | "System.UInt32" -> Some (typeof<uint32>)
+          | "System.UInt64" -> Some (typeof<uint64>)
+          | "System.String" -> Some (typeof<string>)
+          | "System.Boolean" -> Some (typeof<bool>)
+          | FoundSystemType t -> Some t
+          | _ -> None;      
+        | _ -> None
+
+    /// Tries to resolve type of a variable and adds it to the Context dictionary
+    let tryAddVariableType (name:string) (cr:CodeTypeReference) (varTypes:Map<string,Type>) =
+      let ret t = Map.add name t varTypes
+      match tryGetSystemType (Some cr) with 
+        | Some t -> ret t; 
+        | _ -> varTypes
+
+    // Returns string with type arguments
+    let rec getTypeArgs (tya:CodeTypeReferenceCollection) renames ns tyParams fsSyntax =
+      if (tya.Count > 0) then
+        let sb = new StringBuilder()
+        sb.Append("<") |> ignore
+        for a in tya do
+          let str = (getTypeRef a renames ns tyParams fsSyntax):string
+          sb.Append(str).Append(", ") |> ignore
+        let s = sb.ToString()
+        s.Substring(0, s.Length - 2) + ">"
+      else
+        ""
+        
+        // Several standard renaming tricks      
+              
+    and isKnownSealedType (t:CodeTypeReference) = 
+        t.ArrayRank = 0 &&
+        match t.BaseType with 
+        | "System.String" 
+        | "System.Single" 
+        | "System.Double" 
+        | "System.DateTime" 
+        | "System.TimeSpan" 
+        | "System.Decimal" 
+        | "System.Char" 
+        | "System.SByte" 
+        | "System.Byte" 
+        | "System.Int16" 
+        | "System.Int32" 
+        | "System.Int64" 
+        | "System.UInt16" 
+        | "System.UInt32" 
+        | "System.UInt64" 
+        | "System.Boolean" -> true
+        | _ -> false;
+    /// Generates type reference (not for arrays)
+    and getBaseTypeRef (cr:CodeTypeReference) renames (ns:string) (tyParams:Set<string>) fsSyntax =
+      let s = 
+      
+        // Remove current namespace name, because it can't be used in this scope
+        let bst = 
+          if (cr.BaseType.StartsWith(ns+".")) then 
+            cr.BaseType.Substring(ns.Length+1) 
+          elif cr.Options &&& CodeTypeReferenceOptions.GlobalReference <> enum 0 then 
+            "global."+cr.BaseType
+          else 
+            cr.BaseType
+      
+        // Several standard renaming tricks      
+        match Map.tryFind bst renames with
+          // Renamed type (former nested type)
+          | Some nn -> nn
+          
+          // It is a type paramter - rename T to 'T
+          | None when Set.contains cr.BaseType tyParams ->
+              "'" + cr.BaseType
+              
+          // Try if it's standard F# type
+          // This also renames Void to unit, which may not be completly correct, 
+          // but it works much better than if we don't do it
+          | None when fsSyntax ->
+              match cr.BaseType with 
+              | "System.Void" -> "unit"
+              | "System.Object" -> "obj"
+              | "System.String" -> "string"
+              | "System.Single" -> "float32"
+              | "System.Double" -> "float"
+              | "System.Char" -> "char"
+              | "System.Int16" -> "int16" 
+              | "System.Int32" -> "int" 
+              | "System.Int64" -> "int64" 
+              | "System.UInt16" -> "uint16" 
+              | "System.UInt32" -> "uint32" 
+              | "System.UInt64" -> "uint64" 
+              | "System.Boolean" -> "bool"
+              | _ -> bst;
+          | _ -> bst;          
+      // drop `xyz, replace "+" for nested classes with "."
+      let sb = new StringBuilder()
+      let mutable i = 0 
+      while i < s.Length do
+        let c = s.[i]
+        match c with
+          | _ when c = '+' || c = '.' -> sb.Append('.') |> ignore;
+          | '`' -> i <- i + 1;
+                   while (i<s.Length && s.[i]>='0' && s.[i]<='9') do 
+                     i <- i + 1
+          | _ -> sb.Append(c) |> ignore
+        i <- i + 1      
+      // generate type arguments
+      sb.Append(getTypeArgs cr.TypeArguments renames ns tyParams fsSyntax).ToString()
+      
+    /// Generate type reference with empty context
+    and getBaseTypeRefString (s:string) =
+      getBaseTypeRef (CodeTypeReference(s)) Map.empty "" Set.empty true
+    
+    
+    /// Get full type reference using information from context  
+    and getTypeRef (c:CodeTypeReference) (rens:Map<string,string>) (ns:string) (tyParams:Set<string>) (fsSyntax:bool) =
+      if (c = null) then  
+        ""
+      elif (c.ArrayRank = 0) then 
+        getBaseTypeRef c rens ns tyParams fsSyntax
+      else      
+        let baseType = (getTypeRef c.ArrayElementType rens ns tyParams fsSyntax)
+        baseType + "[" + (System.String.Concat (Array.create (c.ArrayRank - 1) ",")) + "]"
+
+    /// Get full type reference string using empty context
+    and getTypeRefSimple (c:CodeTypeReference) = getTypeRef c Map.empty "" Set.empty true
+    
+    /// Get type reference, but don't rename .NET types to F# types
+    /// (this is only needed when calling static methods on the type)
+    let generateTypeRefNet (c:CodeTypeReference) =
+      id +> withCtxt ( fun ctx -> id -- getTypeRef c ctx.TypeRenames ctx.CurrentNamespace ctx.TypeArgumentNames false )
+    
+    /// Generate type reference using context
+    /// (this is most commonly used method)  
+    let generateTypeRef (c:CodeTypeReference) =
+      id +> withCtxt ( fun ctx -> id -- getTypeRef c ctx.TypeRenames ctx.CurrentNamespace ctx.TypeArgumentNames true )
+             
+    /// Generate type arguments using context
+    let generateTypeArgs (c:CodeTypeReferenceCollection) =
+      id +> withCtxt ( fun ctx -> id -- getTypeArgs c ctx.TypeRenames ctx.CurrentNamespace ctx.TypeArgumentNames true )
+             
+    
+    /// Record specified type parameters in the context, call generating function
+    /// and then restore the original type parameters
+    /// (this works if someone uses nested type parameters with the same name)
+    let usingTyParams tyArgs f (x:Context) =
+      let o = x.TypeArgumentNames
+      let n = Array.foldBack Set.add (Array.ofSeq tyArgs) o
+      let x = f { x with TypeArgumentNames = n }
+      { x with TypeArgumentNames = o }      
+
+
+    /// Preprocess collection with type parameters
+    /// Returns array to be used with <c>usingTyParams</c> and
+    /// function to be called to generate < ... > code
+    let processTypeArgs (args:CodeTypeParameterCollection) =     
+      let tyargs = seq { for (p:CodeTypeParameter) in args -> p.Name }       
+      let genTyArgs =
+        if (args.Count = 0) then id else
+        let s = tyargs |> Seq.fold (fun ctx s -> ctx + ", '" + s) ""
+        id 
+        -- "<" -- s.Substring(2, s.Length-2)
+        +> if (args.Count = 0) then id -- ">" else
+             let argsWithConstr = args |> Seq.cast |> Seq.filter (fun (p:CodeTypeParameter) -> 
+               p.Constraints.Count <> 0 || p.HasConstructorConstraint) |> Seq.cast |> Seq.toList
+             if (argsWithConstr.Length <> 0) then
+               id -- " when " +>
+               col sepWordAnd argsWithConstr (fun (p:CodeTypeParameter) -> 
+                 col sepWordAnd p.Constraints (fun impl ->
+                   id -- "'" -- p.Name -- " :> " +> generateTypeRef impl)
+                 +> if (not p.HasConstructorConstraint) then id else
+                      if (p.Constraints.Count <> 0) then id -- " and " else id
+                      -- "'" -- p.Name -- " : (new:unit->'" -- p.Name -- ")")
+               -- ">"
+             else id -- ">"
+      tyargs, genTyArgs
+    
+    //---------------------------------------------------------------------------------------------
+    // Binary operators and numeric functions
+    
+    /// Generates code for binary operator using function for left and right operand
+    let binaryOp (op:CodeBinaryOperatorType) fleft fright =
+      id -- "(" +>
+      match op with    
+        | CodeBinaryOperatorType.Add -> fleft -- " + " +> fright;
+        | CodeBinaryOperatorType.BitwiseAnd -> fleft -- " &&& " +> fright;
+        | CodeBinaryOperatorType.BitwiseOr -> fleft -- " ||| " +> fright;
+        | CodeBinaryOperatorType.BooleanAnd -> fleft -- " && " +> fright;
+        | CodeBinaryOperatorType.BooleanOr -> fleft -- " || " +> fright;
+        | CodeBinaryOperatorType.Divide -> fleft -- " / " +> fright;
+        | CodeBinaryOperatorType.GreaterThan -> fleft -- " > " +> fright;
+        | CodeBinaryOperatorType.GreaterThanOrEqual -> fleft -- " >= " +> fright;
+        | CodeBinaryOperatorType.LessThan -> fleft -- " < " +> fright;
+        | CodeBinaryOperatorType.LessThanOrEqual -> fleft -- " <= " +> fright;
+        | CodeBinaryOperatorType.Modulus -> fleft -- " % " +> fright;
+        | CodeBinaryOperatorType.Multiply -> fleft -- " * " +> fright;
+        | CodeBinaryOperatorType.Subtract -> fleft -- " - " +> fright;
+        
+        // REVIEW: this is not used in any tests and it is not sure what it means
+        | CodeBinaryOperatorType.Assign -> fleft -- " <- " +> fright; 
+        
+        // REVIEW: reference and value equality use C# semantics, so it is not sure what we should generate
+        | CodeBinaryOperatorType.ValueEquality -> fleft -- " = " +> fright;  
+        | CodeBinaryOperatorType.IdentityEquality -> id -- "System.Object.ReferenceEquals(" +> fleft -- ", " +> fright -- ")"; 
+        | CodeBinaryOperatorType.IdentityInequality -> id -- "not (System.Object.ReferenceEquals(" +> fleft -- ", " +> fright -- "))"; 
+        | _ -> failwithf "unimplemented binary operator type '%A'" op;
+      -- ")"
+    
+    /// Are both types numerical types where numeric conversion function can be applied?
+    let rec isNumericConversion (src:Type) (target:Type) = 
+      convertFunc src <> "" && convertFunc target <> ""
+    
+    
+    /// Returns F# conversion function for the specified type (or empty string)
+    and convertFunc (ty:Type) = 
+      if (ty = (typeof<int16>)) then "int16"
+      elif (ty = (typeof<int32>)) then "int32"
+      elif (ty = (typeof<int64>)) then "int64"
+      elif (ty = (typeof<int16>)) then "uint16"
+      elif (ty = (typeof<int32>)) then "uint32"
+      elif (ty = (typeof<int64>)) then "uint64"
+      elif (ty = (typeof<float>)) then "float"
+      elif (ty = (typeof<float32>)) then "float32"
+      elif (ty = (typeof<decimal>)) then "decimal"
+      elif (ty = (typeof<byte>)) then "byte"
+      elif (ty = (typeof<sbyte>)) then "sbyte"
+      else ""
+    
+    
+    /// Generate value of primitive expression  
+    let generatePrimitiveExpr (reqty:Type option) (c:CodePrimitiveExpression) =
+      let (value, typ) = 
+        match c.Value with
+          | :? Char as c -> (sprintf "%A" c, Some(typeof<Char>))
+          | :? String as s -> (sprintf "\"%s\"" (s.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n").Replace("\t", "\\t").Replace("\r", "\\r").Replace("\b", "\\b")), Some(typeof<string>)) 
+          | :? Boolean as b -> ((if (b) then "true" else "false"), Some(typeof<bool>))
+          | :? Single as f -> (sprintf "%A" f, Some(typeof<float32>))
+          | :? Double as f -> (sprintf "%A" f, Some(typeof<float>))
+          | :? Byte as i -> (sprintf "%A" i, Some(typeof<Byte>))
+          | :? SByte as i -> (sprintf "%A" i, Some(typeof<SByte>))
+          | :? Int16 as i -> (sprintf "%A" i, Some(typeof<int16>))
+          | :? Int32 as i -> (sprintf "%A" i, Some(typeof<int>))
+          | :? Int64 as i -> (sprintf "%A" i, Some(typeof<int64>))
+          | :? UInt16 as i -> (sprintf "%A" i, Some(typeof<uint16>))
+          | :? UInt32 as i -> (sprintf "%A" i, Some(typeof<uint32>))
+          | :? UInt64 as i -> (sprintf "%A" i, Some(typeof<uint64>))
+          | null -> ("(Unchecked.defaultof<_>)", None)
+          | _ -> ("(* Unknown primitive value '"+c.Value.ToString()+"' of type '"+
+                  c.Value.GetType().Name+"'. Please report this to the F# team. *)", None) 
+      match typ, reqty with        
+        | Some t, Some rt when t <> rt -> id -- convertFunc rt -- " (" -- value -- ")"
+        | _, _ ->  id -- value
+        
+        
+    /// Generate array initializer. Checks generator options for ASP.NET workaround.
+    let rec generateArrayCreateExpr (c:CodeArrayCreateExpression) =
+      if (c.Initializers<>null && c.Initializers.Count>0) then
+        id
+        -- "([| " +> col sepArgsSemi c.Initializers generateExpression -- " |] : "
+        +> withCtxt (fun ctx -> 
+            generateTypeRef c.CreateType          
+            -- if (ctx.Options &&& AdditionalOptions.AspNetArrays <> enum 0) then "[]" else "")
+        -- ")" 
+      else
+        id
+        -- "(Array.zeroCreate "
+        +> if (c.SizeExpression <> null) then
+              id -- "(" +> generateExpression c.SizeExpression -- ")"
+           else
+              id +> str c.Size
+        -- ":"
+        +> withCtxt (fun ctx -> 
+            generateTypeRef c.CreateType          
+            -- if (ctx.Options &&& AdditionalOptions.AspNetArrays <> enum 0) then "[]" else "")
+        -- ")";
+    
+    /// Tries to resolve if type is an array, so we can generate 
+    /// appropriate code (it can be either indexer or array, but we need to generate
+    /// .Item call for indexers (no overloading is supported by .[]).
+    /// Returns: "None" - can't resolve, "Some" resovled (true/false - is it an array?)
+    and tryIsExpressionArray c (ctx:Context) = 
+      match (c :> CodeExpression) with
+        | :? CodeFieldReferenceExpression as ce when 
+             (ce.TargetObject :? CodeThisReferenceExpression) -> 
+             match Map.tryFind ce.FieldName ctx.FieldTypes with 
+               | Some t -> Some (t.ArrayRank > 0)
+               | None -> None
+        | :? CodePropertyReferenceExpression as ce when 
+             (ce.TargetObject :? CodeThisReferenceExpression) -> 
+             match Map.tryFind ce.PropertyName ctx.PropertyTypes with 
+               | Some t -> Some (t.ArrayRank > 0)
+               | None -> None
+        | _ -> None    
+    
+    
+    /// Tries to resolve type of an expression using a few tricks:
+    /// * Fields of current type may have known type
+    /// * Properties of current type as well
+    /// * We can also try to resolve other properties (sometimes it helps)
+    /// * Resolve type for local variables or argument reference 
+    and tryGetExpressionType c (ctx:Context) = 
+      match (c :> CodeExpression) with
+        | :? CodeFieldReferenceExpression as ce when 
+             (ce.TargetObject :? CodeThisReferenceExpression) -> 
+             tryGetSystemType (Map.tryFind ce.FieldName ctx.FieldTypes)
+        | :? CodePropertyReferenceExpression as ce when 
+             (ce.TargetObject :? CodeThisReferenceExpression) -> 
+             tryGetSystemType (Map.tryFind ce.PropertyName ctx.PropertyTypes)
+        | :? CodePropertyReferenceExpression as ce ->
+               match (tryGetExpressionType ce.TargetObject ctx) with
+                 | None -> None
+                 | Some t ->
+                     try 
+                       Some (t.GetProperty(ce.PropertyName).PropertyType)
+                     with _ ->
+                       None
+        | :? CodeArgumentReferenceExpression as ce ->                              
+               Map.tryFind ce.ParameterName ctx.LocalVariableTypes  
+               // NOTE:
+               // XSD generates incorrect referenece (uses argument ref where it should be variable ref)
+               // and unfortunately it is followed by wrong numeric type, so we need to workaround this
+        | :? CodeVariableReferenceExpression as ce ->
+               Map.tryFind ce.VariableName ctx.LocalVariableTypes 
+        | _ -> None
+      
+    //---------------------------------------------------------------------------------------------
+    // Generating code for expressions
+          
+    /// Generates a "this" or "CurrentType" reference depending on whether a reference
+    /// is static or not. Used for "ambiguous" references without a type or object qualifier.
+    ///
+    /// Unfortunately the Code tree isn't so kind as to tell us whether a reference is static
+    /// or not up front. Instead we predetermine a set of some static members and 
+    /// assume all other references are instance references. 
+    ///
+    and generateExpressionDefaultThis isKnownStatic c = 
+      withCtxt (fun ctx -> 
+          match c with 
+          | null -> 
+              // REVIEW: this is still incorrect if the reference is static and it is a reference from an inherited type
+              id -- (if isKnownStatic then ctx.CurrentType.Name else "this" )  
+          | _ -> generateExpression c)
+        
+    /// Matches array or indexer expression and corrects it if the generated CodeDOM is incorrect
+    and (|CodeArrayAccessOrIndexer|_|) (ctx:Context) (c:CodeExpression) =
+      let noneT b = match b with Some v -> v | _ -> true
+      let noneF b = match b with Some v -> v | _ -> false
+      match c with 
+        | :? CodeArrayIndexerExpression as ce -> 
+             Some(true && (noneT (tryIsExpressionArray ce.TargetObject ctx)), ce.TargetObject, ce.Indices)
+        | :? CodeIndexerExpression as ce -> 
+             Some(false || (noneF (tryIsExpressionArray ce.TargetObject ctx)), ce.TargetObject, ce.Indices)
+        | _ -> None
+      
+    /// Generate expression - with unkonw type
+    and generateExpression c = generateExpressionTyped None c    
+ 
+    // Generates code for CodeExpression
+    // If the caller knows the expected type of the expression it can be given as an argument,
+    // but currently it is used only when generating primitve expression to convert value to the right type
+    and generateExpressionTyped ty c ctx = 
+      (match c with 
+        | :? CodeArgumentReferenceExpression as ce ->
+              id -! ce.ParameterName
+        | :? CodeArrayCreateExpression as ce ->
+              id +> generateArrayCreateExpr ce              
+        
+        // for indexers we generate get_Item to handle overloading
+        | CodeArrayAccessOrIndexer ctx (isArray, target, indices) ->
+              id
+              +> generateExpression target -- "."
+              +> id -- "[" +> col sepArgs indices generateExpression -- "]" 
+              
+        | :? CodeBaseReferenceExpression as ce ->
+              id -- "base"
+              
+        | :? CodeBinaryOperatorExpression as ce ->
+              binaryOp ce.Operator (generateExpressionTyped ty ce.Left) (generateExpressionTyped ty ce.Right)
+        
+        // casting can also represent numeric conversion - we try to detect that case      
+        | :? CodeCastExpression as ce -> 
+              id 
+              +> withCtxt (fun ctx -> 
+                  match tryGetExpressionType (ce.Expression) ctx, tryGetSystemType (Some ce.TargetType) with
+                  | Some(t1), Some(t2) when isNumericConversion t1 t2 ->
+                      id
+                      -- "(" -- (convertFunc t2)
+                      -- "(" +> generateExpression ce.Expression -- "))"
+                  | _ ->
+                    id
+                    -- "((" +> generateExpression ce.Expression -- " :> obj) :?> " +> generateTypeRef ce.TargetType -- ")" )
+        
+        // argument for "ref" or "out" C# parameter - both generated as byref in F#
+        | :? CodeDirectionExpression as ce ->
+              match ce.Direction with 
+              | FieldDirection.Out 
+              | FieldDirection.Ref -> 
+                  id -- "&" +> generateExpression ce.Expression
+              | _ -> 
+                  id +> generateExpression ce.Expression
+        
+        // for delegates, we use 'FuncFromTupled' to get the right function type      
+        | :? CodeDelegateCreateExpression as ce ->
+              id 
+              -- "new " +> generateTypeRef ce.DelegateType -- "(FuncConvert.FuncFromTupled " 
+              +> generateExpression ce.TargetObject 
+              -- "." -- ce.MethodName -- ")";
+        
+        | :? CodeDelegateInvokeExpression as ce ->
+              id
+              +> match ce.TargetObject with 
+                  // "this.<DeclaredEventName>( ... )" - will be translated to a raise function returned
+                  // by create_DelegateEvent
+                  | :? CodeEventReferenceExpression as eref when  
+                      (eref.TargetObject :? CodeThisReferenceExpression) 
+                      && ((ctx.DeclaredEvents |> List.tryFind (fun e -> e.Name = eref.EventName)) <> None) -> 
+                      // F# declared event..
+                      id
+                      -- "this._invoke_" -- eref.EventName -- " [| "
+                      +> col sepArgsSemi ce.Parameters (fun (e:CodeExpression) ->
+                           id
+                           -- " box (" 
+                           +> generateExpression e
+                           -- ")" ) -- " |]"
+                  // other than this.<Event>(). This may not be correct (but works on cases in test suite)
+                  | _ -> 
+                      generateExpression ce.TargetObject 
+                      -- ".Invoke(" +> col sepArgs ce.Parameters generateExpression -- ")"
+        
+        // this prevents using mutable variable in a way it would escape its scope
+        | :? CodeEventReferenceExpression as ce ->
+              id -- "let __e = " +> generateExpression ce.TargetObject -- " in __e." -- ce.EventName
+                          
+        | :? CodeFieldReferenceExpression as ce -> 
+              withCtxt (fun ctx ->  
+              
+                // if 'UnknownFieldsAsLocals' is set than the code will generate
+                // "fld" instead of "this.fld" when accessing field that is not known
+                let sft =
+                  match ce.TargetObject with
+                  | :? CodeThisReferenceExpression as t when 
+                       (ctx.Options &&& AdditionalOptions.UnknonwFieldsAsLocals <> enum 0) ->
+                       Option.isNone (Map.tryFind ce.FieldName ctx.FieldTypes)
+                  | _ -> false
+                if sft then
+                  id -! ce.FieldName
+                else
+                  id 
+                  +> match ce.TargetObject with 
+                       | :? CodeTypeReferenceExpression as ct ->
+                             id +> generateTypeRefNet ct.Type
+                       | _ -> 
+                           let isKnownStatic = 
+                               match ce.TargetObject, ctx.AllFields.TryFind ce.FieldName with 
+                               | null, Some m -> 
+                                  (m.Attributes &&& MemberAttributes.ScopeMask = MemberAttributes.Static) 
+                               | _ -> false
+                           generateExpressionDefaultThis isKnownStatic ce.TargetObject
+                 -- "." -- ce.FieldName )
+              
+        | :? CodeMethodInvokeExpression as ce ->
+              id 
+              +> generateExpression (ce.Method :> CodeExpression) 
+              -- "(" +> col sepArgs ce.Parameters generateExpression -- ")" 
+              
+        | :? CodeMethodReferenceExpression as ce ->
+              id 
+              +> match ce.TargetObject with 
+                   | :? CodeTypeReferenceExpression as ct ->
+                         id +> generateTypeRefNet ct.Type
+                   | _ -> 
+                       let isKnownStatic = 
+                           match ce.TargetObject, ctx.AllMeths.TryFind ce.MethodName with 
+                           | null, Some m -> 
+                              (m.Attributes &&& MemberAttributes.ScopeMask = MemberAttributes.Static) 
+                           | _ -> false
+                       generateExpressionDefaultThis isKnownStatic ce.TargetObject
+              -- "." -- ce.MethodName 
+              +> generateTypeArgs ce.TypeArguments
+              
+        | :? CodeObjectCreateExpression as ce ->
+              id
+              -- "new " +> generateTypeRef ce.CreateType 
+              -- "(" +> col sepArgs ce.Parameters generateExpression -- ")" 
+              
+        | :? CodePrimitiveExpression as ce -> 
+              id +> generatePrimitiveExpr ty ce 
+              
+        | :? CodePropertyReferenceExpression as ce ->
+              id 
+              +> match ce.TargetObject with 
+                   | :? CodeTypeReferenceExpression as ct ->
+                         id +> generateTypeRefNet ct.Type
+                   | _ -> 
+                       let isKnownStatic = 
+                           match ce.TargetObject, ctx.AllProps.TryFind ce.PropertyName with 
+                           | null, Some m -> 
+                              (m.Attributes &&& MemberAttributes.ScopeMask = MemberAttributes.Static) 
+                           | _ -> false
+                       generateExpressionDefaultThis isKnownStatic ce.TargetObject
+              -- "." -- ce.PropertyName 
+              
+        | :? CodePropertySetValueReferenceExpression as ce ->  
+              id -- "value"
+              
+        // we move all lines of "snippets" by 100 columns so it isn't violating #light rules
+        | :? CodeSnippetExpression as ce ->
+              let strs = 
+                ce.Value.Split([| '\r'; '\n' |], StringSplitOptions.RemoveEmptyEntries)
+                |> Array.map (fun s -> String(' ',100) + s )
+              colT sepNone strs (fun s -> id ++ s)
+
+        | :? CodeThisReferenceExpression as ce ->  
+              id -- "this"
+              
+        | :? CodeTypeOfExpression as ce ->  
+              id -- "(typeof<" +> generateTypeRef ce.Type -- ">)"
+              
+        | :? CodeTypeReferenceExpression as ce ->  
+              id +> generateTypeRef ce.Type 
+              
+        | :? CodeVariableReferenceExpression as ce ->            
+              match ty with 
+              | Some t when (convertFunc t) <> "" -> id -- "(" -- (convertFunc t) -- " " -! ce.VariableName -- ")"
+              | _ -> id -! ce.VariableName
+              
+        | null ->
+            id 
+            
+        | _ -> id 
+               -- "(* Unknown expression type '" -- (c.GetType().Name) 
+               -- "' please report this to the F# team. *)") ctx
+    
+    //---------------------------------------------------------------------------------------------
+    // Generating code for statements
+      
+    and generateVariableDeclStmt (c:CodeVariableDeclarationStatement) =
+      id
+      +> (fun ctx -> { ctx with LocalVariableTypes = tryAddVariableType c.Name c.Type ctx.LocalVariableTypes } )
+      ++ "let mutable (" -! c.Name -- ":" +> generateTypeRef c.Type -- ") = "
+      +> if (c.InitExpression <> null) then 
+           (generateExpressionTyped (tryGetSystemType (Some c.Type))) c.InitExpression 
+         else 
+           (generateDefaultValue c.Type);
+    
+    // REVIEW: Line pragmas don't work with the #light syntax
+    let generateLinePragma (l:CodeLinePragma) = 
+      if (l = null) then id else
+        id 
+        ++ "# " +> str l.LineNumber -- " \"" -- l.FileName -- "\""
+        
+    let rec generateCatchClause (c:CodeCatchClause) =
+      id
+      ++ "| :? " +> generateTypeRef c.CatchExceptionType 
+      -- " as " -- c.LocalName -- " ->" +> incIndent
+      +> generateStatements c.Statements +> decIndent
+
+    and generateStatements (sts:CodeStatementCollection) = 
+      let fix = 
+        if (sts.Count = 0 || (sts.[sts.Count - 1] :? CodeVariableDeclarationStatement))
+          then id ++ "()" else id
+      col sepNone sts generateStatement +> fix      
+
+    // Generates block of statements which can return a value
+    and generateStatementBlock typ (statements:CodeStatementCollection) =        
+      // determine if the block uses only "safe" return statements
+      // that can be translated to functional returns without using exceptions
+      let safeReturns = 
+        statements 
+        |> codeDomCallbackWithScope (fun rcall safeScope res o -> 
+            match o with 
+            | :? CodeMethodReturnStatement as ret -> safeScope && res
+            | :? CodeTryCatchFinallyStatement as tfs -> rcall (safeScope && (tfs.CatchClauses.Count = 0)) res o
+            | :? CodeStatementCollection -> rcall safeScope res o
+            | _ -> rcall false res o ) true true
+    
+      id
+      +> incIndent
+      +> (fun ctx -> { ctx with CurrentMethodReturnType=typ; 
+                                LocalVariableTypes = Map.empty; 
+                                ReturnUsingException = not safeReturns })
+      // if returning using exception - wrap inside try .. catch
+      +> if (not safeReturns) then id ++ "try" +> incIndent else id
+      +> generateStatements statements
+      +> if (safeReturns) then id else
+           match typ with 
+           | Some t when t.BaseType <> "System.Void" -> 
+               id ++ "failwith \"Code branch didn't return any value!\";"
+               +> decIndent
+               ++ "with" ++ "    | ReturnException" +> uniqid -- " v -> (v :?> " +> generateTypeRef t -- ")"
+           | _ ->  
+               id ++ "raise ReturnNoneException" +> uniqid 
+               +> decIndent
+               ++ "with" ++ "    | ReturnNoneException" +> uniqid -- " -> ()"
+      +> (fun ctx -> {ctx with CurrentMethodReturnType=None; 
+                               LocalVariableTypes = Map.empty; 
+                               ReturnUsingException = false })
+      +> decIndent
+
+    and generateComment (c:CodeComment) =
+      id 
+      -- if c.DocComment then "/// " else "// " 
+      -- (c.Text);
+
+    and generateExpressionThenUpCast e (t: CodeTypeReference) = 
+        if isKnownSealedType t then 
+            generateExpression e
+        else
+            id -- "((" +> generateExpression e -- " :> obj) :?> " +> generateTypeRef t -- ")" 
+          
+    and generateStatement (c:CodeStatement) = 
+      (generateLinePragma c.LinePragma) +>
+      (match c with 
+        | :? CodeAssignStatement as cs -> 
+              match cs.Left with 
+                | :? CodeIndexerExpression as ci ->
+                    id ++ "" 
+                    +> generateExpressionDefaultThis false ci.TargetObject -- ".set_Item(" 
+                    +> col sepArgs ci.Indices generateExpression -- ", "
+                    +> withCtxt (fun ctx -> generateExpressionTyped (tryGetExpressionType cs.Left ctx) cs.Right)
+                    -- ")"
+                | _ ->
+                    id ++ "" +> generateExpression cs.Left 
+                    -- " <- " 
+                    +> withCtxt (fun ctx -> generateExpressionTyped (tryGetExpressionType cs.Left ctx) cs.Right)
+                    
+        | :? CodeAttachEventStatement as cs ->
+              id ++ "" +> generateExpression (cs.Event :> CodeExpression) 
+              -- ".AddHandler(" +> generateExpression cs.Listener -- ")"
+              
+        | :? CodeCommentStatement as cs -> 
+              id ++ "" +> generateComment cs.Comment 
+              
+        | :? CodeConditionStatement as cs ->
+              id 
+              ++ "if " +> generateExpression cs.Condition -- " then"
+              +> incIndent +> col sepNone cs.TrueStatements generateStatement +> decIndent
+              +> if (cs.FalseStatements<>null && cs.FalseStatements.Count>0) then 
+                   id 
+                   ++ "else" +> incIndent 
+                   +> col sepNone cs.FalseStatements generateStatement +> decIndent else id                
+                   
+        | :? CodeExpressionStatement as cs -> 
+              id ++ "" +> generateExpression cs.Expression -- " |> ignore";
+              
+        | :? CodeIterationStatement as cs ->
+              id 
+              +> generateStatement cs.InitStatement
+              ++ "while " +> generateExpression cs.TestExpression -- " do"
+              +> incIndent
+              +> col sepNone cs.Statements generateStatement 
+              +> generateStatement cs.IncrementStatement
+              +> decIndent
+              
+        // Return - either throw "ReturnException" or just generate F# expression with the value
+        | :? CodeMethodReturnStatement as cs -> 
+              id
+              +> withCtxt (fun ctx -> 
+                   if (ctx.ReturnUsingException) then
+                       id 
+                       ++ "raise ("
+                       +> match ctx.CurrentMethodReturnType with
+                          | Some t when t.BaseType <> "System.Void" -> 
+                              id -- "ReturnException" +> uniqid -- "(" +> generateExpressionThenUpCast cs.Expression t -- ")"
+                          | _ -> 
+                              id -- "ReturnNoneException" +> uniqid
+                       -- ")"
+                   else 
+                       match ctx.CurrentMethodReturnType with
+                       | Some t when t.BaseType <> "System.Void" -> 
+                           id 
+                           ++ "" +> generateExpressionThenUpCast cs.Expression t
+                       | _ ->      id ++ "")
+                     
+        | :? CodeSnippetStatement as cs ->
+              let strs = cs.Value.Split([| '\r'; '\n' |], StringSplitOptions.RemoveEmptyEntries);
+              colT sepNone strs (fun s -> id ++ s)
+              
+        | :? CodeVariableDeclarationStatement as cs -> 
+              id +> generateVariableDeclStmt cs
+              
+        | :? CodeThrowExceptionStatement as cs ->            
+              id ++ "raise (" +> generateExpression cs.ToThrow -- ")"
+        
+        // try .. catch .. finaly is generated as try (try .. catch) finally      
+        | :? CodeTryCatchFinallyStatement as cs -> 
+              let hasCatch = (cs.CatchClauses<>null && cs.CatchClauses.Count>0) 
+              let hasFinally = (cs.FinallyStatements<>null && cs.FinallyStatements.Count>0) 
+              id 
+              ++ "try" +> incIndent
+              +> if (hasCatch && hasFinally) then id ++ "try" +> incIndent else id
+              +> generateStatements cs.TryStatements 
+              +> if (cs.CatchClauses<>null && cs.CatchClauses.Count>0) then 
+                   decIndent 
+                   ++ "with" +> incIndent 
+                   +> col sepNone cs.CatchClauses generateCatchClause
+                   +> decIndent else id;
+              +> if (cs.FinallyStatements<>null && cs.FinallyStatements.Count>0) then 
+                   decIndent
+                   ++ "finally" +> incIndent 
+                   +> col sepNone cs.FinallyStatements generateStatement
+                   +> decIndent else id;
+                   
+        | _ -> id 
+               -- "(* Unknown statement type '" -- (c.GetType().Name) 
+               -- "' please report this to the F# team. *)")
+
+    //---------------------------------------------------------------------------------------------
+    // Support for class members (Custom attributes, paramters, etc..)
+        
+    let generateAttributeArg (c:CodeAttributeArgument) =
+      id
+      +> if (c.Name<> null && c.Name.Length>0) then 
+          id -- c.Name -- "=" else id
+      +> generateExpression c.Value;
+      
+    let generateCustomAttrDecl (c:CodeAttributeDeclaration) =
+      id
+      -- (getBaseTypeRefString c.Name)
+      +> if (c.Arguments.Count = 0) then id else
+           id -- "(" +> (col sepArgs c.Arguments generateAttributeArg) -- ")" 
+          
+    let generateCustomAttrDeclsList (c:CodeAttributeDeclaration list) =
+      id 
+      +> if (c.Length = 0) then id else 
+           id ++ "[<" +> (colT sepNlnSemiSpace c generateCustomAttrDecl) -- ">]"
+          
+    let generateCustomAttrDeclsForType (c:CodeAttributeDeclaration list) (a:Reflection.TypeAttributes) =
+      id 
+      +> if (c.Length = 0)
+            && (a &&& TypeAttributes.Abstract  = enum 0)
+            && (a &&& TypeAttributes.Sealed  = enum 0) then id 
+         else 
+           id ++ "[<" 
+                 +> (colT sepNlnSemiSpace [ for x in c do yield generateCustomAttrDecl x
+                                            if a &&& TypeAttributes.Abstract <> enum 0 then yield (id -- "Microsoft.FSharp.Core.AbstractClassAttribute" +> sepNlnSemiSpace)
+                                            if a &&& TypeAttributes.Sealed   <> enum 0 then yield (id -- "Microsoft.FSharp.Core.SealedAttribute" +> sepNlnSemiSpace) ]
+                                          (fun c -> c) )                                           
+              -- ">]"
+          
+(*
+VisibilityMask Specifies type visibility information. 
+ NotPublic Specifies that the class is not public. 
+ Public Specifies that the class is public. 
+ NestedPublic Specifies that the class is nested with public visibility. 
+ NestedPrivate Specifies that the class is nested with private visibility. 
+ NestedFamily Specifies that the class is nested with family visibility, and is thus accessible only by methods within its own type and any subtypes. 
+ NestedAssembly Specifies that the class is nested with assembly visibility, and is thus accessible only by methods within its assembly. 
+ NestedFamANDAssem Specifies that the class is nested with assembly and family visibility, and is thus accessible only by methods lying in the intersection of its family and assembly. 
+ NestedFamORAssem Specifies that the class is nested with family or assembly visibility, and is thus accessible only by methods lying in the union of its family and assembly. 
+ LayoutMask Specifies class layout information. 
+ AutoLayout Specifies that class fields are automatically laid out by the common language runtime. 
+ SequentialLayout Specifies that class fields are laid out sequentially, in the order that the fields were emitted to the metadata. 
+ ExplicitLayout Specifies that class fields are laid out at the specified offsets. 
+ ClassSemanticsMask Specifies class semantics information; the current class is contextful (else agile). 
+ Class Specifies that the type is a class. 
+ Interface Specifies that the type is an interface. 
+    DONE: Abstract Specifies that the type is abstract. 
+    DONE: Sealed Specifies that the class is concrete and cannot be extended. 
+ SpecialName Specifies that the class is special in a way denoted by the name. 
+ Import Specifies that the class or interface is imported from another module. 
+ Serializable Specifies that the class can be serialized. 
+ StringFormatMask Used to retrieve string information for native interoperability. 
+ AnsiClass LPTSTR is interpreted as ANSI. 
+ UnicodeClass LPTSTR is interpreted as UNICODE. 
+ AutoClass LPTSTR is interpreted automatically. 
+ CustomFormatClass LPSTR is interpreted by some implementation-specific means, which includes the possibility of throwing a NotSupportedException. 
+ CustomFormatMask Used to retrieve non-standard encoding information for native interop. The meaning of the values of these 2 bits is unspecified. 
+ BeforeFieldInit Specifies that calling static methods of the type does not force the system to initialize the type. 
+ ReservedMask Attributes reserved for runtime use. 
+ RTSpecialName Runtime should check name encoding. 
+ HasSecurity 
+*)
+
+    let generateCustomAttrDecls (c:CodeAttributeDeclarationCollection) = 
+      generateCustomAttrDeclsList (c |> Seq.cast |> Seq.toList)
+      
+    // NOTE: may contain custom attributes - this isn't supported
+    let generateParamDecl (c:CodeParameterDeclarationExpression) =
+      let dir = if (c.Direction <> FieldDirection.In) then " byref" else ""
+      id 
+      -! c.Name -- ":" +> generateTypeRef c.Type -- dir;
+
+    // NOTE: may contain custom attributes - this isn't supported
+    let generateAbstractParamDecl (c:CodeParameterDeclarationExpression) =
+      let dir = if (c.Direction <> FieldDirection.In) then " byref" else ""
+      id +> generateTypeRef c.Type -- dir
+
+    // Find all overloads of the method, so we can produce [<OverloadID>]
+    let getMethodOverloads (membs:CodeTypeMemberCollection) = 
+      let getMethodOverload map (n:CodeMemberMethod) = 
+        let n = (n.Name, getTypeRefSimple n.PrivateImplementationType)
+        match Map.tryFind n map with 
+          | Some v -> v 
+          | None -> 0
+      let incMethodOverload (n:CodeMemberMethod) map = 
+        let n = (n.Name, getTypeRefSimple n.PrivateImplementationType)
+        match Map.tryFind n map with 
+          | Some v -> Map.add n (v+1) map
+          | None -> Map.add n 1 map          
+      let m,a = 
+        membs 
+        |> codeDomCallBackNoScope 
+            (fun rcall (res,mlst) o -> 
+                match o with 
+                  | :? CodeMemberMethod as meth when meth.GetType() = (typeof<CodeMemberMethod>) -> 
+                      // we have found another method
+                      (incMethodOverload meth res, 
+                       ( meth, 
+                         getMethodOverload res meth,
+                         getTypeRefSimple meth.PrivateImplementationType
+                       )::mlst)
+                  | :? CodeTypeMemberCollection -> 
+                       // recursively walk through member collection
+                       rcall (res,mlst) o
+                  | _ -> (res,mlst))
+            (Map.empty, [])
+      getMethodOverload m, a
+      
+    //---------------------------------------------------------------------------------------------
+    // Fields, properties, constructors, methods
+    
+    /// fields 
+    let generateField (c:CodeMemberField) =    
+      id
+      +> generateCustomAttrDecls c.CustomAttributes
+      +> if ((c.Attributes &&& MemberAttributes.ScopeMask) = MemberAttributes.Static) then
+            id
+            ++ "[<Microsoft.FSharp.Core.DefaultValueAttribute(false)>]"
+            ++ "static val mutable private " -- c.Name -- ":" +> generateTypeRef c.Type
+            //++ (match c.InitExpression with
+                 
+         elif ((c.Attributes &&& MemberAttributes.ScopeMask) = MemberAttributes.Const) then
+            id
+            ++ "static member " -- c.Name -- " = " +> generateExpression c.InitExpression // should have initial value!
+         else
+             id ++ "[<Microsoft.FSharp.Core.DefaultValueAttribute(false)>]"
+                ++ "val mutable " -- c.Name -- ":" +> generateTypeRef c.Type
+    
+    /// Abstract property in the interface 
+    let generateInterfaceMemberProperty (c:CodeMemberProperty) =    
+      id 
+      ++ "abstract " -- c.Name -- " : " 
+      +> (if c.Parameters.Count  > 0 then col sepStar c.Parameters generateAbstractParamDecl -- " -> " else id) 
+      +> generateTypeRef c.Type -- " with " -- (if c.HasGet && not c.HasSet then "get" elif c.HasGet && c.HasSet then "get,set" else "set")
+
+    // REVIEW: this is not correct, it should follow same abstract/default/override logic
+    // as methods. Unfortunately it isn't possible to declare "abstract" property with "default" implementation
+    let generateClassProperty (typ:MemberGenerateType)  (p:CodeMemberProperty) =    
+    
+      (if typ = MemberGenerateType.InsideStruct ||
+          p.Attributes &&& MemberAttributes.ScopeMask = MemberAttributes.Override ||
+          p.Attributes &&& MemberAttributes.ScopeMask = MemberAttributes.Static 
+       then id
+       else (id 
+             ++ ""
+             +> generateInterfaceMemberProperty p))
+      +> generateCustomAttrDecls p.CustomAttributes
+      ++ if typ = MemberGenerateType.InsideStruct then "member this."
+         elif (p.Attributes &&& MemberAttributes.ScopeMask = MemberAttributes.Override) then "override  this." 
+         elif (p.Attributes &&& MemberAttributes.ScopeMask = MemberAttributes.Static) then "static member " 
+         else "default this."
+      -- p.Name  
+
+      +> if (not p.HasGet) then id else 
+         incIndent
+         ++ "with get("
+         +> col sepArgs p.Parameters generateParamDecl
+         -- ") : " +> generateTypeRef p.Type -- " =" 
+         +> generateStatementBlock (Some p.Type) p.GetStatements 
+         +> decIndent
+      +> if (not p.HasSet) then id else 
+         incIndent
+         ++ (if p.HasGet then "and" else "with") -- " set(" 
+         +> col sepNone p.Parameters (fun p -> (generateParamDecl p) -- ", ")
+         -- "value:" +> generateTypeRef p.Type 
+         -- ") : unit =" 
+         +> generateStatementBlock None p.SetStatements 
+         +> decIndent
+    
+    // The argument 'c' can be null when generating default ctor 
+    // (which is not generated by the compiler as in C#)
+    let generateConstructor (c:CodeConstructor) =    
+      // Find all (non-static) fields
+      withCtxt (fun ctx -> 
+          let fields = 
+            ctx.CurrentType.Members
+              |> codeDomFlatFilter (fun o -> 
+                   match o with 
+                     | :? CodeMemberField as fld -> 
+                       let keep = 
+                         (fld.Attributes &&& MemberAttributes.ScopeMask <> MemberAttributes.Static) &&
+                         (fld.Attributes &&& MemberAttributes.ScopeMask <> MemberAttributes.Const)  &&
+                         (match fld.InitExpression with null -> false | _ -> true)
+
+                       (keep, false) 
+                     | _ -> 
+                       (false, false) )
+              |> List.map ( fun f -> f :?> CodeMemberField )
+          id
+          +> (if c <> null then generateCustomAttrDecls c.CustomAttributes else id)
+          ++ "new(" 
+          +> if (c <> null) then (col sepArgs c.Parameters generateParamDecl) else id
+          -- ") as this ="
+          +> incIndent
+          ++ "{"
+          +> incIndent
+          // Calling base constructor?
+          +> if (c = null || c.BaseConstructorArgs = null || c.BaseConstructorArgs.Count = 0) then id else
+                 let (b, i) = ctx.BaseTypes
+                 match b with 
+                   | None -> failwith "Calling constructor of nonexisting base?"
+                   | Some t -> 
+                      id 
+                      ++ "inherit " +> generateTypeRef t -- "("
+                      +> col sepArgs c.BaseConstructorArgs generateExpression
+                      --");"; 
+          // Generate events
+          +> decIndent
+          ++ "}"
+          +> if ((c <> null && c.Statements.Count > 0) || not fields.IsEmpty || not ctx.DeclaredEvents.IsEmpty) then
+               id
+               -- " then"
+               +> incIndent
+               +> incIndent
+               // Initialize events
+               +> colT sepNone ctx.DeclaredEvents ( fun e -> 
+                           id 
+                           ++ "let t_event_" -- e.Name -- " = new DelegateEvent<" +> generateTypeRef e.Type -- ">();"
+                           ++ "this._event_" -- e.Name -- " <- t_event_" -- e.Name -- ".Publish;"
+                           ++ "this._invoke_" -- e.Name -- " <- t_event_" -- e.Name -- ".Trigger;" ) 
+               // Initialize fields
+               +> colT sepNone fields (fun fld -> 
+                        id ++ "this." -- fld.Name -- " <- " +> generateExpression fld.InitExpression-- ";" )
+               // Run other initialization code
+               +> (if c <> null && c.Statements.Count > 0 then 
+                     id
+                     ++ "begin"
+                     +> generateStatementBlock (None) c.Statements 
+                     ++ "end"
+                   else 
+                      id)
+               +> decIndent
+               +> decIndent
+             else 
+               id
+          +> decIndent)
+
+    /// Abstract method in the interface
+    let generateInterfaceMemberMethod (c:CodeMemberMethod, overloadId:int) =
+      let custAttrs = (c.CustomAttributes |> Seq.cast |> Seq.toList)
+
+      let tyargs, genTyArgs = processTypeArgs c.TypeParameters       
+      usingTyParams tyargs 
+        (id
+        +> col sepNone c.Comments generateStatement
+        +> generateCustomAttrDeclsList custAttrs
+        ++ "abstract "
+        -- c.Name 
+        +> genTyArgs
+        -- " : "
+        +> if (c.Parameters.Count > 0) then
+             id +> col sepStar c.Parameters generateAbstractParamDecl
+           else
+             id -- "unit"
+        -- " -> "
+        +> generateTypeRef c.ReturnType)
+      
+    /// By default all CodeDOM generated methods are 'virtual' which means that 
+    /// we have to generate "abstract and default" (unless we're in struct or
+    /// we're implementing an interface, or the method is overriden)
+    /// (NOTE: the same logic isn't properly implemented for properties)
+    let generateMethod (typ:MemberGenerateType) (c:CodeMemberMethod) genAttrFunc =    
+      
+      let prefx, mnm =
+        if (typ = MemberGenerateType.InsideInterface) then
+          id, "member this."
+        elif (typ = MemberGenerateType.InsideStruct) then
+          id, "member this."
+        elif (c.Attributes &&& MemberAttributes.ScopeMask = MemberAttributes.Static) then 
+          id, "static member "
+        elif (c :? CodeEntryPointMethod) then
+          id, "static member "
+        elif (c.Attributes &&& MemberAttributes.ScopeMask = MemberAttributes.Abstract) then 
+          (id +> generateInterfaceMemberMethod (c, -1)),
+          ""
+        elif (c.Attributes &&& MemberAttributes.ScopeMask = MemberAttributes.Override) then 
+          id, "override this." 
+        else
+          (id +> generateInterfaceMemberMethod (c, -1)),
+          "default this."
+
+      //REVIEW: This is mutating the CodeMemberMethod which is a little questionable
+      if c.Name = "" then c.Name <- freshName ()
+      if (mnm = "") then prefx else
+      let tyargs, genTyArgs = processTypeArgs c.TypeParameters       
+      usingTyParams tyargs 
+        (prefx
+        +> genAttrFunc
+        ++ mnm -- c.Name +> genTyArgs -- " "
+        -- " (" +> col sepArgs c.Parameters generateParamDecl -- ")"
+        -- " ="
+        
+        // We need to create mutable copy of all arguments except for "byref" arguments which are mutable
+        +> incIndent
+        +> col sepNone c.Parameters (fun (c:CodeParameterDeclarationExpression) ->  
+             if (c.Direction <> FieldDirection.In) then id else
+               id ++ "let mutable " -- c.Name -- " = " -- c.Name ) 
+        +> decIndent     
+        +> generateStatementBlock (Some c.ReturnType) c.Statements)
+
+    /// Generates method code
+    /// Generates comments and than calls 'generatMethod'
+    let generateClassMemberMethod (typ:MemberGenerateType) (c:CodeMemberMethod, overloadId:int) =
+      let custAttrs = (c.CustomAttributes |> Seq.cast |> Seq.toList)
+      id
+      +> col sepNone c.Comments generateStatement
+      +> generateMethod typ c (generateCustomAttrDeclsList custAttrs)
+    
+    let generateEntryPointMethod (typ:MemberGenerateType) (c:CodeEntryPointMethod)  = 
+      id
+      +> (fun ctx -> {ctx with MainMethodForCurrentNamespace = Some (c, ctx.CurrentType)})
+      +> (generateClassMemberMethod typ ((c :> CodeMemberMethod), -1))
+    
+    let generateEvent (c:CodeMemberEvent) = 
+      id
+      +> generateCustomAttrDecls c.CustomAttributes
+      ++ "[<CLIEvent>]"
+      ++ "member this." -- c.Name -- " ="
+      +> incIndent
+      ++ "this._event_" -- c.Name
+      +> decIndent
+    
+    let generateEventField (c:CodeMemberEvent) =
+      id
+      +> (fun ctx -> { ctx with DeclaredEvents = c::ctx.DeclaredEvents })
+      ++ "[<Microsoft.FSharp.Core.DefaultValueAttribute(false)>]"
+      ++ "val mutable _event_" -- c.Name -- " : IDelegateEvent<" +> generateTypeRef c.Type -- ">;"
+      ++ "[<Microsoft.FSharp.Core.DefaultValueAttribute(false)>]"
+      ++ "val mutable _invoke_" -- c.Name -- " : obj[] -> unit;";
+    
+
+    let generateCodeSnippetMember (c:CodeSnippetTypeMember) =
+      
+      // Remove additional spaces to make sure that the code aligns with the rest
+      // CONSIDER: what to do with '\t' ?
+      let countSpaces (s:string) =
+        let rec countSpacesAux (s:string) i n = 
+          if i >= s.Length then n
+          elif s.[i] = ' ' then countSpacesAux s (i + 1) (n + 1)
+          else n
+        countSpacesAux s 0 0
+              
+      let lines = c.Text.Split([| '\n'; '\r' |], StringSplitOptions.RemoveEmptyEntries)
+      if lines.Length > 0 then 
+          let spaces = Array.foldBack (countSpaces >> min) lines Int32.MaxValue
+          let lines = lines |> Array.map (fun s -> s.[spaces..])
+          
+          // ASP.NET doesn�t use any comments or custom attributes, 
+          // but I assume this would be the right order
+          id 
+          +> col sepNone c.Comments generateStatement
+          +> generateLinePragma c.LinePragma
+          +> generateCustomAttrDecls c.CustomAttributes
+          +> colT sepNone lines ((++) id)
+      else 
+          id
+
+            
+    //---------------------------------------------------------------------------------------------
+    // Interfaces and classes and other types
+
+    let generateInterfaceImplementation (ifcnfo:KeyValuePair<_, _>) =
+      let name = ifcnfo.Key
+      let membs = ifcnfo.Value
+      id 
+      ++ "interface " -- name -- " with"
+      +> incIndent
+      +> colT sepNln membs (generateClassMemberMethod MemberGenerateType.InsideInterface)
+      +> decIndent
+      ++ "end"
+
+    let generateClassMember typ (c:CodeTypeMember) =
+      match c with 
+      | :? CodeTypeDeclaration -> id 
+      | :? CodeMemberField 
+      | :? CodeMemberEvent 
+      | :? CodeConstructor 
+      | :? CodeMemberProperty ->
+            id
+            +> col sepNone c.Comments generateStatement
+            +> match c with 
+                 | :? CodeMemberField as cm -> generateField cm
+                 | :? CodeMemberEvent as cm -> generateEvent cm
+                 | :? CodeConstructor as cm -> generateConstructor cm
+                 | :? CodeMemberProperty as cm -> generateClassProperty typ cm
+                 | _ -> failwithf "unimplemented CodeTypeMember '%A'" c
+      | _ ->
+            id ++ "(* Member of type '" +> str (c.GetType().Name) --  "' is not supported by the CodeDOM provider and was omitted *)" 
+
+      
+    let generateClassOrStruct structOrCls (scope:string list) (c:CodeTypeDeclaration) ctx =
+      // affects members
+      let typ = 
+        if (structOrCls = "struct") then MemberGenerateType.InsideStruct 
+          else MemberGenerateType.InsideClass
+        
+      // Find all constructors
+      let ctors = c |> codeDomFlatFilter (fun o -> 
+            match o with 
+              | :? CodeTypeDeclaration as dc -> (false, dc = c)
+              | :? CodeConstructor as c -> (true, true)
+              | _ -> (false, true); ) 
+      let anyCtor = ctors.Length > 0;
+      
+      // Find base classes
+      let (baseClass, interfaces) = resolveHierarchy c ctx
+      
+      // Find fields and their types
+      let (ft, pt, flds, props, meths, events) = 
+          c.Members |> codeDomCallBackNoScope (fun rcall ((ft, pt,flds, props, meths, events) as acc) o -> 
+              match o with 
+                | :? CodeMemberField as fld -> (Map.add fld.Name fld.Type ft, pt, Map.add fld.Name  fld flds, props, meths, events)
+                | :? CodeMemberProperty as prop -> (ft, Map.add prop.Name prop.Type pt, flds, Map.add prop.Name prop props, meths, events)
+                | :? CodeMemberMethod as meth -> (ft, pt, flds, props, Map.add meth.Name meth meths, events)
+                | :? CodeMemberEvent as ev -> (ft, pt, flds, props, meths, Map.add ev.Name ev events)
+                | :? CodeTypeMemberCollection -> rcall acc o
+                | _ -> acc; ) (Map.empty, Map.empty, Map.empty, Map.empty, Map.empty, Map.empty)
+                          
+      // Find all overloads of the method, so we can produce [<OverloadID>]
+      let (getOverload, allmeths) = getMethodOverloads(c.Members)
+      
+      // Get tripple with method info, overload id and name of the interface where
+      // it belongs (if it's "PrivateImplementationType")
+      let allmeths = allmeths |> List.map ( fun (cm, ovIdx, intrfcName) -> 
+        match getOverload cm with | 1 -> (cm, -1, intrfcName) | _ -> (cm, ovIdx, intrfcName) )
+        
+      // Split between methods of the class
+      // and methods that implemnet some interface
+      let ifcTable = new Dictionary<string, ResizeArray<CodeMemberMethod*int>>()
+      let allmeths = 
+        allmeths |> mapFilter (fun (m, idx, ifn) -> 
+          match m.PrivateImplementationType, m.ImplementationTypes.Count with
+          | null, 0 -> Some((m,idx))
+          | _ , 0 -> 
+            let b,v = ifcTable.TryGetValue(ifn)
+            let v = 
+              if (not b) then 
+                let rs = new ResizeArray<CodeMemberMethod*int>()
+                ifcTable.Add(ifn, rs)
+                rs 
+              else v
+            v.Add((m,idx))
+            None
+          | null, n -> 
+            for implementedInterface in m.ImplementationTypes do
+                let b,v = ifcTable.TryGetValue(getTypeRefSimple implementedInterface)
+                let v =
+                  if (not b) then
+                    let rs = new ResizeArray<CodeMemberMethod*int>()
+                    ifcTable.Add(getTypeRefSimple implementedInterface, rs)
+                    rs
+                  else v
+                v.Add((m, idx))
+            Some((m,idx))
+          | _, _ -> failwith "CodeMethodMember must not have both ImplementationTypes and PrivateImplementationType set.")
+
+
+      // NOTE: we ignore class visibility and also IsPartial property
+      // Declare type arguments and generate class 
+      let tyargs, genTyArgs = processTypeArgs c.TypeParameters       
+      (usingTyParams tyargs 
+        (id  
+        +> (fun ctx -> { ctx with BaseTypes = (baseClass, interfaces); FieldTypes = ft; PropertyTypes = pt; AllFields=flds; AllProps=props; AllMeths=meths; AllEvents=events  })   
+        ++ ""    
+        ++ (if c.IsPartial then "(* partial *)" else "")    
+        +> col sepNone scope (fun s -> id -- s -- "_") -- c.Name 
+        +> genTyArgs
+        -- " = " -- structOrCls
+        +> incIndent
+        +> match (baseClass) with
+             | Some (bc) -> id ++ "inherit " +> generateTypeRef bc -- " "
+             | _ -> id
+        
+        // Filter and generate members
+        +> colFilterT<CodeMemberEvent>     sepNln c.Members generateEventField
+        +> colFilter<CodeMemberField>     sepNln c.Members (generateClassMember typ)
+        +> colFilter<CodeTypeConstructor> sepNln c.Members (generateClassMember typ)
+        +> colFilter<CodeMemberEvent>     sepNln c.Members (generateClassMember typ)
+        
+        // Generate default empty constructor for classes 
+        // without constructors (but not for structs!)
+        +> if (anyCtor) then
+             colFilter<CodeConstructor> sepNln c.Members (generateClassMember typ)
+           elif (structOrCls = "class" && not c.IsPartial) then
+             generateConstructor null
+           else
+            id 
+            
+        // User code
+        +> colFilterT<CodeSnippetTypeMember> sepNln c.Members generateCodeSnippetMember
+        // Properties, methods, interface implementations
+        +> colFilter<CodeMemberProperty> sepNln c.Members (generateClassMember typ)
+        +> colT sepNln allmeths (generateClassMemberMethod typ)
+        +> colT sepNln ifcTable generateInterfaceImplementation
+        +> colFilterT<CodeEntryPointMethod> sepNln c.Members (generateEntryPointMethod typ)
+        +> decIndent
+        ++ "end")) ctx
+        
+    let generateInterface (scope:string list) (c:CodeTypeDeclaration) =
+      // handle overloads
+      let (getOverload, allmeths) = getMethodOverloads c.Members 
+      let allmeths = allmeths |> List.map ( fun (cm, ovIdx, _) -> 
+        match getOverload cm with | 1 -> (cm, -1) | _ -> (cm, ovIdx) )
+
+      let castToProp (a:CodeTypeMember) = (a :?> CodeMemberProperty)        
+
+      // NOTE: visibility is ignored
+      let tyargs, genTyArgs = processTypeArgs c.TypeParameters       
+      usingTyParams tyargs 
+        (id  
+        ++ ""    
+        +> col sepNone scope (fun s -> id -- s -- "_") -- c.Name 
+        +> genTyArgs
+        -- " = interface" 
+        +> incIndent
+        +> col sepNln c.BaseTypes (fun (cr:CodeTypeReference) -> id ++ "inherit " +> generateTypeRef cr)
+        +> colFilter<CodeMemberProperty> sepNln c.Members (castToProp >> generateInterfaceMemberProperty)
+        ++ ""
+        +> colT sepNln allmeths generateInterfaceMemberMethod
+        +> decIndent
+        ++ "end")
+      
+    let generateDelegate (scope:string list) (c:CodeTypeDelegate) =
+      let tyargs, genTyArgs = processTypeArgs c.TypeParameters       
+      usingTyParams tyargs 
+        (id
+        ++ ""
+        +> col sepNone scope (fun s -> id -- s -- "_") -- c.Name 
+        +> genTyArgs
+        -- " = delegate of "
+        +> if (c.Parameters.Count = 0) then
+             id -- "unit"
+           else
+             col sepStar c.Parameters (fun (p:CodeParameterDeclarationExpression) ->
+               id +> generateTypeRef p.Type )
+        -- " -> "
+        +> match c.ReturnType with 
+             | null -> id -- "unit"
+             | rt -> generateTypeRef rt)
+      
+    let generateEnumField (index:int) (c:CodeMemberField) =    
+      id 
+      ++ "| " -- c.Name -- " = " 
+      +> match c.InitExpression with
+           | null -> str index
+           | :? CodePrimitiveExpression as p -> generatePrimitiveExpr None p
+           | _ -> failwith "Invalid enum !";
+                     
+    let generateEnum (scope:string list) (c:CodeTypeDeclaration) =
+      let counter = createCounter()
+      id     
+      ++ "" 
+      +> col sepNone scope (fun s -> id -- s -- "_") -- c.Name 
+      -- " =" 
+      +> incIndent
+      +> col sepNone c.Members (fun c -> generateEnumField (counter()) c)
+      +> decIndent
+    
+    let generateTypeDecl index (scope:string list, c:CodeTypeDeclaration) =      
+      id
+      ++ if (index = 0) then "type" else "and"
+      +> incIndent
+      +> col sepNone c.Comments generateStatement 
+      +> generateCustomAttrDeclsForType (c.CustomAttributes |> Seq.cast |> Seq.toList) c.TypeAttributes
+      +> (fun ctx -> { ctx with CurrentType = c })
+      +> match c with 
+           | :? CodeTypeDelegate as cd -> generateDelegate scope cd
+           | c when c.IsClass -> generateClassOrStruct "class" scope c
+           | c when c.IsInterface -> generateInterface scope c
+           | c when c.IsEnum -> generateEnum scope c
+           | c when c.IsStruct -> generateClassOrStruct "struct" scope c
+           | _ -> 
+            // NOTE: I believe this is full match..
+            id ++ "(* Type '" -- (c.Name) --  "' is not supported by the CodeDOM provider and was omitted. *)"
+      +> decIndent
+      +> (fun ctx -> { ctx with DeclaredEvents = []; CurrentType = null; BaseTypes = (None, []); FieldTypes = Map.empty; PropertyTypes = Map.empty; })
+      
+    /// Generates a main method.
+    let generateMainMethod (c:CodeEntryPointMethod, t:CodeTypeDeclaration) (ns:CodeNamespace) =
+      let retType = getTypeRefSimple c.ReturnType 
+      let custAttrs = 
+        CodeAttributeDeclaration("EntryPoint", [||]) :: (c.CustomAttributes |> Seq.cast |> Seq.toList)
+      
+      if ((c.Parameters.Count = 0) || (c.Parameters.Count = 1 && (getTypeRefSimple c.Parameters.[0].Type) = "string[]" ))
+         && (retType = "int" || retType = "unit")
+      then
+        id
+        ++ "[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]"
+        ++ "module __EntryPoint ="
+        +> incIndent
+        +>   (generateCustomAttrDeclsList custAttrs)  
+        ++   "let Main (args:string[]) ="
+        +> incIndent
+        // REVIEW: Do we need to pass this through the "rename" table?  Could use '(generateTypeRef t)', but we don't have a CodeTypeReference
+        ++ t.Name -- "." -- (c.Name) 
+        +> if c.Parameters.Count = 1 
+           then id -- "(args)"
+           else id -- "()"
+        // F# only supports main methods returning int.  If we're asked to emit one that returns unit, just return 1.
+        +> if retType = "unit" then id ++ "0" else id
+        +> decIndent 
+        +> decIndent
+      else
+        id ++ "(* Could not generate entry point for method '" -- (c.Name) -- "'. *)"
+      
+    //---------------------------------------------------------------------------------------------
+    // Namespaces and compilation units
+    
+    /// Returns CodeNamespace, list of classes with scope (which includes class names 
+    /// of containing classes and sequence of class renames)
+    let preprocessNamespace (c:CodeNamespace) =
+        
+        // Extract flat class structure
+        let flatClasses = 
+            c 
+            |> codeDomCallbackWithScope (fun rcall scope acc o -> 
+                  match o with 
+                    | :? CodeTypeDeclaration as dc -> 
+                        //sprintf "preprocessNamespace: rcall for type c.Name = %s\n" dc.Name |> System.Windows.Forms.MessageBox.Show |> ignore
+                        rcall (dc.Name::scope) ((scope, dc)::acc) (box dc.Members)
+                    | _ -> rcall scope acc o) [] [];
+        let flatClasses = flatClasses |> List.rev
+        
+        // Get all renamed classes - this changes file structure, but at least it works
+        let addNameWithScope n (scope:string list) acc = 
+            let scn = String.Join("_",Array.ofList scope) + "_" + n
+            let (_, res) = 
+                scope |> List.fold ( fun (prefix,st) e ->
+                  let npref = e + prefix
+                  let nmap = Map.add (npref + n) scn st 
+                  ("." + npref, nmap) ) (".", Map.add n scn acc)
+            res                
+
+        //sprintf "c.Name = %s, #flatClasses = %d\n" c.Name flatClasses.Length |> System.Windows.Forms.MessageBox.Show |> ignore
+
+        let renames = 
+            flatClasses 
+            |> List.fold ( fun acc ((scope:string list), ty) ->
+                  if (scope.Length = 0) then acc 
+                  else addNameWithScope ty.Name scope acc ) Map.empty
+
+        //if (renames |> Seq.length) > 0 then
+        //    sprintf "#renames = %d\n" (renames |> Seq.length) |> System.Windows.Forms.MessageBox.Show |> ignore
+
+        (c, flatClasses, renames |> Map.toSeq);        
+        
+    let generateImport (c:CodeNamespaceImport) = 
+      id  ++ "open " -- c.Namespace
+      
+    /// Generates namespace code - takes output from 'preprocessNamespace'
+    let generateNamespaceInternal ((c:CodeNamespace, flatClasses, _), containing) =
+      let counter = createCounter()
+      let ifcSet = 
+        flatClasses 
+          |> List.fold (fun st (scope, (c:CodeTypeDeclaration)) -> 
+                if (c.IsInterface) then 
+                  let st = Set.add c.Name st 
+                  Set.add (String.Join(".",Array.ofList(scope@[c.Name]))) st
+                else st) Set.empty
+      
+      id
+      +> ( fun ctx -> { ctx with CurrentNamespace = c.Name; DeclaredInterfaces = ifcSet } )
+      +> col sepNone c.Comments generateStatement
+      +> ((if String.IsNullOrEmpty c.Name then id ++ "namespace global" else id ++ "namespace " -! c.Name) +> incIndent) 
+      ++ "// Generated by F# CodeDom"
+      ++ "#nowarn \"49\" // uppercase argument names"
+      ++ "#nowarn \"67\" // this type test or downcast will always hold"
+      ++ "#nowarn \"66\" // this upcast is unnecessary - the types are identical"
+      ++ "#nowarn \"58\" // possible incorrect indentation.." // (when using CodeSnippets ie. in ASP.NET)
+      ++ "#nowarn \"57\" // do not use create_DelegateEvent"
+      ++ "#nowarn \"51\" // address-of operator can occur in the code"
+      ++ "#nowarn \"1183\" // unused 'this' reference"
+      +> colT sepNone containing (fun s -> id ++ "open " -- s)
+      +> col sepNone c.Imports generateImport
+      ++ ""              
+      ++ "exception ReturnException" +> uniqid -- " of obj"
+      ++ "exception ReturnNoneException" +> uniqid 
+
+      ++ "[<AutoOpen>]"
+      ++ "module FuncConvertFinalOverload" +> uniqid -- " ="
+      ++ "  // This extension member adds to the FuncConvert type and is the last resort member in the method overloading rules. "
+      ++ "  type global.Microsoft.FSharp.Core.FuncConvert with"
+      ++ "      /// A utility function to convert function values from tupled to curried form"
+      ++ "      static member FuncFromTupled (f:'T -> 'Res) = f"
+      ++ ""
+      +> colT sepNln flatClasses (fun c -> generateTypeDecl (counter()) c)
+      +> withCtxt (fun ctx -> match ctx.MainMethodForCurrentNamespace with None -> id | Some mainMethod -> (generateMainMethod mainMethod c))
+      +> if (c.Name<>null && c.Name.Length>0) then decIndent else id
+      +> ( fun ctx -> { ctx with CurrentNamespace = ""; MainMethodForCurrentNamespace = None } )
+    
+    
+    /// Generate code for namespace without compilation unit  
+    let generateNamespace (c:CodeNamespace) = 
+        generateNamespaceInternal ((preprocessNamespace c), [])
+        
+    /// Generate code for type declaration (not included in namespace)                 
+    let generateTypeDeclOnly (c:CodeTypeDeclaration) =
+        let ns = new CodeNamespace()
+        ns.Types.Add(c) |> ignore
+        let ((_, flatClasses, _), containing) = (preprocessNamespace ns, [])
+        let counter = createCounter()
+        id
+        ++ ""              
+        ++ "exception ReturnException" +> uniqid -- " of obj"
+        ++ "exception ReturnNoneException" +> uniqid 
+        ++ ""
+        +> colT sepNln flatClasses (fun c -> generateTypeDecl (counter()) c)
+
+    /// Generate code for compile unit (file)                
+    let generateCompileUnit (c:CodeCompileUnit) (preprocHacks:CodeCompileUnit -> unit) =
+      
+      // Generate code for the compilation unit
+      preprocHacks c;
+      match c with 
+        | :? CodeSnippetCompileUnit as cs -> 
+          id +> generateLinePragma cs.LinePragma ++ cs.Value
+        | _ -> 
+          let preprocNs = c.Namespaces |> Seq.cast |> Seq.map preprocessNamespace
+          let renames = preprocNs |> Seq.collect (fun (_, _, renames) -> renames) 
+          let getContainingNamespaces (c:CodeNamespace) nslist =
+            nslist |> List.filter ( fun (n:string) -> c.Name.StartsWith(n) )
+          let (namespacesWithPrev, _) = 
+            preprocNs |> Seq.fold (fun (res, tmpNames) (c, cls, renames) ->
+              (((c, cls, renames), getContainingNamespaces c tmpNames)::res, c.Name::tmpNames) ) ([], [])
+          let namespacesWithPrev = namespacesWithPrev |> Seq.toList |> List.rev
+
+          // renames |> Seq.map (fun (s, t) -> sprintf "%s --> %s\n" s t) |> Seq.toList |> String.concat "\n" |> System.Windows.Forms.MessageBox.Show |> ignore
+          
+          (fun ctx -> { ctx with TypeRenames = Map.ofSeq renames; } )        
+          ++ "//------------------------------------------------------------------------------"
+          ++ "// <autogenerated>"
+          ++ "//     This code was generated by a tool."
+          ++ "//     Runtime Version: " +> (str System.Environment.Version)
+          ++ "//"
+          ++ "//     Changes to this file may cause incorrect behavior and will be lost if "
+          ++ "//     the code is regenerated."
+          ++ "// </autogenerated>"
+          ++ "//------------------------------------------------------------------------------"
+          ++ ""
+          ++ "namespace global"
+          ++ ""
+          +> colT sepNln namespacesWithPrev generateNamespaceInternal;
+
+    //---------------------------------------------------------------------------------------------
diff --git a/src/FSharp.PowerPack.Build.Tasks/FSLex.Build.fs b/src/FSharp.PowerPack.Build.Tasks/FSLex.Build.fs
new file mode 100755
index 0000000..292957a
--- /dev/null
+++ b/src/FSharp.PowerPack.Build.Tasks/FSLex.Build.fs
@@ -0,0 +1,111 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Build
+
+open System
+open Microsoft.Build.Framework
+open Microsoft.Build.Utilities
+open Internal.Utilities
+
+(**************************************
+MSBuild task for fslex
+
+options:
+        -o <string>: Name the output file.
+        --codepage <int>: Assume input lexer specification file is encoded with the given codepage.
+        --unicode: Produce a lexer for use with 16-bit unicode characters.
+        --help: display this list of options
+        -help: display this list of options
+**************************************)
+
+type FsLex() = 
+    inherit ToolTask()
+
+    let mutable inputFile  : string = null
+    let mutable outputFile : string = null
+    
+    let mutable codePage   : string = null
+    let mutable unicode   = false
+    let mutable otherFlags   = ""
+
+    let mutable toolPath : string = 
+        match FSharpEnvironment.BinFolderOfFSharpPowerPack with
+        | Some s -> s
+        | None -> ""
+#if FX_ATLEAST_35   
+#else 
+    let mutable toolExe : string = "fslex.exe"
+#endif 
+
+    // [<Required>]
+    member this.InputFile
+        with get ()  = inputFile
+        and  set (x) = inputFile <- x
+    
+    [<Output>]
+    member this.OutputFile
+        with get ()  = outputFile
+        and  set (x) = outputFile <- x
+    
+    // --codepage <int>: Assume input lexer specification file is encoded with the given codepage.
+    member this.CodePage
+        with get ()  = codePage
+        and  set (x) = codePage <- x
+    
+    // --unicode: Produce a lexer for use with 16-bit unicode characters.
+    member this.Unicode
+        with get ()  = unicode
+        and  set (x) = unicode <- x
+
+    member this.OtherFlags
+        with get() = otherFlags
+        and set(s) = otherFlags <- s
+
+    // For targeting other versions of fslex.exe, such as "\LKG\" or "\Prototype\"
+    member this.ToolPath
+        with get ()  = toolPath
+        and  set (s) = toolPath <- s
+        
+#if FX_ATLEAST_35   
+#else 
+    // Name of the .exe to call
+    member this.ToolExe
+        with get ()  = toolExe
+        and  set (s) = toolExe <- s        
+#endif
+
+    // ToolTask methods
+    override this.ToolName = "fslex.exe"
+    
+    override this.GenerateFullPathToTool() = 
+        System.IO.Path.Combine(toolPath, this.ToolExe)
+        
+    override this.GenerateCommandLineCommands() =
+    
+        let builder = new CommandLineBuilder()
+        
+        // CodePage
+        builder.AppendSwitchIfNotNull("--codepage ", codePage)
+        
+        // Unicode
+        if unicode then builder.AppendSwitch("--unicode")
+
+        // OutputFile
+        builder.AppendSwitchIfNotNull("-o ", outputFile)
+
+        // OtherFlags - must be second-to-last
+        builder.AppendSwitchUnquotedIfNotNull("", otherFlags)
+
+        builder.AppendSwitchIfNotNull(" ", inputFile)
+        
+        let args = builder.ToString()
+
+        // when doing simple unit tests using API, no BuildEnginer/Logger is attached
+        if this.BuildEngine <> null then
+            let eventArgs = { new CustomBuildEventArgs(message=args,helpKeyword="",senderName="") with member x.Equals(y) = false }
+            this.BuildEngine.LogCustomEvent(eventArgs)
+        args
+    
+    // Expose this to internal components (for unit testing)
+    member internal this.InternalGenerateCommandLineCommands() =
+        this.GenerateCommandLineCommands()
diff --git a/src/FSharp.PowerPack.Build.Tasks/FSLex.Build.fsi b/src/FSharp.PowerPack.Build.Tasks/FSLex.Build.fsi
new file mode 100755
index 0000000..9e0d8c9
--- /dev/null
+++ b/src/FSharp.PowerPack.Build.Tasks/FSLex.Build.fsi
@@ -0,0 +1,26 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Build
+
+type FsLex =
+    inherit Microsoft.Build.Utilities.ToolTask
+
+    new : unit -> FsLex
+    
+    override GenerateCommandLineCommands : unit -> System.String
+    override GenerateFullPathToTool : unit -> System.String
+    override ToolName : System.String
+    
+    member internal InternalGenerateCommandLineCommands : unit -> System.String
+    
+    member InputFile  : string with set
+    [<Microsoft.Build.Framework.Output>]
+    member OutputFile : string with set
+    member CodePage   : string with set
+    member OtherFlags : string with set
+    member Unicode    : bool   with set
+    member ToolPath   : string with set
+#if FX_ATLEAST_35   
+#else 
+    member ToolExe    : string with set    
+#endif
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fs b/src/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fs
new file mode 100755
index 0000000..2709932
--- /dev/null
+++ b/src/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fs
@@ -0,0 +1,124 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Build
+
+open System
+open Microsoft.Build.Framework
+open Microsoft.Build.Utilities
+open Internal.Utilities
+
+(**************************************
+MSBuild task for fsyacc
+**************************************)
+
+type FsYacc() = 
+    inherit ToolTask()
+
+    let mutable inputFile  : string = null
+    let mutable outputFile : string = null
+    
+    let mutable codePage   : string = null
+    let mutable otherFlags : string = null
+    let mutable mlCompat   = false
+    
+    let mutable _open  : string = null
+    let mutable _module  : string = null
+
+    let mutable toolPath : string = 
+        match FSharpEnvironment.BinFolderOfFSharpPowerPack with
+        | Some s -> s
+        | None -> ""
+#if FX_ATLEAST_35
+#else
+    let mutable toolExe : string = "fsyacc.exe"
+#endif
+
+    // [<Required>]
+    member this.InputFile
+        with get ()  = inputFile
+        and  set (x) = inputFile <- x
+    
+    [<Microsoft.Build.Framework.Output>]
+    member this.OutputFile
+        with get ()  = outputFile
+        and  set (x) = outputFile <- x
+    
+    member this.OtherFlags
+        with get() = otherFlags
+        and set(s) = otherFlags <- s
+
+    // --codepage <int>: Assume input lexer specification file is encoded with the given codepage.
+    member this.CodePage
+        with get ()  = codePage
+        and  set (x) = codePage <- x
+    
+    // --ml-compatibility: Support the use of the global state from the 'Parsing' module in MLLib.
+    member this.MLCompatibility
+        with get ()  = mlCompat
+        and  set (x) = mlCompat <- x
+        
+    // --open
+    member this.Open
+        with get ()  = _open
+        and  set (x) = _open <- x       
+
+   // --module
+    member this.Module
+        with get ()  = _module
+        and  set (x) = _module <- x             
+
+    // For targeting other versions of fslex.exe, such as "\LKG\" or "\Prototype\"
+    member this.ToolPath
+        with get ()  = toolPath
+        and  set (s) = toolPath <- s
+        
+#if FX_ATLEAST_35
+#else
+    // Name of the .exe to call
+    member this.ToolExe
+        with get ()  = toolExe
+        and  set (s) = toolExe <- s        
+#endif
+
+    // ToolTask methods
+    override this.ToolName = "fsyacc.exe"
+    
+    override this.GenerateFullPathToTool() = 
+        System.IO.Path.Combine(toolPath, this.ToolExe)
+        
+    override this.GenerateCommandLineCommands() =
+    
+        let builder = new CommandLineBuilder()
+        
+        // CodePage
+        builder.AppendSwitchIfNotNull("--codepage ", codePage)
+        
+        // ML Compatibility
+        if mlCompat then builder.AppendSwitch("--ml-compatibility")
+
+        // Open
+        builder.AppendSwitchIfNotNull("--open ", _open)
+
+        // Module
+        builder.AppendSwitchIfNotNull("--module ", _module)
+
+        // OutputFile
+        builder.AppendSwitchIfNotNull("-o ", outputFile)
+
+        // OtherFlags - must be second-to-last
+        builder.AppendSwitchUnquotedIfNotNull("", otherFlags)
+
+        builder.AppendSwitchIfNotNull(" ", inputFile)
+        
+        let args = builder.ToString()
+
+        // when doing simple unit tests using API, no BuildEnginer/Logger is attached
+        if this.BuildEngine <> null then
+            let eventArgs = { new CustomBuildEventArgs(message=args,helpKeyword="",senderName="") with member x.Equals(y) = false }
+            this.BuildEngine.LogCustomEvent(eventArgs)
+        
+        args
+    
+    // Expose this to internal components (for unit testing)
+    member internal this.InternalGenerateCommandLineCommands() =
+        this.GenerateCommandLineCommands()
diff --git a/src/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fsi b/src/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fsi
new file mode 100755
index 0000000..52c241e
--- /dev/null
+++ b/src/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fsi
@@ -0,0 +1,28 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Build
+
+type FsYacc =
+    inherit Microsoft.Build.Utilities.ToolTask
+
+    new : unit -> FsYacc
+    
+    override GenerateCommandLineCommands : unit -> System.String
+    override GenerateFullPathToTool : unit -> System.String
+    override ToolName : System.String
+    
+    member internal InternalGenerateCommandLineCommands : unit -> System.String
+    
+    member InputFile  : string with set
+    [<Microsoft.Build.Framework.Output>]
+    member OutputFile : string with set
+    member CodePage   : string with set
+    member OtherFlags : string with set
+    member MLCompatibility : bool with set
+    member Open : string with set
+    member Module   : string with set
+    member ToolPath   : string with set
+#if FX_ATLEAST_35
+#else
+    member ToolExe   : string with set    
+#endif
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.Build.Tasks.fsproj b/src/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.Build.Tasks.fsproj
new file mode 100755
index 0000000..7d59257
--- /dev/null
+++ b/src/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.Build.Tasks.fsproj
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{a9566921-4193-4ec8-83fb-f5a0dc257678}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>FSharp.PowerPack.Build.Tasks</AssemblyName>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <DocumentationFile>FSharp.PowerPack.Build.Tasks.xml</DocumentationFile>
+    <NoWarn>$(NoWarn);9;60;35;42;62;86;47;40</NoWarn>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="assemblyinfo.FSharp.PowerPack.Build.Tasks.dll.fs">
+      <Link>assemblyinfo.FSharp.PowerPack.Build.Tasks.dll.fs</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\CompilerLocationUtils.fs">
+      <Link>CompilerLocationUtils.fs</Link>
+    </Compile>
+    <Compile Include="FSLex.Build.fsi" />
+    <Compile Include="FSLex.Build.fs" />
+    <Compile Include="FSYacc.Build.fsi" />
+    <Compile Include="FSYacc.Build.fs" />
+    <CustomCopyLocal Include="FSharp.PowerPack.targets">
+      <TargetFilename>FSharp.PowerPack.targets</TargetFilename>
+    </CustomCopyLocal>
+    <None Include="FSharp.PowerPack.targets" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="Microsoft.Build.Engine" />
+    <Reference Include="Microsoft.Build.Framework" />
+    <Reference Include="Microsoft.Build.Utilities" />
+    <Reference Include="FSharp.Core" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.Build.Tasks.fsproj.vspscc b/src/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.Build.Tasks.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.Build.Tasks.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.targets b/src/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.targets
new file mode 100755
index 0000000..d07d007
--- /dev/null
+++ b/src/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.targets
@@ -0,0 +1,84 @@
+<!--
+***********************************************************************************************
+FSharp.PowerPack.targets
+
+WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
+		  created a backup copy.  Incorrect changes to this file will make it
+		  impossible to load or build your projects from the command-line or the IDE.
+
+PowerPack build rules.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+***********************************************************************************************
+-->
+
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+	<UsingTask TaskName="FsLex" AssemblyFile="FSharp.PowerPack.Build.Tasks.dll"/>
+	<UsingTask TaskName="FsYacc" AssemblyFile="FSharp.PowerPack.Build.Tasks.dll"/>
+	<PropertyGroup>
+		<CompileDependsOn>CallFsLex;CallFsYacc;$(CompileDependsOn)</CompileDependsOn>
+	</PropertyGroup>
+
+	<!-- Build FsLex files. -->
+	<Target
+		Name="CallFsLex"
+		Inputs="@(FsLex)"
+		Outputs="@(FsLex->'$(FsLexOutputFolder)%(Filename).fs')"
+		Condition="'@(FsLex)'!=''">
+
+		<!-- Create the output directory -->
+		<MakeDir Directories="$(FsLexOutputFolder)"/>
+		<!-- Call FsLex -->
+		<FsLex
+			InputFile="%(FsLex.Identity)"
+			OutputFile="$(FsLexOutputFolder)%(FsLex.Filename).fs"
+			ToolPath="$(FsLexToolPath)"
+			ToolExe="$(FsLexToolExe)"
+			OtherFlags="%(FsLex.OtherFlags)"
+			Unicode="$(FsLexUnicode)">
+			<!-- Track outputs for 'Clean' -->
+			<Output TaskParameter="OutputFile" ItemName="FileWrites"/>
+		</FsLex>
+    <!-- Make sure it will get cleaned  -->
+    <CreateItem Include="$(FsLexOutputFolder)%(FsLex.Filename).fs">
+      <Output TaskParameter="Include" ItemName="FileWrites"/>
+    </CreateItem>
+  </Target>
+
+	<!-- Build FsYacc files. -->
+	<Target
+		Name="CallFsYacc"
+		Inputs="@(FsYacc)"
+		Outputs="@(FsYacc->'$(FsYaccOutputFolder)%(Filename).fs')"
+		Condition="'@(FsYacc)'!=''">
+
+		<!-- Create the output directory -->
+		<MakeDir Directories="$(FsYaccOutputFolder)"/>
+		<!-- Call FsYacc -->
+		<FsYacc
+			InputFile="%(FsYacc.Identity)"
+			OutputFile="$(FsYaccOutputFolder)%(FsYacc.Filename).fs"
+			Open="%(FsYacc.Open)"
+			Module="%(FsYacc.Module)"
+			OtherFlags="%(FsYacc.OtherFlags)"
+			ToolPath="$(FsYaccToolPath)"
+			ToolExe="$(FsYaccToolExe)">
+			<!-- Track outputs for 'Clean' -->
+			<Output TaskParameter="OutputFile" ItemName="FileWrites"/>
+    </FsYacc>
+    <!-- Make sure it will get cleaned  -->
+    <CreateItem Include="$(FsYaccOutputFolder)%(FsYacc.Filename).fs">
+      <Output TaskParameter="Include" ItemName="FileWrites"/>
+    </CreateItem>
+  </Target>
+	<ItemGroup>
+       <AvailableItemName Include="FsLex">
+           <Visible>false</Visible>
+       </AvailableItemName>
+       <AvailableItemName Include="FsYacc">
+           <Visible>false</Visible>
+       </AvailableItemName>
+    </ItemGroup>
+</Project>
+
+
diff --git a/src/FSharp.PowerPack.Build.Tasks/assemblyinfo.FSharp.PowerPack.Build.Tasks.dll.fs b/src/FSharp.PowerPack.Build.Tasks/assemblyinfo.FSharp.PowerPack.Build.Tasks.dll.fs
new file mode 100755
index 0000000..dbdbb10
--- /dev/null
+++ b/src/FSharp.PowerPack.Build.Tasks/assemblyinfo.FSharp.PowerPack.Build.Tasks.dll.fs
@@ -0,0 +1,7 @@
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("FSharp.PowerPack.Build.Tasks.dll")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("FSharp.PowerPack.Build.Tasks.dll")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
diff --git a/src/FSharp.PowerPack.Compatibility/Compat.Array.fs b/src/FSharp.PowerPack.Compatibility/Compat.Array.fs
new file mode 100755
index 0000000..5c1f453
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/Compat.Array.fs
@@ -0,0 +1,110 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+#nowarn "9"
+#nowarn "51" // The address-of operator may result in non-verifiable code. Its use is restricted to passing byrefs to functions that require them
+   
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Array = 
+
+    open System.Runtime.InteropServices
+    
+    let invalidArg arg msg = raise (new System.ArgumentException((msg:string),(arg:string)))        
+    
+    let nonempty (arr: _[]) = (arr.Length <> 0)
+    
+    let inline pinObjUnscoped (obj: obj) =  GCHandle.Alloc(obj,GCHandleType.Pinned) 
+
+    let inline pinObj (obj: obj) f = 
+        let gch = pinObjUnscoped obj 
+        try f gch
+        finally
+            gch.Free()
+    
+    [<NoDynamicInvocation>]
+    let inline pin (arr: 'T []) (f : nativeptr<'T> -> 'U) = 
+        pinObj (box arr) (fun _ -> f (&&arr.[0]))
+    
+    [<NoDynamicInvocation>]
+    let inline pinUnscoped (arr: 'T []) : nativeptr<'T> * _ = 
+        let gch = pinObjUnscoped (box arr) 
+        &&arr.[0], gch
+
+    [<NoDynamicInvocation>]
+    let inline pin_unscoped arr= pinUnscoped arr 
+      
+    let inline contains x (arr: 'T []) =
+        let mutable found = false
+        let mutable i = 0
+        let eq = LanguagePrimitives.FastGenericEqualityComparer
+
+        while not found && i < arr.Length do
+            if eq.Equals(x,arr.[i]) then
+                found <- true
+            else
+                i <- i + 1
+        found
+
+    let inline mem x arr = contains x arr
+        
+    let scanSubRight f (arr : _[]) start fin initState = 
+        let mutable state = initState 
+        let res = Array.create (2+fin-start) initState 
+        for i = fin downto start do
+          state <- f arr.[i] state;
+          res.[i - start] <- state
+        done;
+        res
+
+    let scanSubLeft f  initState (arr : _[]) start fin = 
+        let mutable state = initState 
+        let res = Array.create (2+fin-start) initState 
+        for i = start to fin do
+          state <- f state arr.[i];
+          res.[i - start+1] <- state
+        done;
+        res
+
+    let scanReduce f (arr : _[]) = 
+        let arrn = arr.Length
+        if arrn = 0 then invalidArg "arr" "the input array is empty"
+        else scanSubLeft f arr.[0] arr 1 (arrn - 1)
+
+    let scanReduceBack f (arr : _[])  = 
+        let arrn = arr.Length
+        if arrn = 0 then invalidArg "arr" "the input array is empty"
+        else scanSubRight f arr 0 (arrn - 2) arr.[arrn - 1]
+
+    let createJaggedMatrix (n:int) (m:int) (x:'T) = 
+        let arr = (Array.zeroCreate n : 'T [][]) 
+        for i = 0 to n - 1 do 
+            let inner = (Array.zeroCreate m : 'T []) 
+            for j = 0 to m - 1 do 
+                inner.[j] <- x
+            arr.[i] <- inner
+        arr
+
+    let create_matrix n m x = createJaggedMatrix n m x
+
+    let isEmpty array = Array.isEmpty array
+
+    let zero_create n = Array.zeroCreate n 
+
+    let fold_left f z array = Array.fold f z array
+
+    let fold_right f array z = Array.foldBack f array z
+
+    let for_all f array = Array.forall f array
+
+
+    let split array = Array.unzip array
+
+    let combine array1 array2 = Array.zip array1 array2
+
+    let make (n:int) (x:'T) = Array.create n x
+
+    let to_list array = Array.toList array
+
+    let of_list list  = Array.ofList list
+
diff --git a/src/FSharp.PowerPack.Compatibility/Compat.Array.fsi b/src/FSharp.PowerPack.Compatibility/Compat.Array.fsi
new file mode 100755
index 0000000..8dcd690
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/Compat.Array.fsi
@@ -0,0 +1,81 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+   
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+    open System
+
+    /// Compatibility operations on arrays.  
+    [<RequireQualifiedAccess>]
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Array = 
+
+        /// Create a jagged 2 dimensional array.
+        val createJaggedMatrix: int -> int -> 'T -> 'T array array
+
+        /// Is an element in the array, uses (=) equality.
+        val inline contains: 'T -> 'T array -> bool  when 'T : equality
+
+        /// Like reduce, but return both the intermediary and final results
+        val scanReduce : reduction:('T -> 'T -> 'T) -> 'T array -> 'T array
+
+        /// Like reduceBack, but return both the intermediary and final results
+        val scanReduceBack : reduction:('T -> 'T -> 'T) -> 'T array -> 'T array
+
+
+        /// Pin the given array for the duration of a single call to the given function.  A native pointer to
+        /// the first element in the array is passed to the given function.  Cleanup the GCHandle associated with the 
+        /// pin when the function completes, even if an exception is raised.
+        [<Unverifiable>]
+        [<NoDynamicInvocation>]
+        val inline pin: 'T[] -> (nativeptr<'T> -> 'Result) -> 'Result
+
+        /// As for Array.pin, except that the caller is responsible for calling Free on the returned GCHandle in order
+        /// to release the pin.
+        [<Unverifiable>]
+        [<NoDynamicInvocation>]
+        val inline pinUnscoped: 'T[] -> nativeptr<'T> *  System.Runtime.InteropServices.GCHandle
+
+
+        /// Create a jagged 2 dimensional array.  Synonym for createJaggedMatrix.
+        [<CompilerMessage("This construct is for ML compatibility. The F# name for this function is 'createJaggedMatrix'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+        val create_matrix: int -> int -> 'T -> 'T array array
+
+        [<CompilerMessage("This construct is for ML compatibility. The F# name for this function is 'contains'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+        val inline mem: 'T -> 'T array -> bool when 'T : equality
+
+        [<Unverifiable>]
+        [<NoDynamicInvocation>]
+        [<Obsolete("This function has been renamed to 'pinUnscoped'")>]
+        val inline pin_unscoped: 'T[] -> nativeptr<'T> *  System.Runtime.InteropServices.GCHandle
+
+        [<Obsolete("This function will be removed. Use 'not Array.isEmpty' instead")>]
+        val nonempty: 'T[] -> bool
+
+        [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'zip' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+        val combine: array1:'T1 array -> array2:'T2 array -> ('T1 * 'T2) array
+
+        [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'unzip' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+        val split: array:('T1 * 'T2) array -> ('T1 array * 'T2 array)
+
+        [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'forall' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+        val for_all: predicate:('T -> bool) -> array:array<'T> -> bool
+
+        [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'create' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+        val make: count:int -> value:'T -> array<'T>
+         
+        [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'fold' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+        val fold_left: folder:('State -> 'T -> 'State) -> state:'State -> array: array<'T> -> 'State
+
+        /// Apply a function to each element of the array, threading an accumulator argument
+        /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
+        /// then computes <c>f i0 (...(f iN s))</c>
+        [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'foldBack' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+        val fold_right: folder:('T -> 'State -> 'State) -> array:array<'T> -> state:'State -> 'State
+
+        [<CompilerMessage("This construct is for ML compatibility. The F# library name for this function is now 'Array.toList'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+        val to_list: array:'T[] -> 'T list
+
+        [<CompilerMessage("This construct is for ML compatibility. The F# library name for this function is now 'Array.ofList'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+        val of_list: list:'T list -> 'T[]
+
diff --git a/src/FSharp.PowerPack.Compatibility/Compat.Array2D.fs b/src/FSharp.PowerPack.Compatibility/Compat.Array2D.fs
new file mode 100755
index 0000000..508095b
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/Compat.Array2D.fs
@@ -0,0 +1,33 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+#nowarn "9"
+#nowarn "51" // The address-of operator may result in non-verifiable code. Its use is restricted to passing byrefs to functions that require them
+   
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<RequireQualifiedAccess>]
+module Array2D = 
+    
+    open System.Runtime.InteropServices
+    
+    let inline pinObjUnscoped (obj: obj) =  
+        GCHandle.Alloc(obj,GCHandleType.Pinned) 
+
+    let inline pinObj (obj: obj) f = 
+        let gch = pinObjUnscoped obj 
+        try f gch
+        finally
+            gch.Free()
+
+    [<NoDynamicInvocation>]
+    let inline pin (arr: 'T [,]) (f : nativeptr<'T> -> 'U) = 
+        pinObj (box arr) (fun _ -> f (&&arr.[0,0]))
+    
+    [<NoDynamicInvocation>]
+    let inline pinUnscoped (arr: 'T [,]) : nativeptr<'T> * _ = 
+        let gch = pinObjUnscoped (box arr) 
+        &&arr.[0,0], gch
+
+    [<NoDynamicInvocation>]
+    let inline pin_unscoped arr = pinUnscoped arr
diff --git a/src/FSharp.PowerPack.Compatibility/Compat.Array2D.fsi b/src/FSharp.PowerPack.Compatibility/Compat.Array2D.fsi
new file mode 100755
index 0000000..c1fdcb1
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/Compat.Array2D.fsi
@@ -0,0 +1,27 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+    open System
+
+    [<RequireQualifiedAccess>]
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Array2D = 
+
+        /// Pin the given array for the duration of a single call to the given function.  A native pointer to
+        /// the first element in the array is passed to the given function.  Cleanup the GCHandle associated with the 
+        /// pin when the function completes, even if an exception is raised.
+        [<Unverifiable>]
+        [<NoDynamicInvocation>]
+        val inline pin: 'T[,] -> (nativeptr<'T> -> 'Result) -> 'Result
+
+        /// As for Array2D.pin, except that the caller is responsible for calling Free on the returned GCHandle in order
+        /// to release the pin.
+        [<Unverifiable>]
+        [<NoDynamicInvocation>]
+        val inline pinUnscoped: 'T[,] -> nativeptr<'T> *  System.Runtime.InteropServices.GCHandle
+        
+        [<Unverifiable>]
+        [<NoDynamicInvocation>]
+        [<Obsolete("This function has been renamed to 'pinUnscoped'")>]
+        val inline pin_unscoped: 'T[,] -> nativeptr<'T> *  System.Runtime.InteropServices.GCHandle
diff --git a/src/FSharp.PowerPack.Compatibility/Compat.List.fs b/src/FSharp.PowerPack.Compatibility/Compat.List.fs
new file mode 100755
index 0000000..c5e43ad
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/Compat.List.fs
@@ -0,0 +1,140 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+#nowarn "62"
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+open Microsoft.FSharp.Core.OptimizedClosures
+open System.Collections.Generic
+open System.Diagnostics
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module List = 
+
+    let invalidArg arg msg = raise (new System.ArgumentException((msg:string),(arg:string)))        
+
+    let nonempty x = match x with [] -> false | _ -> true
+    let rec contains x l = match l with [] -> false | h::t -> x = h || contains x t
+    let mem x l = contains x l
+    let rec memq x l = 
+        match l with 
+        | [] -> false 
+        | h::t -> LanguagePrimitives.PhysicalEquality x h || memq x t
+
+    let rec rev_map2_acc (f:FSharpFunc<_,_,_>) l1 l2 acc =
+        match l1,l2 with 
+        | [],[] -> acc
+        | h1::t1, h2::t2 -> rev_map2_acc f t1 t2 (f.Invoke(h1,h2) :: acc)
+        | _ -> invalidArg "l2" "the lists have different lengths"
+
+    let rev_map2 f l1 l2 = 
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        rev_map2_acc f l1 l2 []
+
+    let rec rev_append l1 l2 = 
+        match l1 with 
+        | [] -> l2
+        | h::t -> rev_append t (h::l2)
+
+
+    let rec rev_map_acc f l acc =
+        match l with 
+        | [] -> acc
+        | h::t -> rev_map_acc f t (f h :: acc)
+
+    let rev_map f l = rev_map_acc f l []
+
+    let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
+
+    let rec assoc x l = 
+        match l with 
+        | [] -> indexNotFound()
+        | ((h,r)::t) -> if x = h then r else assoc x t
+
+    let rec try_assoc x l = 
+        match l with 
+        | [] -> None
+        | ((h,r)::t) -> if x = h then Some(r) else try_assoc x t
+
+    let rec mem_assoc x l = 
+        match l with 
+        | [] -> false
+        | ((h,_)::t) -> x = h || mem_assoc x t
+
+    let rec remove_assoc x l = 
+        match l with 
+        | [] -> []
+        | (((h,_) as p) ::t) -> if x = h then t else p:: remove_assoc x t
+
+    let rec assq x l = 
+        match l with 
+        | [] -> indexNotFound()
+        | ((h,r)::t) -> if LanguagePrimitives.PhysicalEquality x h then r else assq x t
+
+    let rec try_assq x l = 
+        match l with 
+        | [] -> None
+        | ((h,r)::t) -> if LanguagePrimitives.PhysicalEquality x h then Some r else try_assq x t
+
+    let rec mem_assq x l = 
+        match l with 
+        | [] -> false
+        | ((h,_)::t) -> LanguagePrimitives.PhysicalEquality x h || mem_assq x t
+
+    let rec remove_assq x l = 
+        match l with 
+        | [] -> []
+        | (((h,_) as p) ::t) -> if LanguagePrimitives.PhysicalEquality x h then t else p:: remove_assq x t
+
+    let scanReduce f l = 
+        match l with 
+        | [] -> invalidArg "l" "the input list is empty"
+        | (h::t) -> List.scan f h t
+
+    let scanArraySubRight<'T,'State> (f:FSharpFunc<'T,'State,'State>) (arr:_[]) start fin initState = 
+        let mutable state = initState  
+        let mutable res = [state]  
+        for i = fin downto start do
+            state <- f.Invoke(arr.[i], state);
+            res <- state :: res
+        res
+
+    let scanReduceBack f l = 
+        match l with 
+        | [] -> invalidArg "l" "the input list is empty"
+        | _ -> 
+            let f = FSharpFunc<_,_,_>.Adapt(f)
+            let arr = Array.ofList l 
+            let arrn = Array.length arr 
+            scanArraySubRight f arr 0 (arrn - 2) arr.[arrn - 1]
+
+    let fold_left f z xs = List.fold f z xs
+
+    let fold_left2 f z xs1 xs2 = List.fold2 f z xs1 xs2
+
+    let fold_right f xs z = List.foldBack f xs z
+
+    let fold_right2 f xs1 xs2 z = List.foldBack2 f xs1 xs2 z
+
+    let for_all f xs = List.forall f xs
+
+    let for_all2 f xs1 xs2 = List.forall2 f xs1 xs2
+
+    let stable_sort f xs = List.sortWith f xs
+
+    let split x =  List.unzip x
+
+    let combine x1 x2 =  List.zip x1 x2
+
+    let find_all f x = List.filter f x
+
+    let flatten (list:seq<list<_>>) = List.concat list
+
+    let of_array (array:'T array) = List.ofArray array
+
+    let to_array (list:'T list) = List.toArray list
+
+    let hd list = List.head list
+
+    let tl list = List.tail list
+
diff --git a/src/FSharp.PowerPack.Compatibility/Compat.List.fsi b/src/FSharp.PowerPack.Compatibility/Compat.List.fsi
new file mode 100755
index 0000000..0af95ff
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/Compat.List.fsi
@@ -0,0 +1,126 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+open System
+
+/// Compatibility operations on lists.  
+[<RequireQualifiedAccess>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module List = 
+
+    /// Like reduce, but return both the intermediary and final results
+    val scanReduce : reduction:('T -> 'T -> 'T) -> 'T list -> 'T list
+
+    /// Like reduceBack, but return both the intermediary and final results
+    val scanReduceBack : reduction:('T -> 'T -> 'T) -> 'T list -> 'T list
+
+    /// Is an element in the list. Elements are compared using generic equality.
+    val contains: 'T -> 'T list -> bool when 'T : equality
+
+    /// Is an element in the list. Elements are compared using generic equality.
+    [<CompilerMessage("This construct is for ML compatibility. The F# name for this function is 'contains'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val mem: 'T -> 'T list -> bool when 'T : equality
+
+    /// Lookup key's data in association list, uses (=) equality.
+    /// Raise <c>System.IndexOutOfRangeException</c> exception if key not found, in which case you should typically use <c>try_assoc</c> instead.
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val assoc: 'Key -> ('Key * 'Value) list -> 'Value when 'Key : equality
+
+    /// Lookup key's data in association list, uses (=) equality,
+    /// returning "Some data" or "None".  
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val try_assoc: 'Key -> ('Key * 'Value) list -> 'Value option when 'Key : equality
+
+    /// Does the key have pair in the association list?
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val mem_assoc: 'Key -> ('Key * 'Value) list -> bool when 'Key : equality
+
+    /// Remove pair for key from the association list (if it's there).
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val remove_assoc: 'Key -> ('Key * 'Value) list -> ('Key * 'Value) list when 'Key : equality
+
+    /// See <c>assoc</c>, but uses the physical equality operator (==) for equality tests
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val assq: 'Key -> ('Key * 'Value) list -> 'Value when 'Key : not struct
+      
+    /// See <c>try_assoc</c>, but uses the physical equality operator (==) for equality tests.    
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val try_assq: 'Key -> ('Key * 'Value) list -> 'Value option when 'Key : not struct
+
+    /// See <c>mem_assoc</c>, but uses the physical equality operator (==) for equality tests.      
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val mem_assq: 'Key -> ('Key * 'Value) list -> bool when 'Key : not struct
+
+    /// See <c>remove_assoc</c>, but uses the physical equality operator (==) for equality tests.        
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val remove_assq: 'Key -> ('Key * 'Value) list -> ('Key * 'Value) list when 'Key : not struct
+
+    /// See <c>mem</c>, but uses the physical equality operator (==) for equality tests.        
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val memq: 'T -> 'T list -> bool when 'T : not struct
+
+    /// Return true if the list is not empty.
+    [<Obsolete("This function will be removed. Use 'not List.isEmpty' instead")>]
+    val nonempty: 'T list -> bool
+
+    /// "rev_map f l1" evaluates to "map f (rev l1)"
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val rev_map: mapping:('T -> 'U) -> 'T list -> 'U list
+
+    /// "rev_map2 f l1 l2" evaluates to "map2 f (rev l1) (rev l2)"
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val rev_map2: mapping:('T1 -> 'T2 -> 'U) -> 'T1 list -> 'T2 list -> 'U list
+
+    /// "rev_append l1 l2" evaluates to "append (rev l1) l2"
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val rev_append: 'T list -> 'T list -> 'T list
+
+    [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'concat' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val flatten: lists:seq<'T list> -> 'T list
+
+    [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'filter' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val find_all: predicate:('T -> bool) -> list:'T list -> 'T list
+
+    [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'fold' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val fold_left: folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State
+
+    [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'fold2' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val fold_left2: folder:('State -> 'T1 -> 'T2 -> 'State) -> state:'State -> list1:'T1 list -> list2:'T2 list -> 'State
+
+    [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'foldBack' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val fold_right: folder:('T -> 'State -> 'State) -> list:'T list -> state:'State -> 'State
+
+    [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'foldBack2' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val fold_right2: folder:('T1 -> 'T2 -> 'State -> 'State) -> list1:'T1 list -> list2:'T2 list -> state:'State -> 'State
+
+    [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'forall' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val for_all: predicate:('T -> bool) -> list:'T list -> bool
+
+    [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'sortWith' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val stable_sort: list: ('T -> 'T -> int) -> 'T list -> 'T list
+
+    [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'unzip' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val split: list:('T1 * 'T2) list -> ('T1 list * 'T2 list)
+
+    [<CompilerMessage("This construct is for ML compatibility. This F# library function has been renamed. Use 'zip' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val combine: list1:'T1 list -> list2:'T2 list -> ('T1 * 'T2) list
+    
+    [<CompilerMessage("This construct is for ML compatibility. The F# library name for this function is now 'List.ofArray'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val of_array : array:'T[] -> 'T list
+
+    [<CompilerMessage("This construct is for ML compatibility. The F# library name for this function is now 'List.toArray'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val to_array: list:'T list -> 'T[]
+
+    /// Return the first element of the list.
+    ///
+    /// Raises <c>System.ArgumentException</c> if <c>list</c> is empty
+    [<CompilerMessage("This construct is for ML compatibility. The F# library name for this function is now 'List.head'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val hd: list:'T list -> 'T
+
+    /// Return the tail of the list.  
+    ///
+    /// Raises <c>System.ArgumentException</c> if <c>list</c> is empty
+    [<CompilerMessage("This construct is for ML compatibility. The F# library name for this function is now 'List.tail'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val tl: list:'T list -> 'T list
+
diff --git a/src/FSharp.PowerPack.Compatibility/Compat.Seq.fs b/src/FSharp.PowerPack.Compatibility/Compat.Seq.fs
new file mode 100755
index 0000000..1019bff
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/Compat.Seq.fs
@@ -0,0 +1,21 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+#nowarn "9"
+   
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+open System.Collections.Generic
+
+[<RequireQualifiedAccess>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Seq = 
+
+    let generate openf compute closef = 
+        seq { let r = openf() 
+              try 
+                let x = ref None
+                while (x := compute r; (!x).IsSome) do
+                    yield (!x).Value
+              finally
+                 closef r }
+    
diff --git a/src/FSharp.PowerPack.Compatibility/Compat.Seq.fsi b/src/FSharp.PowerPack.Compatibility/Compat.Seq.fsi
new file mode 100755
index 0000000..48f368d
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/Compat.Seq.fsi
@@ -0,0 +1,14 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+    open System
+
+    [<RequireQualifiedAccess>]
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Seq = 
+
+
+        [<Obsolete("This function will be removed in a future release. Use a sqeuence expression instead")>]
+        val generate   : opener:(unit -> 'b) -> generator:('b -> 'T option) -> closer:('b -> unit) -> seq<'T>
+
diff --git a/src/FSharp.PowerPack.Compatibility/Compat.String.fs b/src/FSharp.PowerPack.Compatibility/Compat.String.fs
new file mode 100755
index 0000000..ded9306
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/Compat.String.fs
@@ -0,0 +1,111 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<RequireQualifiedAccess>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module String = 
+    let test_null arg = match arg with null -> raise (new System.ArgumentNullException("arg")) | _ -> ()
+    let invalidArg arg msg = raise (new System.ArgumentException((msg:string),(arg:string)))        
+
+    let get (str:string) i =
+        test_null str
+        try str.[i]
+        with :? System.ArgumentException -> invalidArg "i" "index out of bounds" 
+
+    let length (str:string) =
+        test_null str
+        str.Length
+
+    let sub (s:string) (start:int) (len:int) =
+        test_null s
+        try s.Substring(start,len)
+        with :? System.ArgumentException -> failwith "String.sub" 
+
+    let compare (x:string) y = compare x y
+
+    let fast_get (s:string) n =
+        test_null s
+        s.[n]
+
+    let of_char (c:char) = System.Char.ToString(c)
+    let make (n: int) (c: char) : string = new System.String(c, n)
+
+    let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index for the character was not found in the string"))
+    
+    let index_from (s:string) (start:int) (c:char) =  
+        test_null s
+        try let r = s.IndexOf(c,start) in if r = -1 then indexNotFound() else r
+        with :? System.ArgumentException -> invalidArg "start" "String.index_from" 
+      
+    let rindex_from (s:string) (start:int) (c:char) =
+        test_null s
+        try let r =  s.LastIndexOf(c,start) in if r = -1 then indexNotFound() else r
+        with :? System.ArgumentException -> invalidArg "start" "String.rindex_from" 
+      
+
+    let index (s:string) (c:char) =
+        test_null s
+        index_from s 0 c
+
+    let rindex (s:string) (c:char) =
+        test_null s
+        rindex_from s (length s - 1) c
+
+    let contains_between (s:string) (start:int) (stop:int) (c:char) =
+        test_null s
+        try s.IndexOf(c,start,(stop-start+1)) <> -1
+        with :? System.ArgumentException -> invalidArg "start" "String.contains_between" 
+
+    let contains_from (s:string) (start:int) (c:char) =
+        test_null s
+        let stop = length s - 1 in 
+        try s.IndexOf(c,start,(stop-start+1)) <> -1
+        with :? System.ArgumentException -> invalidArg "start" "String.contains_from" 
+
+    let rcontains_from (s:string) (stop:int) (c:char) =
+        test_null s
+        let start = 0 in
+        try s.IndexOf(c,start,(stop-start+1)) <> -1
+        with :? System.ArgumentException -> invalidArg "stop" "String.rcontains_from" 
+      
+    let contains (s:string) (c:char) = contains_from s 0 c
+
+    let uppercase (s:string) =
+        test_null s
+#if FX_NO_TO_LOWER_INVARIANT
+        s.ToUpper(System.Globalization.CultureInfo.InvariantCulture)
+#else
+        s.ToUpperInvariant()
+#endif
+
+    let lowercase (s:string) =
+        test_null s
+#if FX_NO_TO_LOWER_INVARIANT
+        s.ToLower(System.Globalization.CultureInfo.InvariantCulture)
+#else
+        s.ToLowerInvariant()
+#endif
+
+    let capitalize (s:string) =
+        test_null s
+        if s.Length = 0 then "" 
+        else (uppercase s.[0..0]) + s.[1..s.Length-1]
+
+    let uncapitalize (s:string) =
+        test_null s
+        if s.Length = 0 then  ""
+        else (lowercase s.[0..0]) + s.[1..s.Length-1]
+
+#if FX_NO_STRING_SPLIT_OPTIONS
+#else
+    let split (c : char list) =
+        let ca = Array.ofList c 
+        fun (s:string) ->
+            test_null s
+            Array.toList(s.Split(ca, System.StringSplitOptions.RemoveEmptyEntries))
+#endif
+
+    let trim (c : char list) =
+        let ca = Array.ofList c 
+        fun (s:string) -> s.Trim(ca)
diff --git a/src/FSharp.PowerPack.Compatibility/Compat.String.fsi b/src/FSharp.PowerPack.Compatibility/Compat.String.fsi
new file mode 100755
index 0000000..fe03f2a
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/Compat.String.fsi
@@ -0,0 +1,99 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+/// Compatibility module for string processing.  Richer string operations
+/// are available via the member functions on strings and other functionality in
+/// the <c>System.String</c> type
+/// and the <c>System.Text.RegularExpressions</c> namespace.
+[<RequireQualifiedAccess>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module String = 
+
+    /// Return a string with the first character converted to uppercase.
+    val capitalize: string -> string
+
+    /// Return a string with the first character converted to lowercase.
+    val uncapitalize: string -> string
+
+#if FX_NO_STRING_SPLIT_OPTIONS
+#else
+    /// Split the string using the given list of separator characters.
+    /// Trimming is also performed at both ends of the string and any empty
+    /// strings that result from the split are discarded.
+    val split: char list -> (string -> string list)
+#endif
+
+    /// Removes all occurrences of a set of characters specified in a
+    /// list from the beginning and end of this instance.
+    val trim: char list -> (string -> string)
+
+    /// Compare the given strings using ordinal comparison
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'Operators.compare' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val compare: string -> string -> int
+
+    /// Returns the character at the specified position in the string
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.[i]' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val get: string -> int -> char
+
+    /// Return a substring of length 'length' starting index 'start'.
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.[i..j]' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val sub: string -> start:int -> length:int -> string
+
+    /// Return a new string with all characters converted to lowercase
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.ToLower()' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val lowercase: string -> string
+
+    /// Return a string of the given length containing repetitions of the given character
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'String.replicate' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val make: int -> char -> string
+
+    /// Return s string of length 1 containing the given character
+    [<CompilerMessage("This construct is for ML compatibility. Consider using the overloaded 'string' operator instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val of_char: char -> string
+
+    /// Return true is the given string contains the given character
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.Contains' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val contains: string -> char -> bool
+
+    /// Return true is the given string contains the given character in the
+    /// range specified by the given start index and the given length
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.IndexOf' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val contains_between: string -> start:int -> length:int -> char -> bool
+
+    /// Return true is the given string contains the given character in the
+    /// range from the given start index to the end of the string.
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.IndexOf' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val contains_from: string -> int -> char -> bool
+
+    /// Return the first index of the given character in the
+    /// string.  Raise <c>KeyNotFoundException</c> if
+    /// the string does not contain the given character.
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.IndexOf' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val index: string -> char -> int
+
+    /// Return the first index of the given character in the
+    /// range from the given start position to the end of the string.  
+    /// Raise <c>KeyNotFoundException</c> if
+    /// the string does not contain the given character.
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.IndexOf' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val index_from: string -> start:int -> char -> int
+
+    /// Return true if the string contains the given character prior to the given index
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.LastIndexOf' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val rcontains_from: string -> start:int -> char -> bool
+
+    /// Return the index of the first occurrence of the given character 
+    /// from the end of the string proceeding backwards
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.LastIndexOf' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val rindex: string -> char -> int
+
+    /// Return the index of the first occurrence of the given character 
+    /// starting from the given index proceeding backwards.
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.LastIndexOf' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val rindex_from: string -> start:int -> char -> int
+
+    /// Return a string with all characters converted to uppercase.
+    [<CompilerMessage("This construct is for ML compatibility. Consider using 'str.ToUpper' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val uppercase: string -> string
+
diff --git a/src/FSharp.PowerPack.Compatibility/FSharp.PowerPack.Compatibility.fsproj b/src/FSharp.PowerPack.Compatibility/FSharp.PowerPack.Compatibility.fsproj
new file mode 100755
index 0000000..5b3be5f
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/FSharp.PowerPack.Compatibility.fsproj
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{6fc3b299-23cb-4098-998d-06c014431807}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>FSharp.PowerPack.Compatibility</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TreatWarningsAsErrors>
+    </TreatWarningsAsErrors>
+    <DocumentationFile>FSharp.PowerPack.Compatibility.xml</DocumentationFile>
+    <NoWarn>$(NoWarn);9;44;60;35;42;62;86;47;40;51</NoWarn>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="assemblyinfo.fs">
+      <Link>assemblyinfo.fs</Link>
+    </Compile>
+    <Compile Include="lazy.fsi" />
+    <Compile Include="lazy.fs" />
+    <Compile Include="Compat.String.fsi" />
+    <Compile Include="Compat.String.fs" />
+    <Compile Include="Compat.List.fsi" />
+    <Compile Include="Compat.List.fs" />
+    <Compile Include="Compat.Array.fsi" />
+    <Compile Include="Compat.Array.fs" />
+    <Compile Include="Compat.Array2D.fsi" />
+    <Compile Include="Compat.Array2D.fs" />
+    <Compile Include="Compat.Seq.fsi" />
+    <Compile Include="Compat.Seq.fs" />
+    <Compile Include="byte.fsi">
+      <Link>byte.fsi</Link>
+    </Compile>
+    <Compile Include="byte.fs">
+      <Link>byte.fs</Link>
+    </Compile>
+    <Compile Include="char.fsi">
+      <Link>char.fsi</Link>
+    </Compile>
+    <Compile Include="char.fs">
+      <Link>char.fs</Link>
+    </Compile>
+    <Compile Include="sbyte.fs">
+      <Link>sbyte.fs</Link>
+    </Compile>
+    <Compile Include="int16.fs">
+      <Link>int16.fs</Link>
+    </Compile>
+    <Compile Include="int32.fsi">
+      <Link>int32.fsi</Link>
+    </Compile>
+    <Compile Include="int32.fs">
+      <Link>int32.fs</Link>
+    </Compile>
+    <Compile Include="int64.fsi">
+      <Link>int64.fsi</Link>
+    </Compile>
+    <Compile Include="int64.fs">
+      <Link>int64.fs</Link>
+    </Compile>
+    <Compile Include="uint32.fsi">
+      <Link>uint32.fsi</Link>
+    </Compile>
+    <Compile Include="uint32.fs">
+      <Link>uint32.fs</Link>
+    </Compile>
+    <Compile Include="uint64.fsi">
+      <Link>uint64.fsi</Link>
+    </Compile>
+    <Compile Include="uint64.fs">
+      <Link>uint64.fs</Link>
+    </Compile>
+    <Compile Include="float.fsi">
+      <Link>float.fsi</Link>
+    </Compile>
+    <Compile Include="float.fs">
+      <Link>float.fs</Link>
+    </Compile>
+    <Compile Include="hashtbl.fsi">
+      <Link>hashtbl.fsi</Link>
+    </Compile>
+    <Compile Include="hashtbl.fs">
+      <Link>hashtbl.fs</Link>
+    </Compile>
+    <Compile Include="arg.fsi">
+      <Link>arg.fsi</Link>
+    </Compile>
+    <Compile Include="arg.fs">
+      <Link>arg.fs</Link>
+    </Compile>
+    <Compile Include="sys.fsi">
+      <Link>sys.fsi</Link>
+    </Compile>
+    <Compile Include="sys.fs">
+      <Link>sys.fs</Link>
+    </Compile>
+    <Compile Include="obj.fsi">
+      <Link>obj.fsi</Link>
+    </Compile>
+    <Compile Include="obj.fs">
+      <Link>obj.fs</Link>
+    </Compile>
+    <Compile Include="filename.fsi">
+      <Link>filename.fsi</Link>
+    </Compile>
+    <Compile Include="filename.fs">
+      <Link>filename.fs</Link>
+    </Compile>
+    <Compile Include="map.fsi">
+      <Link>map.fsi</Link>
+    </Compile>
+    <Compile Include="map.fs">
+      <Link>map.fs</Link>
+    </Compile>
+    <Compile Include="set.fsi">
+      <Link>set.fsi</Link>
+    </Compile>
+    <Compile Include="set.fs">
+      <Link>set.fs</Link>
+    </Compile>
+    <Compile Include="printexc.fsi">
+      <Link>printexc.fsi</Link>
+    </Compile>
+    <Compile Include="printexc.fs">
+      <Link>printexc.fs</Link>
+    </Compile>
+    <Compile Include="pervasives.fsi">
+      <Link>pervasives.fsi</Link>
+    </Compile>
+    <Compile Include="pervasives.fs">
+      <Link>pervasives.fs</Link>
+    </Compile>
+    <Compile Include="buffer.fsi">
+      <Link>buffer.fsi</Link>
+    </Compile>
+    <Compile Include="buffer.fs">
+      <Link>buffer.fs</Link>
+    </Compile>
+    <Compile Include="lexing.fsi">
+      <Link>lexing.fsi</Link>
+    </Compile>
+    <Compile Include="lexing.fs">
+      <Link>lexing.fs</Link>
+    </Compile>
+    <Compile Include="parsing.fsi">
+      <Link>parsing.fsi</Link>
+    </Compile>
+    <Compile Include="parsing.fs">
+      <Link>parsing.fs</Link>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\FSharp.PowerPack\FSharp.PowerPack.fsproj">
+      <Name>FSharp.PowerPack</Name>
+      <Project>{649fa588-f02e-457c-9fcf-87e46407481f}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Condition="'$(TargetFramework)'=='Silverlight'" Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.Common.targets"/>
+</Project>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Compatibility/FSharp.PowerPack.Compatibility.fsproj.vspscc b/src/FSharp.PowerPack.Compatibility/FSharp.PowerPack.Compatibility.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/FSharp.PowerPack.Compatibility.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FSharp.PowerPack.Compatibility/arg.fs b/src/FSharp.PowerPack.Compatibility/arg.fs
new file mode 100755
index 0000000..edd054b
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/arg.fs
@@ -0,0 +1,29 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Arg
+
+let Clear  x = ArgType.Clear x
+let Float  x = ArgType.Float x
+let Int    x = ArgType.Int x
+let Rest   x = ArgType.Rest x
+let Set    x = ArgType.Set x
+let String x = ArgType.String x
+let Unit   x = ArgType.Unit x
+
+type spec = ArgType
+type argspec = (string * spec * string) 
+#if FX_NO_COMMAND_LINE_ARGS
+#else
+
+exception Bad of string
+exception Help of string
+let parse_argv cursor argv specs other usageText =
+    ArgParser.ParsePartial(cursor, argv, List.map (fun (a,b,c) -> ArgInfo(a,b,c)) specs, other, usageText)
+
+let parse specs other usageText = 
+    ArgParser.Parse(List.map (fun (a,b,c) -> ArgInfo(a,b,c)) specs, other, usageText)
+
+let usage specs usageText = 
+    ArgParser.Usage(List.map (fun (a,b,c) -> ArgInfo(a,b,c)) specs, usageText)
+#endif
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Compatibility/arg.fsi b/src/FSharp.PowerPack.Compatibility/arg.fsi
new file mode 100755
index 0000000..1014c7b
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/arg.fsi
@@ -0,0 +1,50 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+/// A simple command-line argument processor.
+[<CompilerMessage("This module is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Arg
+
+// (c) Microsoft Corporation 2005-2009. 
+
+
+/// The spec value describes the action of the argument,
+/// and whether it expects a following parameter.
+type spec = ArgType
+
+val Clear  : bool ref         -> spec
+val Float  : (float -> unit)  -> spec
+val Int    : (int -> unit)    -> spec
+val Rest   : (string -> unit) -> spec
+val Set    : bool ref         -> spec
+val String : (string -> unit) -> spec
+val Unit   : (unit -> unit)   -> spec
+
+type argspec = (string * spec * string)
+
+/// "parse specs f use" parses the arguments given by Sys.argv
+/// according to the argument processing specifications "specs".
+/// Arguments begin with "-". Non-arguments are passed to "f" in
+/// order.  "use" is printed as part of the usage line if an error occurs.
+///
+/// Permitted arguments are specified using triples: (arg, action, help).
+/// Actions are:
+///   Unit(f): call f, no subseq. arg
+///   Set(br): set ref to 'true', no subseq. arg.
+///   Clear(br): set ref to 'false, no subseq. arg.
+///   String(f): pass the subseq. arg to f
+///   Int(f): pass the subseq. arg to f
+///   Float(f): pass the subseq. arg to f
+///   Rest(f): pass all subseq. args to f in order
+#if FX_NO_COMMAND_LINE_ARGS
+#else
+val parse: argspec list -> (string -> unit) -> string -> unit
+/// "usage specs use" prints the help for each argument.
+val usage: argspec list -> string -> unit
+exception Bad of string
+exception Help of string
+
+
+val parse_argv: int ref -> string array -> argspec list -> (string -> unit) -> string -> unit
+#endif
+
diff --git a/src/FSharp.PowerPack.Compatibility/assemblyinfo.fs b/src/FSharp.PowerPack.Compatibility/assemblyinfo.fs
new file mode 100755
index 0000000..e9e69df
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/assemblyinfo.fs
@@ -0,0 +1,30 @@
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("FSharp.PowerPack.Compatibility.dll")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("FSharp.PowerPack.Compatibility.dll")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+//[<assembly: System.Security.SecurityTransparent>]
+[<assembly: AutoOpen("Microsoft.FSharp.Compatibility.OCaml")>]
+[<assembly: AutoOpen("Microsoft.FSharp")>]
+do()
+
+#if FX_NO_SECURITY_PERMISSIONS
+#else
+#if FX_SIMPLE_SECURITY_PERMISSIONS
+[<assembly: System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.RequestMinimum)>]
+#else
+#endif
+#endif
+
+[<assembly: System.Runtime.InteropServices.ComVisible(false)>]
+
+[<assembly: System.CLSCompliant(true)>]
+
+
+#if FX_NO_DEFAULT_DEPENDENCY_TYPE
+#else
+[<assembly: System.Runtime.CompilerServices.Dependency("FSharp.Core",System.Runtime.CompilerServices.LoadHint.Always)>] 
+#endif
+
+do ()
diff --git a/src/FSharp.PowerPack.Compatibility/buffer.fs b/src/FSharp.PowerPack.Compatibility/buffer.fs
new file mode 100755
index 0000000..81652ac
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/buffer.fs
@@ -0,0 +1,33 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Buffer
+
+open Microsoft.FSharp.Compatibility.OCaml
+open Microsoft.FSharp.Compatibility.OCaml.Pervasives
+
+#nowarn "62" // use of ocaml compat functions from Pervasives
+
+type t = System.Text.StringBuilder
+
+let create (n:int) = new System.Text.StringBuilder(n)
+    
+let contents (t:t) = t.ToString()
+let length (t:t) = t.Length
+let clear (t:t) = ignore (t.Remove(0,length t))
+let reset (t:t) = ignore (t.Remove(0,length t))
+let add_char (t:t) (c:char) = ignore (t.Append(c))
+let add_string (t:t) (s:string) = ignore (t.Append(s))
+let add_substring (t:t) (s:string) n m = ignore (t.Append(s.[n..n+m-1]))
+let add_buffer (t:t) (t2:t) = ignore (t.Append(t2.ToString()))
+
+#if FX_NO_ASCII_ENCODING
+#else
+let add_channel (t:t) (c:in_channel) n = 
+  let b = Array.zeroCreate n  in 
+  really_input c b 0 n;
+  ignore (t.Append(System.Text.Encoding.ASCII.GetString(b, 0, n)))
+#endif
+
+let output_buffer (os:out_channel) (t:t) = 
+  output_string os (t.ToString())
diff --git a/src/FSharp.PowerPack.Compatibility/buffer.fsi b/src/FSharp.PowerPack.Compatibility/buffer.fsi
new file mode 100755
index 0000000..c37f4a4
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/buffer.fsi
@@ -0,0 +1,57 @@
+//==========================================================================
+// Buffer: StringBuilder operations for ML compatibility
+//
+// (c) Microsoft Corporation 2005-2008.  The interface to the module 
+// is similar to that found in versions of other ML implementations, 
+// but is not an exact match.  The type signatures in this interface
+// are an edited version of those generated automatically by running 
+// "bin\fsc.exe -i" on the implementation file.
+//===========================================================================
+
+/// Imperative buffers for building strings, a shallow interface to <c>System.Text.StringBuilder</c>
+[<CompilerMessage("This module is for ML compatibility. The Buffer module is a thin wrapper over the type System.Text.StringBuilder. Consider using that type directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Buffer
+open Microsoft.FSharp.Compatibility.OCaml.Pervasives
+
+#nowarn "62" // use of ocaml compat types from Pervasives
+
+type t = System.Text.StringBuilder
+
+/// Add second buffer to the first.
+val add_buffer: t -> t -> unit
+
+/// Add character to the buffer.
+val add_char: t -> char -> unit
+
+/// Add string to the buffer.
+val add_string: t -> string -> unit
+
+/// Given a string, start position and length add that substring to the buffer.
+val add_substring: t -> string -> int -> int -> unit
+
+/// Clears the buffer.
+val clear: t -> unit
+
+/// Gets the string built from the buffer.
+val contents: t -> string
+
+/// Create a buffer with suggested size.
+val create: int -> t
+
+/// Number of characters in the buffer.
+val length: t -> int
+
+val output_buffer: out_channel -> t -> unit
+
+/// Clears the buffer (same as Buffer.clear).
+val reset: t -> unit
+
+#if FX_NO_ASCII_ENCODING
+#else
+/// Read the given number of bytes as ASCII and add the resulting string 
+/// to the buffer.  Warning: this assumes an ASCII encoding for the I/O channel, i.e. it uses 
+/// Pervasives.really_input and then use ascii_to_string to produce the string 
+/// to add.  
+val add_channel: t -> in_channel -> int -> unit
+#endif
diff --git a/src/FSharp.PowerPack.Compatibility/byte.fs b/src/FSharp.PowerPack.Compatibility/byte.fs
new file mode 100755
index 0000000..e4a8aa5
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/byte.fs
@@ -0,0 +1,44 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2009.  
+//==========================================================================
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Byte = 
+
+    let compare (x:byte) y = compare x y
+
+    let zero = 0uy
+    let one = 1uy
+    let add (x:byte) (y:byte) = x + y
+    let sub (x:byte) (y:byte) = x - y
+    let mul (x:byte) (y:byte) = x * y
+    let div (x:byte) (y:byte) = x / y
+    let rem (x:byte) (y:byte) = x % y
+    let succ (x:byte) = x + 1uy
+    let pred (x:byte) = x - 1uy
+    let max_int = 0xFFuy
+    let min_int = 0uy
+    let logand (x:byte) (y:byte) = x &&& y
+    let logor (x:byte) (y:byte) = x ||| y
+    let logxor (x:byte) (y:byte) = x ^^^ y
+    let lognot (x:byte) = ~~~x
+    let shift_left (x:byte) (n:int) =  x <<< n
+    let shift_right (x:byte) (n:int) =  x >>> n
+    let of_int (n:int) =  byte n
+    let to_int (x:byte) = int x
+    let of_char (n:char) =  byte n
+    let to_char (x:byte) = char x
+    let of_string (s:string) = byte (int32 s)
+      
+    let to_string (x:byte) =  (box x).ToString()
+
+    let of_int32 (n:int32) = byte n
+    let to_int32 (x:uint8) = int32 x
+
+    let of_uint16 (n:uint16) = byte n
+    let to_uint16 (x:uint8)  = uint16 x
+
+    let of_uint32 (n:uint32) = byte n
+    let to_uint32 (x:uint8)  = uint32 x
diff --git a/src/FSharp.PowerPack.Compatibility/byte.fsi b/src/FSharp.PowerPack.Compatibility/byte.fsi
new file mode 100755
index 0000000..c35dca6
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/byte.fsi
@@ -0,0 +1,76 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2009.  
+//==========================================================================
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<System.Obsolete("Consider using operators such as 'int' and 'uint32' and 'uint64' to convert numbers")>]
+/// Byte (8-bit) operations.
+module Byte = 
+
+    /// The value zero as a System.Byte
+    val zero: byte
+    /// The value one as a System.Byte
+    val one: byte
+    /// Returns the successor of the argument wrapped around 255uy
+    val succ: byte -> byte
+    /// Returns the predeccessor of the argument wrapped around 0uy
+    val pred: byte -> byte
+
+    /// Returns the sum of a and b
+    val add: a:byte -> b:byte -> byte
+    /// Returns a divided by b 
+    val div: a:byte -> b:byte -> byte
+    /// Returns a multiplied by b 
+    val mul: a:byte -> b:byte -> byte
+    /// Returns a minus b 
+    val sub: a:byte -> b:byte -> byte
+    /// Returns the remainder of a divided by b
+    val rem: a:byte -> b:byte -> byte
+
+    /// Compares a and b and returns 1 if a > b, -1 if b < a and 0 if a = b
+    val compare: a:byte -> b:byte -> int
+
+    /// Combines the binary representation of a and b by bitwise and
+    val logand: a:byte -> b:byte -> byte
+    /// Returns the bitwise logical negation of a
+    val lognot: a:byte -> byte
+    /// Combines the binary representation of a and b by bitwise or
+    val logor: a:byte -> b:byte -> byte
+    /// Combines the binary representation of a and b by bitwise xor
+    val logxor: a:byte -> b:byte -> byte
+    /// Shifts the binary representation a by n bits to the left
+    val shift_left: a:byte -> n:int -> byte
+    /// Shifts the binary representation a by n bits to the right
+    val shift_right: a:byte -> n:int -> byte
+
+    /// Converts a char to a byte
+    val of_char: c:char -> byte
+    /// Converts a byte to a char 
+    val to_char: b:byte -> char
+
+    /// Converts a 32-bit integer to a byte
+    val of_int: i:int -> byte
+    /// Converts a byte to a 32-bit integer 
+    val to_int: b:byte -> int
+
+    /// Converts a 32-bit integer to a byte
+    val of_int32: i:int32 -> byte
+    /// Converts a byte to a 32-bit integer 
+    val to_int32: b:byte -> int32
+
+    /// Converts a 16-bit integer to a byte
+    val of_uint16: ui:uint16 -> byte
+    /// Converts a byte to a 16-bit integer 
+    val to_uint16: b:byte -> uint16
+
+    /// Converts an unsigned 32-bit integer to a byte
+    val of_uint32: ui:uint32 -> byte
+    /// Converts a byte to an unsigned 32-bit integer 
+    val to_uint32: b:byte -> uint32
+
+    /// Converts a string to a byte
+    val of_string: s:string -> byte
+    /// Converts a byte to a string
+    val to_string: b:byte -> string
diff --git a/src/FSharp.PowerPack.Compatibility/char.fs b/src/FSharp.PowerPack.Compatibility/char.fs
new file mode 100755
index 0000000..31d0b4e
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/char.fs
@@ -0,0 +1,21 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2009.  
+//==========================================================================
+
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Char = 
+    let compare (x:char) y = Operators.compare x y
+
+    let code (c:char) = int c 
+    let chr (n:int) =  char n 
+
+#if FX_NO_TO_LOWER_INVARIANT
+    let lowercase (c:char) = System.Char.ToLower(c, System.Globalization.CultureInfo.InvariantCulture)
+    let uppercase (c:char) = System.Char.ToUpper(c, System.Globalization.CultureInfo.InvariantCulture)
+#else
+    let lowercase (c:char) = System.Char.ToLowerInvariant(c)
+    let uppercase (c:char) = System.Char.ToUpperInvariant(c)
+#endif
diff --git a/src/FSharp.PowerPack.Compatibility/char.fsi b/src/FSharp.PowerPack.Compatibility/char.fsi
new file mode 100755
index 0000000..0e1e42c
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/char.fsi
@@ -0,0 +1,23 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2009.  
+//==========================================================================
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+/// Unicode characters, i.e. the <c>System.Char</c> type.  see also the operations
+/// in <c>System.Char</c> and the <c>System.Text.Encoding</c> interfaces if necessary.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<RequireQualifiedAccess>]
+[<CompilerMessage("This module is for ML compatibility. Consider using the F# overloaded operators such as 'char' and 'int' to convert basic types and System.Char.ToLower and System.Char.ToUpper to change case. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+module Char = 
+
+    /// Converts the value of the specified 32-bit signed integer to its equivalent Unicode character
+    val chr: i:int -> char
+    /// Converts the value of the specified Unicode character to the equivalent 32-bit signed integer
+    val code: c:char -> int
+    /// Compares a and b and returns 1 if a > b, -1 if b < a and 0 if a = b
+    val compare: a:char -> b:char -> int
+    /// Converts the value of a Unicode character to its lowercase equivalent
+    val lowercase: char -> char
+    /// Converts the value of a Unicode character to its uppercase equivalent
+    val uppercase: char -> char 
diff --git a/src/FSharp.PowerPack.Compatibility/filename.fs b/src/FSharp.PowerPack.Compatibility/filename.fs
new file mode 100755
index 0000000..2df1b27
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/filename.fs
@@ -0,0 +1,52 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Filename
+
+open System.IO
+
+let current_dir_name = "."
+let parent_dir_name =  ".."
+let concat (x:string) (y:string) = Path.Combine (x,y)
+let is_relative (s:string) = not (Path.IsPathRooted(s))
+
+// Case sensitive (original behaviour preserved).
+let check_suffix (x:string) (y:string) = x.EndsWith(y,System.StringComparison.Ordinal) 
+
+let chop_suffix (x:string) (y:string) =
+    if not (check_suffix x y) then 
+        raise (System.ArgumentException("chop_suffix")) // message has to be precisely this, for OCaml compatibility, and no argument name can be set
+    x.[0..x.Length-y.Length-1]
+
+let has_extension (s:string) = 
+    (s.Length >= 1 && s.[s.Length - 1] = '.' && s <> ".." && s <> ".") 
+    || Path.HasExtension(s)
+
+let chop_extension (s:string) =
+    if s = "." then "" else // for OCaml compatibility
+    if not (has_extension s) then 
+        raise (System.ArgumentException("chop_extension")) // message has to be precisely this, for OCaml compatibility, and no argument name can be set
+    Path.Combine (Path.GetDirectoryName s,Path.GetFileNameWithoutExtension(s))
+
+
+let basename (s:string) = 
+    Path.GetFileName(s)
+
+let dirname (s:string) = 
+    if s = "" then "."
+    else 
+      match Path.GetDirectoryName(s) with 
+      | null -> if Path.IsPathRooted(s) then s else "."
+      | res -> if res = "" then "." else res
+
+let is_implicit (s:string) = 
+    is_relative s &&
+      match Path.GetDirectoryName(s) with 
+      | null -> true
+      | res -> (res <> current_dir_name && res <> parent_dir_name)
+
+
+let temp_file (_p:string) (_s:string) = Path.GetTempFileName()
+
+let quote s = "\'" ^ s ^ "\'"
+
diff --git a/src/FSharp.PowerPack.Compatibility/filename.fsi b/src/FSharp.PowerPack.Compatibility/filename.fsi
new file mode 100755
index 0000000..089c827
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/filename.fsi
@@ -0,0 +1,63 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008.   The interface to the module 
+// is similar to that found in versions of other ML implementations, 
+// but is not an exact match.  The type signatures in this interface
+// are an edited version of those generated automatically by running 
+// "bin\fsc.exe -i" on the implementation file.
+//===========================================================================
+
+/// Common filename operations.  This module is included to make it possible to cross-compile 
+/// code with other ML compilers.  See also <c>System.IO.Path</c>
+[<CompilerMessage("This module is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Filename
+
+/// "check_suffix f s" returns true if filename "f" ends in suffix "s",
+/// e.g. check_suffix "abc.fs" ".fs" returns true.
+val check_suffix: string -> string -> bool
+
+/// "chop_extension f" removes the extension from the given
+/// filename. Raises ArgumentException if no extension is present.
+val chop_extension: string -> string
+
+/// Assuming "check_suffix f s" holds, "chop_suffix f s" returns the
+/// filename "f" with the suffix "s" removed.
+val chop_suffix: string -> string -> string
+
+/// "concat a b" returns System.IO.Path.Combine(a,b), i.e. the
+/// two names conjoined by the appropriate directory separator character
+/// for this architecture.
+val concat: string -> string -> string
+
+/// "dirname" and "basename" decompose a filename into a directory name
+/// and a filename, i.e. "concat (dirname s) (basename s) = s"
+val dirname: string -> string
+
+/// "dirname" and "basename" decompose a filename into a directory name
+/// and a filename, i.e. "concat (dirname s) (basename s) = s"
+val basename: string -> string
+
+/// The name used for the current directory on this OS. 
+val current_dir_name: string
+
+/// "parent_dir_name" returns the name for the directory above the current directory on
+/// this OS.
+val parent_dir_name: string
+
+/// Return true if the filename has a "." extension
+val has_extension: string -> bool
+
+/// Is the path is relative to the current directory or absolute.
+val is_relative: string -> bool
+
+/// Returns true if the path is relative to the current directory but does not begin with 
+/// an explicit "." or ".."
+val is_implicit: string -> bool
+
+/// "quote s" is designed for use to quote a filename when using it
+/// for a system command.  It returns ("\'" ^ s ^ "\'").  
+val quote: string -> string
+
+/// "temp_file f s" returns a hitherto unused new file name.  "f" and "s"
+/// are hints as to a suitable file name and suffix for the file.
+val temp_file: string -> string -> string
diff --git a/src/FSharp.PowerPack.Compatibility/float.fs b/src/FSharp.PowerPack.Compatibility/float.fs
new file mode 100755
index 0000000..4e45e63
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/float.fs
@@ -0,0 +1,56 @@
+
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+/// ML-like operations on 64-bit System.Double floating point numbers.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Float = 
+
+    let add (x:float) (y:float) = x + y
+    let div (x:float) (y:float) = x / y
+    let mul (x:float) (y:float) = x * y
+    let sub (x:float) (y:float) = x - y
+    let neg (x:float)   = - x
+
+    let compare (x:float) y = compare x y
+
+    let of_int (x:int) = float x
+    let ceil      (x:float)           = System.Math.Ceiling(x)
+    let floor     (x:float)           = System.Math.Floor(x)
+    let to_int (x:float) = 
+#if FX_NO_TRUNCATE
+         System.Convert.ToInt32(x) // REVIEW: possible implications of not calling Trancate?
+#else
+         System.Convert.ToInt32(System.Math.Truncate(x))
+#endif
+
+    let of_int64 (x:int64) = float x
+    let to_int64 (x:float) = int64 x
+
+    let of_int32 (x:int32) = float x
+    let to_int32 (x:float) = int32 x
+
+    let of_float32 (x:float32) = float x
+    let to_float32 (x:float) = float32 x
+
+    let to_string (x:float) = (box x).ToString()
+    let of_string (s:string) = 
+      (* Note System.Double.Parse doesn't handle -0.0 correctly (it returns +0.0) *)
+      let s = s.Trim()  
+      let l = s.Length 
+      let p = 0 
+      let p,sign = if (l >= p + 1 && s.[p] = '-') then 1,false else 0,true 
+      let n = 
+        try 
+          if p >= l then raise (new System.FormatException()) 
+          System.Double.Parse(s.[p..],System.Globalization.CultureInfo.InvariantCulture)
+        with :? System.FormatException -> failwith "Float.of_string"
+      if sign then n else -n
+
+#if FX_NO_DOUBLE_BIT_CONVERTER
+#else
+    let to_bits (x:float) = System.BitConverter.DoubleToInt64Bits(x)
+    let of_bits (x:int64) = System.BitConverter.Int64BitsToDouble(x)
+#endif
+
diff --git a/src/FSharp.PowerPack.Compatibility/float.fsi b/src/FSharp.PowerPack.Compatibility/float.fsi
new file mode 100755
index 0000000..0819b9f
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/float.fsi
@@ -0,0 +1,55 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2009.   
+//=========================================================================
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+/// ML-like operations on 64-bit System.Double floating point numbers.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<CompilerMessage("This module is for ML compatibility. Consider using the F# overloaded operators such as 'int' and 'float' to convert numbers. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+module Float= 
+
+    /// Returns the sum of a and b
+    val add: a:float -> b:float -> float
+    /// Returns a divided by b 
+    val div: a:float -> b:float -> float
+    /// Returns a multiplied by b 
+    val mul: a:float -> b:float -> float
+    /// Returns -a
+    val neg: a:float -> float
+    /// Returns a minus b 
+    val sub: a:float -> b:float -> float
+    /// Compares a and b and returns 1 if a > b, -1 if b < a and 0 if a = b
+    val compare: a:float -> b:float -> int
+
+    /// Converts a 32-bit integer to a 64-bit float
+    val of_int: i:int -> float
+    /// Converts a 64-bit float to a 32-bit integer
+    val to_int: f:float -> int
+
+    /// Converts a 32-bit integer to a 64-bit float
+    val of_int32: i:int32 -> float
+    /// Converts a 64-bit float to a 32-bit integer
+    val to_int32: f:float -> int32
+
+    /// Converts a 64-bit integer to a 64-bit float
+    val of_int64: i:int64 -> float
+    /// Converts a 64-bit float to a 64-bit integer 
+    val to_int64: f:float -> int64
+
+    /// Converts a 32-bit float to a 64-bit float
+    val of_float32: f32:float32 -> float
+    /// Converts a 64-bit float to a 32-bit float
+    val to_float32: f:float -> float32
+
+    /// Converts a string to a 64-bit float
+    val of_string: s:string -> float
+    /// Converts a 64-bit float to a string
+    val to_string: f:float -> string
+#if FX_NO_DOUBLE_BIT_CONVERTER
+#else
+    /// Converts a raw 64-bit representation to a 64-bit float
+    val of_bits: i64:int64 -> float
+    /// Converts a 64-bit float to raw 64-bit representation 
+    val to_bits: f:float -> int64
+#endif
diff --git a/src/FSharp.PowerPack.Compatibility/hashtbl.fs b/src/FSharp.PowerPack.Compatibility/hashtbl.fs
new file mode 100755
index 0000000..1f4d13b
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/hashtbl.fs
@@ -0,0 +1,80 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008.  
+//
+//===========================================================================
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Hashtbl
+
+open Microsoft.FSharp.Collections
+open System.Collections.Generic
+open System.IO
+
+type HashTable<'Key,'Val> = HashMultiMap<'Key,'Val> 
+type ('Key,'Val) t = HashMultiMap<'Key,'Val> 
+
+let inline create (n:int) = new HashMultiMap<_,_>(n, HashIdentity.Structural)
+
+let add (t:HashMultiMap<'Key,'Val>) x y = t.Add(x,y)
+let of_list (l : _ list) = 
+     let t = create (List.length l) in 
+     List.iter (fun (x,y) -> add t x y) l; 
+     t
+
+let of_seq (l:seq<_>) = 
+    let arr = Array.ofSeq l in 
+    let t = create (Array.length arr) in Array.iter (fun (x,y) -> add t x y) arr; 
+    t
+
+let copy (t:HashMultiMap<'Key,'Val>)  = t.Copy()
+let find (t:HashMultiMap<'Key,'Val>)  x = t.[x]
+let tryfind (t:HashMultiMap<'Key,'Val>)  x = t.TryFind x
+let find_all (t:HashMultiMap<'Key,'Val>)  x = t.FindAll x
+let mem (t:HashMultiMap<'Key,'Val>)  x =  t.ContainsKey x
+let remove (t:HashMultiMap<'Key,'Val>)  x = t.Remove x
+let replace (t:HashMultiMap<'Key,'Val>)  x y = t.Replace(x,y)
+let fold f (t:HashMultiMap<'Key,'Val>)  c = t.Fold f c
+let clear (t:HashMultiMap<'Key,'Val>)  = t.Clear ()
+let iter f (t:HashMultiMap<'Key,'Val>)  = t.Iterate f
+
+let hash x = LanguagePrimitives.GenericHash x
+let hashq x = LanguagePrimitives.PhysicalHash x
+
+// Componentized Hash Tables
+type Provider<'Key,'Val,'Tag> 
+     when 'Tag :> IEqualityComparer<'Key> =
+  interface
+    abstract create  : int -> Tagged.HashMultiMap<'Key,'Val,'Tag>;
+    abstract clear   : Tagged.HashMultiMap<'Key,'Val,'Tag> -> unit;
+    abstract add     : Tagged.HashMultiMap<'Key,'Val,'Tag> -> 'Key -> 'Val -> unit;
+    abstract copy    : Tagged.HashMultiMap<'Key,'Val,'Tag> -> Tagged.HashMultiMap<'Key,'Val,'Tag>;
+    abstract find    : Tagged.HashMultiMap<'Key,'Val,'Tag> -> 'Key -> 'Val;
+    abstract find_all: Tagged.HashMultiMap<'Key,'Val,'Tag> -> 'Key -> 'Val list;
+    abstract tryfind : Tagged.HashMultiMap<'Key,'Val,'Tag> -> 'Key -> 'Val option;
+    abstract mem     : Tagged.HashMultiMap<'Key,'Val,'Tag> -> 'Key -> bool;
+    abstract remove  : Tagged.HashMultiMap<'Key,'Val,'Tag> -> 'Key -> unit;
+    abstract replace : Tagged.HashMultiMap<'Key,'Val,'Tag> -> 'Key -> 'Val -> unit;
+    abstract iter    : ('Key -> 'Val -> unit) -> Tagged.HashMultiMap<'Key,'Val,'Tag> -> unit;
+    abstract fold    : ('Key -> 'Val -> 'State -> 'State) -> Tagged.HashMultiMap<'Key,'Val,'Tag> -> 'State -> 'State;
+    
+  end
+
+type Provider<'Key,'Val> = Provider<'Key,'Val,IEqualityComparer<'Key>>
+
+let MakeTagged (ops : 'Tag) : Provider<'Key,'Val,'Tag> when 'Tag :> IEqualityComparer<'Key> = 
+  { new Provider<_,_,_> with 
+      member p.create n = Tagged.HashMultiMap<'Key,'Val,'Tag>.Create(ops,n);
+      member p.clear c = c.Clear();
+      member p.add c x y = c.Add(x,y);
+      member p.copy c = c.Copy();
+      member p.find  c x = c.[x];
+      member p.find_all c x = c.FindAll(x);
+      member p.tryfind c x = c.TryFind(x);
+      member p.mem c x = c.ContainsKey(x);
+      member p.remove c x = c.Remove(x);
+      member p.replace c x y = c.Replace(x,y);
+      member p.iter f c = c.Iterate(f);
+      member p.fold f c acc = c.Fold f acc; }
+
+let Make (hash,eq) = MakeTagged (HashIdentity.FromFunctions hash eq)
+
diff --git a/src/FSharp.PowerPack.Compatibility/hashtbl.fsi b/src/FSharp.PowerPack.Compatibility/hashtbl.fsi
new file mode 100755
index 0000000..6a0fa7f
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/hashtbl.fsi
@@ -0,0 +1,139 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008.   The interface to the module 
+// is similar to that found in versions of other ML implementations, 
+// but is not an exact match.  The type signatures in this interface
+// are an edited version of those generated automatically by running 
+// "bin\fsc.exe -i" on the implementation file.
+//===========================================================================
+
+
+/// Multi-entry hash tables using the structural "hash" and "equals" functions.  
+///
+///These tables can be used with keys of any type, but you should check that
+///structural hashing and equality are correct for your key type.  
+///Structural hashing is efficient but not a suitable choice in all circumstances, 
+///e.g. may not hash efficiently on non-reference types and deeply-structured types.
+///Better efficiency is typically achieved if key types are F#-generated
+///types.
+///
+///These hash tables may map items to multiple keys (see find_all).
+///
+///The implementations are not safe for concurrent reading/writing,
+///and so users of these tables should take an appropriate lock
+///before reading/writing if used in a concurrent setting.
+[<CompilerMessage("This module is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Hashtbl
+open Microsoft.FSharp.Collections
+
+open System
+open System.IO
+open System.Collections.Generic
+
+
+/// OCaml compatible type name, for use when not opening module, e.g. Hashtbl.t
+type t<'Key,'Value> = HashMultiMap<'Key,'Value> 
+
+/// Create a hash table with the suggested initial size.  
+///
+/// Inlined to enable generation of efficient hash routines for the key type in the common case.
+val inline create  : int -> HashMultiMap<'Key,'Value> when 'Key : equality
+
+/// Add key and data to the table.
+val add     : HashMultiMap<'Key,'Value> -> 'Key -> 'Value -> unit when 'Key : equality
+
+/// Create a hash table using the given data
+val of_list : ('Key * 'Value) list -> HashMultiMap<'Key,'Value>  when 'Key : equality
+
+/// Create hash table using the given data
+val of_seq : seq<'Key * 'Value>  -> HashMultiMap<'Key,'Value>  when 'Key : equality
+
+/// Empty the table.
+val clear   : HashMultiMap<'Key,'Value> -> unit
+
+/// Create a copy of the table. Remember they are imperative and get mutated. 
+val copy    : HashMultiMap<'Key,'Value> -> HashMultiMap<'Key,'Value>
+
+/// Lookup key's data in the table.
+/// Raises exception is key not in table, if this could happen you should be using tryFind.
+val find    : HashMultiMap<'Key,'Value> -> 'Key -> 'Value
+
+/// Return all bindings for the given key
+val find_all: HashMultiMap<'Key,'Value> -> 'Key -> 'Value list
+
+/// Fold over all bindings
+val fold    : ('Key -> 'Value -> 'State -> 'State) -> HashMultiMap<'Key,'Value> -> 'State -> 'State
+
+///Apply the given function to each binding in the hash table 
+val iter    : ('Key -> 'Value -> unit) -> HashMultiMap<'Key,'Value> -> unit
+
+/// Test for the existence of any bindings for the given key
+val mem    : HashMultiMap<'Key,'Value> -> 'Key -> bool
+
+/// Remove the latest binding for the given key
+val remove : HashMultiMap<'Key,'Value> -> 'Key -> unit
+
+/// Replace the latest binding for the given key
+val replace: HashMultiMap<'Key,'Value> -> 'Key -> 'Value -> unit
+
+/// Lookup the key's data in the table
+val tryfind: HashMultiMap<'Key,'Value> -> 'Key -> 'Value option
+
+/// Hash on the structure of a value according to the F# structural hashing
+/// conventions
+val hash : 'T -> int 
+
+/// Hash on the identity of an object. 
+val hashq: 'T -> int   when 'T : not struct
+
+///A collection of operations for creating and using hash tables based on particular type-tracked hash/equality functions.
+///Generated by the Hashtbl.Make and Hashtbl.MakeTagged functors. This type is for use when you wish to
+///specify a comparison function once and carry around an object that is a provider of (i.e. a factory for) hashtables 
+///that utilize that comparison function.
+///
+///The 'Tag' type parameter is used to track information about the comparison function, which helps ensure 
+///that you don't mixup maps created with different comparison functions
+type Provider<'Key,'Value,'Tag>  
+     when 'Tag :> IEqualityComparer<'Key> =
+  interface
+    abstract create  : int -> Tagged.HashMultiMap<'Key,'Value,'Tag>;
+    abstract clear   : Tagged.HashMultiMap<'Key,'Value,'Tag> -> unit;
+    abstract add     : Tagged.HashMultiMap<'Key,'Value,'Tag> -> 'Key -> 'Value -> unit;
+    abstract copy    : Tagged.HashMultiMap<'Key,'Value,'Tag> -> Tagged.HashMultiMap<'Key,'Value,'Tag>;
+    abstract find    : Tagged.HashMultiMap<'Key,'Value,'Tag> -> 'Key -> 'Value;
+    abstract find_all: Tagged.HashMultiMap<'Key,'Value,'Tag> -> 'Key -> 'Value list;
+    abstract tryfind : Tagged.HashMultiMap<'Key,'Value,'Tag> -> 'Key -> 'Value option;
+    abstract mem     : Tagged.HashMultiMap<'Key,'Value,'Tag> -> 'Key -> bool;
+    abstract remove  : Tagged.HashMultiMap<'Key,'Value,'Tag> -> 'Key -> unit;
+    abstract replace : Tagged.HashMultiMap<'Key,'Value,'Tag> -> 'Key -> 'Value -> unit;
+    abstract iter    : ('Key -> 'Value -> unit) -> Tagged.HashMultiMap<'Key,'Value,'Tag> -> unit;
+    abstract fold    : ('Key -> 'Value -> 'State -> 'State) -> Tagged.HashMultiMap<'Key,'Value,'Tag> -> 'State -> 'State;
+  end
+
+type Provider<'Key,'Value> = Provider<'Key,'Value,IEqualityComparer<'Key>>
+
+/// Same as Make, except track the comparison function being used through an additional type parameter.
+///
+/// To use this function accurately you need to define a new named class that implements IEqualityComparer and
+/// pass an instance of that class as the first argument. For example:
+///      type MyHasher = 
+///        class
+///          new() = { }
+///          interface IEqualityComparer<string> with 
+///            member self.GetHashCode(x) = ...
+///            member self.Equals(x,y) = ...
+///          end
+///        end
+///
+/// let MyStringHashProvider : Hashtbl.Provider<string,int> = Hashtbl.MakeTagged(new MyStringHasher())
+val MakeTagged: ('Tag :> IEqualityComparer<'Key>) -> Provider<'Key,'Value,'Tag>
+
+/// Build a collection of operations for creating and using 
+/// hashtables based on the given hash/equality functions. This returns a record
+/// that contains the functions you use to create and manipulate tables of
+/// this kind.  The returned value is much like an ML module. You should call Make once for 
+/// each new pair of key/value types.  You may need to constrain the result 
+/// to be an instantiation of Provider.
+///
+/// let MyStringHashProvider : Provider<string,int> = Hashtbl.Make(myStringHash,myStringEq)
+val Make: ('Key -> int) * ('Key -> 'Key -> bool) -> Provider<'Key,'Value>
diff --git a/src/FSharp.PowerPack.Compatibility/int16.fs b/src/FSharp.PowerPack.Compatibility/int16.fs
new file mode 100755
index 0000000..617151b
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/int16.fs
@@ -0,0 +1,39 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<System.Obsolete("Consider using operators such as 'int' and 'int64' to convert numbers")>]
+module Int16 = 
+
+    let compare (x:int16) y = compare x y
+
+    let zero = 0s
+    let one = 1s
+    let minus_one = - 1s
+    let neg (x:int16) =  - x
+    let add (x:int16) (y:int16) = x + y
+    let sub (x:int16) (y:int16) = x - y
+    let mul (x:int16) (y:int16) = x * y 
+    let div (x:int16) (y:int16) = x / y
+    let rem (x:int16) (y:int16) = x % y
+    let succ (x:int16) = x + 1s
+    let pred (x:int16) = x - 1s
+    let abs (x:int16) = if x < zero then neg x else x
+    let max_int = 0x7FFFs
+    let min_int = 0x8000s
+    let logand (x:int16) (y:int16) = x &&& y
+    let logor (x:int16) (y:int16) = x ||| y
+    let logxor (x:int16) (y:int16) = x ^^^ y
+    let lognot (x:int16) = ~~~ x
+    let shift_left (x:int16) (n:int) =  x <<< n
+    let shift_right (x:int16) (n:int) =  x >>> n
+
+    let of_int8 (n:int8)   = int16 n
+    let to_int8 (x:int16) = sbyte x
+
+    let of_int (n:int) =  int16 n
+    let to_int (x:int16) = int x
+
+    let of_int32 (n:int32) =  int16 n
+    let to_int32 (x:int16) = int32 x
diff --git a/src/FSharp.PowerPack.Compatibility/int32.fs b/src/FSharp.PowerPack.Compatibility/int32.fs
new file mode 100755
index 0000000..b032494
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/int32.fs
@@ -0,0 +1,60 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Int32 = 
+
+    let compare (x:int32) y = compare x y
+
+    let zero = 0
+    let one = 1
+    let minus_one = (-1)
+    let neg (x:int32) =  -x
+    let add (x:int32) (y:int32) = x + y
+    let sub (x:int32) (y:int32) = x - y
+    let mul (x:int32) (y:int32) = x * y
+    let div (x:int32) (y:int32) = x / y
+    let rem (x:int32) (y:int32) = x % y
+    let succ (x:int32) = x + 1
+    let pred (x:int32) = x - 1
+    let abs (x:int32) = if x < zero then neg x else x
+    let max_int = 0x7FFFFFFF
+    let min_int = 0x80000000
+    let logand (x:int32) (y:int32) = x &&& y
+    let logor (x:int32) (y:int32) = x ||| y
+    let logxor (x:int32) (y:int32) = x ^^^ y
+    let lognot (x:int32) = ~~~ x
+    let shift_left (x:int32) (n:int) =  x <<< n
+    let shift_right (x:int32) (n:int) =  x >>> n
+
+    let of_uint32 (x:uint32) =  int32 x
+    let to_uint32 (x:int32) =  uint32 x
+
+    let shift_right_logical (x:int32) (n:int) =  of_uint32 (to_uint32 x >>> n)
+    let of_int (n:int) =  n
+    let to_int (x:int32) = x
+    let of_float (x:float) =  int32 x
+    let to_float (x:int32) =  float x
+
+    let of_float32 (x:float32) =  int32 x
+    let to_float32 (x:int32) =  float32 x
+
+    let of_int64 (x:int64) =  int32 x
+    let to_int64 (x:int32) =  int64 x
+
+    let of_nativeint (x:nativeint) =  int32 x 
+    let to_nativeint (x:int32) =  nativeint x
+
+
+    let of_string (s:string) = try int32 s with _ -> failwith "Int32.of_string"
+    let to_string (x:int32) = (box x).ToString()
+
+    let bits_of_float32 (x:float32) = System.BitConverter.ToInt32(System.BitConverter.GetBytes(x),0)
+    let float32_of_bits (x:int32) = System.BitConverter.ToSingle(System.BitConverter.GetBytes(x),0)
+
+    let float32_to_float (x:float32) = float x
+    let float_to_float32 (x:float) = float32 x
+
+    let float_of_bits x = float32_to_float (float32_of_bits x)
+    let bits_of_float x = bits_of_float32 (float_to_float32 x)
diff --git a/src/FSharp.PowerPack.Compatibility/int32.fsi b/src/FSharp.PowerPack.Compatibility/int32.fsi
new file mode 100755
index 0000000..8da5e44
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/int32.fsi
@@ -0,0 +1,105 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+/// Basic operations on 32-bit integers. The type int32 is identical to <c>System.Int32</c>. 
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<CompilerMessage("This module is for ML compatibility. Consider using the F# overloaded operators such as 'int' and 'float' to convert numbers. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+module Int32 = 
+
+    /// The value zero as a System.Int32
+    val zero: int32
+    /// The value one as a System.Int32
+    val one: int32
+    /// The value minus one as a System.Int32
+    val minus_one: int32
+    /// Returns the predeccessor of the argument 
+    val pred: int32 -> int32
+    /// Returns the largest 32-bit signed integer
+    val max_int: int32
+    /// Returns the smallest 32-bit signed integer
+    val min_int: int32
+    /// Returns the successor of the argument 
+    val succ: int32 -> int32
+
+    /// Returns the absolute value of the argument
+    val abs: int32 -> int32
+    /// Returns the sum of a and b
+    val add: a:int32 -> b:int32 -> int32
+    /// Returns a divided by b 
+    val div: a:int32 -> b:int32 -> int32
+    /// Returns a multiplied by b 
+    val mul: a:int32 -> b:int32 -> int32    
+    /// Returns -a
+    val neg: a:int32 -> int32
+    /// Returns the remainder of a divided by b
+    val rem: a:int32 -> b:int32 -> int32
+    /// Returns a minus b 
+    val sub: a:int32 -> b:int32 -> int32
+
+    /// Compares a and b and returns 1 if a > b, -1 if b < a and 0 if a = b
+    val compare: a:int32 -> b:int32 -> int
+
+    /// Combines the binary representation of a and b by bitwise and
+    val logand: a:int32 -> b:int32 -> int32
+    /// Returns the bitwise logical negation of a
+    val lognot: a:int32 -> int32
+    /// Combines the binary representation of a and b by bitwise or
+    val logor: a:int32 -> b:int32 -> int32
+    /// Combines the binary representation of a and b by bitwise xor
+    val logxor: int32 -> int32 -> int32
+    /// Shifts the binary representation a by n bits to the left
+    val shift_left: a:int32 -> n:int -> int32
+    /// Shifts the binary representation a by n bits to the right; high-order empty bits are set to the sign bit
+    val shift_right: a:int32 -> n:int -> int32
+    /// Shifts the binary representation a by n bits to the right; high-order bits are zero-filled
+    val shift_right_logical: a:int32 -> n:int -> int32
+
+    /// Converts a 64-bit float to a 32-bit integer
+    val of_float: float -> int32
+    /// Converts a 32-bit integer to a 64-bit float 
+    val to_float: int32 -> float
+
+    /// Converts a 32-bit float to a 32-bit integer
+    val of_float32: float32 -> int32
+    /// Converts a 32-bit integer to a 32-bit float 
+    val to_float32: int32 -> float32
+
+    (* In F#, type int32 is identical to int.  These operations are *)
+    (* included mostly for compatibility with other versions of ML *)
+    /// Converts a 32-bit integer to a 32-bit integer (included for ML compatability)
+    val of_int: int -> int32
+    /// Converts a 32-bit integer to a 32-bit integer (included for ML compatability)
+    val to_int: int32 -> int
+
+    (* Conversions to integers are to either the same size or same sign *)
+    /// Converts a 32-bit unsigned integer to a 32-bit integer 
+    val of_uint32: uint32 -> int32
+    /// Converts a 32-bit integer to a 32-bit unsigned integer 
+    val to_uint32: int32 -> uint32
+
+    /// Converts a 64-bit unsigned integer to a 32-bit integer 
+    val of_int64: int64 -> int32
+    /// Converts a 32-bit unsigned integer to a 64-bit integer 
+    val to_int64: int32 -> int64
+
+    /// Converts a 32-bit unsigned integer to a 32-bit integer 
+    val of_nativeint: nativeint -> int32
+    /// Converts a 32-bit unsigned integer to a 32-bit integer 
+    val to_nativeint: int32 -> nativeint
+
+    /// Converts a string to a 32-bit integer 
+    val of_string: string -> int32
+    /// Converts a 32-bit integer to a string 
+    val to_string: int32 -> string
+
+    /// Converts a raw 32-bit representation to a 64-bit float
+    val float_of_bits: int32 -> float
+    /// Converts a 64-bit float to a raw 32-bit representation 
+    val bits_of_float: float -> int32
+
+    /// Converts a raw 32-bit representation to a 32-bit float
+    val float32_of_bits: int32 -> float32
+    /// Converts a 32-bit float to a raw 32-bit representation 
+    val bits_of_float32: float32 -> int32
+
diff --git a/src/FSharp.PowerPack.Compatibility/int64.fs b/src/FSharp.PowerPack.Compatibility/int64.fs
new file mode 100755
index 0000000..23a2f41
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/int64.fs
@@ -0,0 +1,55 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Int64 = 
+
+    let compare (x:int64) y = compare x y
+
+    let zero = 0L
+    let one = 1L
+    let minus_one = -1L
+    let neg (x:int64) =  -x
+    let add (x:int64) (y:int64) = x + y
+    let sub (x:int64) (y:int64) = x - y
+    let mul (x:int64) (y:int64) = x * y
+    let div (x:int64) (y:int64) = x / y
+    let rem (x:int64) (y:int64) = x % y
+    let succ (x:int64) = x + 1L
+    let pred (x:int64) = x - 1L
+    let abs (x:int64) = if x < zero then neg x else x
+    let max_int = 0x7FFFFFFFFFFFFFFFL
+    let min_int = 0x8000000000000000L
+    let logand (x:int64) (y:int64) = x &&& y
+    let logor (x:int64) (y:int64) = x ||| y
+    let logxor (x:int64) (y:int64) = x ^^^ y
+    let lognot (x:int64) = ~~~x
+    let shift_left (x:int64) (n:int) =  x <<< n
+    let shift_right (x:int64) (n:int) =  x >>> n
+    let of_int (n:int) =  int64 n
+    let to_int (x:int64) = int x
+    let of_int32 (n:int32) =  int64 n
+    let to_int32 (x:int64) = int32 x
+    let of_uint64 (n:uint64) =  int64 n
+    let to_uint64 (x:int64) = uint64 x
+    let shift_right_logical (x:int64) (n:int) =  of_uint64 (to_uint64 x >>> n)
+
+    let of_nativeint (n:nativeint) =  int64 n
+    let to_nativeint (x:int64) = nativeint x
+    let of_float (x:float) =  int64 x
+    let to_float (x:int64) =  float x
+
+    let of_string (s:string) = try int64 s with _ -> failwith "Int64.of_string"
+    let to_string (x:int64) = (box x).ToString()
+
+#if FX_NO_DOUBLE_BIT_CONVERTER
+#else
+    let bits_of_float (x:float) = System.BitConverter.DoubleToInt64Bits(x)
+    let float_of_bits (x:int64) = System.BitConverter.Int64BitsToDouble(x)
+#endif
+
+
+    let of_float32 (x:float32) =  int64 x
+    let to_float32 (x:int64) =  float32 x
+
diff --git a/src/FSharp.PowerPack.Compatibility/int64.fsi b/src/FSharp.PowerPack.Compatibility/int64.fsi
new file mode 100755
index 0000000..291f438
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/int64.fsi
@@ -0,0 +1,100 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+/// Basic operations on 64-bit integers. The type int64 is identical to <c>System.Int64</c>. 
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<CompilerMessage("This module is for ML compatibility. Consider using the F# overloaded operators such as 'int' and 'float' to convert numbers. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+module Int64 = 
+
+    /// The value zero as a System.Int64
+    val zero: int64
+    /// The value one as a System.Int64
+    val one: int64
+    /// Returns the predeccessor of the argument 
+    val pred: int64 -> int64
+    /// Returns the successor of the argument 
+    val succ: int64 -> int64
+    /// Returns the largest 64-bit signed integer
+    val max_int: int64
+    /// Returns the smallest 64-bit signed integer
+    val min_int: int64
+    /// The value minus one as a System.Int64
+    val minus_one: int64
+
+    /// Returns the absolute value of the argument
+    val abs: int64 -> int64
+    /// Returns the sum of a and b
+    val add: a:int64 -> b:int64 -> int64
+    /// Returns a divided by b 
+    val div: a:int64 -> b:int64 -> int64
+    /// Returns a multiplied by b 
+    val mul: a:int64 -> b:int64 -> int64
+    /// Returns -a
+    val neg: a:int64 -> int64
+    /// Returns the remainder of a divided by b
+    val rem: a:int64 -> b:int64 -> int64
+    /// Returns a minus b 
+    val sub: a:int64 -> b:int64 -> int64
+
+    /// Compares a and b and returns 1 if a > b, -1 if b < a and 0 if a = b
+    val compare: int64 -> int64 -> int
+
+    /// Combines the binary representation of a and b by bitwise and
+    val logand: int64 -> int64 -> int64
+    /// Returns the bitwise logical negation of a
+    val lognot: int64 -> int64
+    /// Combines the binary representation of a and b by bitwise or
+    val logor: int64 -> int64 -> int64
+    /// Combines the binary representation of a and b by bitwise xor
+    val logxor: int64 -> int64 -> int64
+    /// Shifts the binary representation a by n bits to the left
+    val shift_left: a:int64 -> n:int -> int64
+    /// Shifts the binary representation a by n bits to the right; high-order empty bits are set to the sign bit
+    val shift_right: a:int64 -> n:int -> int64
+    /// Shifts the binary representation a by n bits to the right; high-order bits are zero-filled
+    val shift_right_logical: a:int64 -> n:int -> int64
+
+    /// Converts a 32-bit float to a 64-bit integer
+    val of_float32: float32 -> int64
+    /// Converts a 64-bit integer to a 32-bit float 
+    val to_float32: int64 -> float32
+
+    /// Converts a 64-bit float to a 64-bit integer
+    val of_float: float -> int64
+    /// Converts a 64-bit integer to a 64-bit float 
+    val to_float: int64 -> float
+
+    (* Conversions to integers are to either the same size or same sign *)
+    /// Converts a 32-bit integer to a 64-bit integer
+    val of_int: int -> int64
+    /// Converts a 64-bit integer to a 32-bit integer
+    val to_int: int64 -> int
+
+    /// Converts a 32-bit integer to a 64-bit integer
+    val of_int32: int32 -> int64
+    /// Converts a 64-bit integer to a 32-bit integer
+    val to_int32: int64 -> int32
+
+    /// Converts an unsigned 64-bit integer to a 64-bit integer
+    val of_uint64: uint64 -> int64
+    /// Converts a 64-bit integer to an unsigned 64-bit integer
+    val to_uint64: int64 -> uint64
+
+    /// Converts a native integer to a 64-bit integer
+    val of_nativeint: nativeint -> int64
+    /// Converts a 64-bit integer to a native integer 
+    val to_nativeint: int64 -> nativeint
+
+    /// Converts a string to a 64-bit integer 
+    val of_string: string -> int64
+    /// Converts a 64-bit integer to a string
+    val to_string: int64 -> string
+
+#if FX_NO_DOUBLE_BIT_CONVERTER
+#else
+    /// Converts a raw 64-bit representation to a 64-bit float
+    val float_of_bits: int64 -> float
+    /// Converts a 64-bit float to a raw 64-bit representation 
+    val bits_of_float: float -> int64
+#endif
diff --git a/src/FSharp.PowerPack.Compatibility/lazy.fs b/src/FSharp.PowerPack.Compatibility/lazy.fs
new file mode 100755
index 0000000..847fa03
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/lazy.fs
@@ -0,0 +1,13 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Lazy
+
+type 'a t = 'a Microsoft.FSharp.Control.Lazy
+
+let force (x: Microsoft.FSharp.Control.Lazy<'T>) = x.Force()
+let force_val (x: Microsoft.FSharp.Control.Lazy<'T>) = x.Force()
+let lazy_from_fun f = Microsoft.FSharp.Control.Lazy.Create(f)
+let create f = Microsoft.FSharp.Control.Lazy.Create(f)
+let lazy_from_val v = Microsoft.FSharp.Control.Lazy.CreateFromValue(v)
+let lazy_is_val (x: Microsoft.FSharp.Control.Lazy<'T>) = x.IsValueCreated
diff --git a/src/FSharp.PowerPack.Compatibility/lazy.fsi b/src/FSharp.PowerPack.Compatibility/lazy.fsi
new file mode 100755
index 0000000..c5247ee
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/lazy.fsi
@@ -0,0 +1,29 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Lazy
+
+open System
+
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+type 'T t = Microsoft.FSharp.Control.Lazy<'T>
+
+/// See Lazy.Force.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'v.Force()' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val force_val: Microsoft.FSharp.Control.Lazy<'T> -> 'T
+
+/// Build a lazy (delayed) value from the given computation
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'lazy' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val lazy_from_fun: (unit -> 'T) -> Microsoft.FSharp.Control.Lazy<'T>
+
+/// Build a lazy (delayed) value from the given pre-computed value.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'Lazy.CreateFromValue' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val lazy_from_val: 'T -> Microsoft.FSharp.Control.Lazy<'T>
+
+/// Check if a lazy (delayed) value has already been computed
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'Lazy.IsForced' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val lazy_is_val: Microsoft.FSharp.Control.Lazy<'T> -> bool
+
+/// Build a lazy (delayed) value from the given computation
+[<CompilerMessage("This construct is for ML compatibility. Consider using Lazy.Create instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val create : (unit -> 'T) -> Microsoft.FSharp.Control.Lazy<'T>
diff --git a/src/FSharp.PowerPack.Compatibility/lexing.fs b/src/FSharp.PowerPack.Compatibility/lexing.fs
new file mode 100755
index 0000000..3408b99
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/lexing.fs
@@ -0,0 +1,68 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2009.  
+//
+//=========================================================================
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Lexing
+
+open Microsoft.FSharp.Text.Lexing
+open System.IO
+open System.Text
+
+type position = Position  
+
+type lexbuf =  LexBuffer<byte>
+
+let from_function (f: byte[] -> int -> int)  = 
+    LexBuffer<byte>.FromByteFunction f
+
+
+let from_text_reader (enc: System.Text.Encoding) (tr: TextReader) =
+  LexBuffer<byte>.FromFunction (fun (bytebuf,start,len) ->
+    /// Don't read too many characters!
+    let lenc = (len * 99) / enc.GetMaxByteCount(100) 
+    let charbuf : char[] = Array.zeroCreate lenc 
+    let nRead = tr.Read(charbuf,start,lenc) 
+    if nRead = 0 then 0 
+    else enc.GetBytes(charbuf,0,nRead,bytebuf,start))
+                 
+let defaultEncoding =
+#if FX_NO_DEFAULT_ENCODING
+        Encoding.UTF8
+#else
+        Encoding.Default
+#endif
+
+let from_channel (is:TextReader)  = from_text_reader defaultEncoding is
+
+let from_bytearray s  = 
+    LexBuffer<byte>.FromBytes(s)
+
+#if FX_NO_ASCII_ENCODING
+let from_string s  = from_channel (new StringReader(s))
+#else
+let from_string s  = from_bytearray (System.Text.Encoding.ASCII.GetBytes(s:string))
+#endif
+
+let from_binary_reader (sr: BinaryReader)  = LexBuffer<byte>.FromFunction(sr.Read)
+
+let lexeme_char (lb:lexbuf) n =  char (int32 (lb.LexemeChar n))
+let lexeme_start_p (lb:lexbuf) = lb.StartPos
+let lexeme_end_p (lb:lexbuf) = lb.EndPos
+let lexeme_start (lb:lexbuf) = (lexeme_start_p lb).pos_cnum
+let lexeme_end (lb:lexbuf) = (lexeme_end_p lb).pos_cnum
+#if FX_NO_ASCII_ENCODING
+let lexeme_utf8 (lb:lexbuf) = System.Text.Encoding.UTF8.GetString(lb.Lexeme, 0, lb.Lexeme.Length)
+#else
+let lexeme (lb:lexbuf) = System.Text.Encoding.ASCII.GetString(lb.Lexeme, 0, lb.Lexeme.Length)
+let lexeme_utf8 (lb:lexbuf) = System.Text.Encoding.UTF8.GetString(lb.Lexeme, 0, lb.Lexeme.Length)
+#endif
+
+let lexeme_bytes (lb:lexbuf) = lb.Lexeme
+let flush_input (lb: lexbuf) = lb.DiscardInput ()
+
+
+let lexbuf_curr_p lb = lexeme_end_p lb
+let lexbuf_set_curr_p (lb:lexbuf) (p : position) = lb.EndPos  <- p
+let lexbuf_set_start_p (lb:lexbuf) (p : position) = lb.StartPos <- p
diff --git a/src/FSharp.PowerPack.Compatibility/lexing.fsi b/src/FSharp.PowerPack.Compatibility/lexing.fsi
new file mode 100755
index 0000000..31b6abb
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/lexing.fsi
@@ -0,0 +1,99 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008.   The interface to the module 
+// is similar to that found in versions of other ML implementations, 
+// but is not an exact match.  The type signatures in this interface
+// are an edited version of those generated automatically by running 
+// "bin\fsc.exe -i" on the implementation file.
+//===========================================================================
+
+/// Lexing: ML-like lexing support
+///
+/// This file maintains rough compatibility for lexbuffers used by some ML
+/// laxer generators.  The lexbuf carries an associated pair of positions.
+/// Beware that only the "cnum" (absolute character number) field is automatically 
+/// updated as each lexeme is matched.  Upon each successful match the prior end
+/// position is transferred to be the start position and a new start position
+/// is allocated with an updated pos_cnum field.
+//[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilerMessage("This module is for ML compatibility. Consider using the Microsoft.FSharp.Text.Lexing namespace directly", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Lexing
+open Microsoft.FSharp.Text.Lexing
+
+     
+type position = Position
+
+/// ASCII LexBuffers 
+///
+/// The type "lexbuf" is opaque, but has an internal position information field 
+/// that can be updated by setting "lexbuf.EndPos", for example if you wish 
+/// to update the other fields in that position data before or during 
+/// lexing.  You will need to do this if you wish to maintain accurate 
+/// line-count information.  If you do this and wish to maintain strict 
+/// cross-compiling compatibility with OCamlLex and other tools you may need code 
+/// to conditionally use lexbuf_set_curr_p when compiling F# code.
+type lexbuf = LexBuffer<byte>
+
+/// Remove all input, though don't discard the  except the current lexeme 
+val flush_input: lexbuf -> unit
+
+/// Fuel a lexer using the given in_channel.  The bytes are read using Pervasives.input.
+/// If the in_channel is a textual channel the bytes are 
+/// presented to the lexer by decoding the characters using System.Text.Encoding.ASCII.
+val from_channel: System.IO.TextReader -> lexbuf
+
+/// Fuel a lexer using the given TextReader or StreamReader.
+/// The characters read are decoded to bytes using the given encoding (e.g. System.Text.Encoding.ASCII)
+/// and the bytes presented to the lexer.  The encoding used to decode the characters
+/// is associated with the expectations of the lexer (e.g. a lexer may be constructed to accept only 
+/// ASCII or pseudo-UTF8 bytes) and will typically be different to 
+/// the encoding used to decode the file.
+val from_text_reader: System.Text.Encoding -> System.IO.TextReader -> lexbuf
+
+/// Fuel a lexer using the given BinaryReader.  
+val from_binary_reader: System.IO.BinaryReader -> lexbuf
+
+/// Fuel a lexer from a string, converted to ascii using <c>System.Text.Encoding.ASCII.GetBytes</c>
+val from_string: string -> lexbuf
+
+/// Fuel a lexer from an array of bytes
+val from_bytearray: byte[] -> lexbuf
+
+/// Fuel a lexer from function that fills an array of bytes up to the given length, returning the
+/// number of bytes filled.
+val from_function: (byte[] -> int -> int) -> lexbuf
+
+#if FX_NO_ASCII_ENCODING
+#else
+/// Return the matched string 
+val lexeme: lexbuf -> string
+#endif
+
+/// Return the matched string interpreting the bytes using the given Unicode text encoding
+val lexeme_utf8: lexbuf -> string
+
+/// Return the bytes for the matched string 
+val lexeme_bytes:  lexbuf -> byte array
+
+/// Return a character from the matched string, innterpreting the bytes using an ASCII encoding
+val lexeme_char: lexbuf -> int -> char
+
+/// Return the positions stored in the lexbuf for the matched string 
+val lexeme_start_p: lexbuf -> position
+/// Return the positions stored in the lexbuf for the matched string 
+val lexeme_end_p: lexbuf -> position
+
+
+/// Return absolute positions into the entire stream of characters
+val lexeme_start: lexbuf -> int
+/// Return absolute positions into the entire stream of characters
+val lexeme_end: lexbuf -> int
+
+/// same as lexeme_end_p 
+[<System.Obsolete("Get the EndPos property in the lexbuf directly, e.g. 'lexbuf.EndPos'")>]
+val lexbuf_curr_p: lexbuf -> position 
+[<System.Obsolete("Set the EndPos property in the lexbuf directly, e.g. 'lexbuf.EndPos <- pos'")>]
+val lexbuf_set_curr_p: lexbuf -> position -> unit
+[<System.Obsolete("Set the StartPos property in the lexbuf directly, e.g. 'lexbuf.StartPos <- pos'")>]
+val lexbuf_set_start_p: lexbuf -> position -> unit
+
diff --git a/src/FSharp.PowerPack.Compatibility/map.fs b/src/FSharp.PowerPack.Compatibility/map.fs
new file mode 100755
index 0000000..fdce638
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/map.fs
@@ -0,0 +1,46 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+    open System.Collections.Generic
+
+    type TaggedMap<'Key,'Value,'Tag when 'Tag :> IComparer<'Key> > = Microsoft.FSharp.Collections.Tagged.Map<'Key,'Value,'Tag>
+    type TaggedMap<'Key,'Value> = Microsoft.FSharp.Collections.Tagged.Map<'Key,'Value>
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Map = 
+
+        type Provider<'Key,'T,'Tag> when 'Tag :> IComparer<'Key> =
+            interface
+              abstract empty: TaggedMap<'Key,'T,'Tag>;
+              abstract add: 'Key -> 'T -> TaggedMap<'Key,'T,'Tag> -> TaggedMap<'Key,'T,'Tag>;
+              abstract find: 'Key -> TaggedMap<'Key,'T,'Tag> -> 'T;
+              abstract first: ('Key -> 'T -> 'U option) -> TaggedMap<'Key,'T,'Tag> -> 'U option;
+              abstract tryfind: 'Key -> TaggedMap<'Key,'T,'Tag> -> 'T option;
+              abstract remove: 'Key -> TaggedMap<'Key,'T,'Tag> -> TaggedMap<'Key,'T,'Tag>;
+              abstract mem: 'Key -> TaggedMap<'Key,'T,'Tag> -> bool;
+              abstract iter: ('Key -> 'T -> unit) -> TaggedMap<'Key,'T,'Tag> -> unit;
+              abstract map:  ('T -> 'U) -> TaggedMap<'Key,'T,'Tag> -> TaggedMap<'Key,'U,'Tag>;
+              abstract mapi: ('Key -> 'T -> 'U) -> TaggedMap<'Key,'T,'Tag> -> TaggedMap<'Key,'U,'Tag>;
+              abstract fold: ('Key -> 'T -> 'State -> 'State) -> TaggedMap<'Key,'T,'Tag> -> 'State -> 'State
+            end
+
+        let MakeTagged (cf : 'Tag) : Provider<'Key,'Value,'Tag> when 'Tag :> IComparer<'Key> =
+            { new Provider<_,_,_> with 
+                 member p.empty = TaggedMap<_,_,_>.Empty(cf);
+                 member p.add k v m  = m.Add(k,v);
+                 member p.find x m = m.[x] 
+                 member p.first f m = m.First(f)
+                 member p.tryfind k m = m.TryFind(k)
+                 member p.remove x m = m.Remove(x)
+                 member p.mem x m = m.ContainsKey(x)
+                 member p.iter f m = m.Iterate(f)
+                 member p.map f m = m.MapRange(f)
+                 member p.mapi f m = m.Map(f)
+                 member p.fold f m z = m.Fold f z }
+
+        type Provider<'Key,'Value> = Provider<'Key,'Value,IComparer<'Key>>
+        let Make cf  = MakeTagged (ComparisonIdentity.FromFunction cf)
+
+
+
+
diff --git a/src/FSharp.PowerPack.Compatibility/map.fsi b/src/FSharp.PowerPack.Compatibility/map.fsi
new file mode 100755
index 0000000..6b13c81
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/map.fsi
@@ -0,0 +1,58 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+#nowarn "62" // compat
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Map = 
+
+    open System
+    open System.Collections.Generic
+    open Microsoft.FSharp.Collections // Tagged.Map etc.
+
+    /// A provider for creating and using maps based on a particular comparison function.
+    /// The 'Tag type parameter is used to track information about the comparison function.
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    type Provider<'Key,'T,'Tag> when 'Tag :> IComparer<'Key> =
+        interface
+          abstract empty: Tagged.Map<'Key,'T,'Tag>;
+          abstract add: 'Key -> 'T -> Tagged.Map<'Key,'T,'Tag> -> Tagged.Map<'Key,'T,'Tag>;
+          abstract find: 'Key -> Tagged.Map<'Key,'T,'Tag> -> 'T;
+          abstract first: ('Key -> 'T -> 'U option) -> Tagged.Map<'Key,'T,'Tag> -> 'U option;
+          abstract tryfind: 'Key -> Tagged.Map<'Key,'T,'Tag> -> 'T option;
+          abstract remove: 'Key -> Tagged.Map<'Key,'T,'Tag> -> Tagged.Map<'Key,'T,'Tag>;
+          abstract mem: 'Key -> Tagged.Map<'Key,'T,'Tag> -> bool;
+          abstract iter: ('Key -> 'T -> unit) -> Tagged.Map<'Key,'T,'Tag> -> unit;
+          abstract map:  ('T -> 'U) -> Tagged.Map<'Key,'T,'Tag> -> Tagged.Map<'Key,'U,'Tag>;
+          abstract mapi: ('Key -> 'T -> 'U) -> Tagged.Map<'Key,'T,'Tag> -> Tagged.Map<'Key,'U,'Tag>;
+          abstract fold: ('Key -> 'T -> 'State -> 'State) -> Tagged.Map<'Key,'T,'Tag> -> 'State -> 'State
+        end
+
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    type Provider<'Key,'T> = Provider<'Key,'T,IComparer<'Key>>
+    
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val Make: ('Key -> 'Key -> int) -> Provider<'Key,'T>
+
+    /// A functor to build a collection of operations for creating and using 
+    /// maps based on the given comparison function. This returns a record that 
+    /// contains the functions you use to create and manipulate maps of
+    /// this kind.  The returned value is much like an ML module. 
+    ///
+    /// Language restrictions related to polymorphism may mean you
+    /// have to create a new instantiation of for each toplevel
+    /// key/value type pair.
+    ///
+    /// To use this function you need to define a new named class that implements IComparer and
+    /// pass an instance of that class as the first argument. For example:
+    ///      type MyComparer = 
+    ///          new() = { }
+    ///          interface IComparer<string> with 
+    ///            member self.Compare(x,y) = ...
+    ///
+    /// let MyStringMapProvider : Map.Provider < string,int > = Map.MakeTagged(new MyComparer())
+
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val MakeTagged: ('Tag :> IComparer<'Key>) -> Provider<'Key,'T,'Tag>
+
diff --git a/src/FSharp.PowerPack.Compatibility/obj.fs b/src/FSharp.PowerPack.Compatibility/obj.fs
new file mode 100755
index 0000000..e596f59
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/obj.fs
@@ -0,0 +1,16 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008.  
+//===========================================================================
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Obj
+
+type t = obj
+let repr x = box x
+let obj (x:obj) = unbox x
+let magic x = obj (repr x)
+let nullobj = (null : obj)
+
+
+let eq (x: 'a)  (y: 'a) = LanguagePrimitives.PhysicalEquality x y
+let not_eq (x:'a) (y:'a) = not (LanguagePrimitives.PhysicalEquality x y)
diff --git a/src/FSharp.PowerPack.Compatibility/obj.fsi b/src/FSharp.PowerPack.Compatibility/obj.fsi
new file mode 100755
index 0000000..080e2b9
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/obj.fsi
@@ -0,0 +1,38 @@
+
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008.  The interface to the module 
+// is similar to that found in versions of other ML implementations, 
+// but is not an exact match.  The type signatures in this interface
+// are an edited version of those generated automatically by running 
+// "bin\fsc.exe -i" on the implementation file.
+//===========================================================================
+
+[<CompilerMessage("This module is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Obj
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'obj' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+type t = obj
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'box' and/or 'unbox' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val magic: 'T -> 'U
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'null' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val nullobj: obj
+
+/// See Microsoft.FSharp.Core.Operators.unbox
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'unbox' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val obj: obj -> 'T
+
+/// See Microsoft.FSharp.Core.Operators.box
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'box' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val repr: 'T -> obj
+
+/// See Microsoft.FSharp.Core.LanguagePrimitives.PhysicalEquality
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'Microsoft.FSharp.Core.LanguagePrimitives.PhysicalEquality' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val eq: 'T -> 'T -> bool when 'T : not struct
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'not(Microsoft.FSharp.Core.LanguagePrimitives.PhysicalEquality(...))' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+/// Negation of Obj.eq (i.e. reference/physical inequality)
+val not_eq: 'T -> 'T -> bool when 'T : not struct
+
diff --git a/src/FSharp.PowerPack.Compatibility/parsing.fs b/src/FSharp.PowerPack.Compatibility/parsing.fs
new file mode 100755
index 0000000..b8b99c2
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/parsing.fs
@@ -0,0 +1,43 @@
+// (c) Microsoft Corporation 2005-2009.
+// Parsing: support fsyacc-generated parsers
+
+[<CompilerMessage("This module is for ML compatibility. Consider using the Microsoft.FSharp.Text.Parsing namespace directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Parsing
+open Microsoft.FSharp.Text.Lexing
+open Microsoft.FSharp.Text.Parsing
+open Microsoft.FSharp.Compatibility.OCaml
+
+let err _  = failwith "You must generate your parser using the '--ml-compatibility' option or call 'Parsing.set_parse_state parseState' in each action before using functions from the Parsing module.  This is because the module uses global state which must be set up for use in each parsing action. Review the notes in the 'Microsoft.FSharp.Compatibility.OCaml.Parsing' module if you are using parsers on multiple threads."
+let dummyProvider = 
+    { new IParseState with 
+        member x.InputRange(i) = err();
+        member p.InputStartPosition(n) = err();
+        member p.InputEndPosition(n) = err();
+        member x.ResultRange = err();
+        member x.GetInput(i) = err();
+        member x.ParserLocalStore = err();
+        member x.RaiseError() = err()  
+      }
+
+let mutable parse_information = dummyProvider
+let set_parse_state (x:IParseState) = parse_information <- x
+
+let enforce_nonnull_pos p = 
+  match (box p) with 
+  | null -> Position.Empty
+  | _ -> p
+
+let symbol_start_pos ()   = parse_information.ResultRange   |> fst |> enforce_nonnull_pos
+let symbol_end_pos ()     = parse_information.ResultRange   |> snd |> enforce_nonnull_pos
+let rhs_start_pos (n:int) = parse_information.InputRange(n) |> fst |> enforce_nonnull_pos
+let rhs_end_pos (n:int)   = parse_information.InputRange(n) |> snd |> enforce_nonnull_pos
+
+exception Parse_error  = RecoverableParseError
+let parse_error s = parse_information.RaiseError()(failwith s : unit)
+
+let symbol_start () = (symbol_start_pos()).pos_cnum
+let symbol_end () = (symbol_end_pos()).pos_cnum
+let rhs_start n = (rhs_start_pos n).pos_cnum
+let rhs_end n = (rhs_end_pos n).pos_cnum
+
diff --git a/src/FSharp.PowerPack.Compatibility/parsing.fsi b/src/FSharp.PowerPack.Compatibility/parsing.fsi
new file mode 100755
index 0000000..a06a7d9
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/parsing.fsi
@@ -0,0 +1,57 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008.   The interface to the module 
+// is similar to that found in versions of other ML implementations, 
+// but is not an exact match.  The type signatures in this interface
+// are an edited version of those generated automatically by running 
+// "bin\fsc.exe -i" on the implementation file.
+//===========================================================================
+
+/// Parsing: parser support for parsers produced by fsyacc.
+///
+/// Parsers generated by fsyacc provide location information within parser
+/// actions.  However that information is not available globally, but
+/// rather is accessed via the functions available on the following local
+/// variable which is available in all parser actions:
+///
+///    parseState : 'a Microsoft.FSharp.Text.Parsing.IParseState
+///
+/// However, this is not compatible with the parser specifications used
+/// with ocamlyacc and similar tools, which make a single parser state available
+/// globally.  If you wish to use a global parser state (e.g. so your code will
+/// cross-compile with OCaml) then you can use the functions in this file.
+/// You will need to either generate the parser with '--ml-compatibility' option 
+/// or add the code
+///
+///       Parsing.set_parse_state parseState;
+///
+/// at the start of each action of your grammar.  The functions below
+/// simply report the results of corresponding calls to the latest object
+/// specified by a call to set_parse_state.
+///
+/// Note that there could be unprotected multi-threaded concurrent access for the
+/// parser information, so you should not in general use these
+/// functions if there may be more than one parser active, and
+/// should instead use the functions directly available from the parseState
+/// object.
+[<CompilerMessage("This module is for ML compatibility. Consider using the Microsoft.FSharp.Text.Parsing namespace directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Parsing
+open Microsoft.FSharp.Text.Parsing
+open Microsoft.FSharp.Compatibility.OCaml
+
+val rhs_end: int -> int
+val rhs_end_pos: int -> Lexing.position
+val rhs_start: int -> int
+val rhs_start_pos: int -> Lexing.position
+val symbol_end: unit -> int
+val symbol_end_pos: unit -> Lexing.position
+val symbol_start: unit -> int
+val symbol_start_pos: unit -> Lexing.position
+
+val set_parse_state: IParseState -> unit
+
+/// You can initialize error recovery by raising the Parse_error exception. 
+
+exception Parse_error = Microsoft.FSharp.Text.Parsing.RecoverableParseError
+
+
diff --git a/src/FSharp.PowerPack.Compatibility/pervasives.fs b/src/FSharp.PowerPack.Compatibility/pervasives.fs
new file mode 100755
index 0000000..7709a9f
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/pervasives.fs
@@ -0,0 +1,710 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<AutoOpen>]
+module Microsoft.FSharp.Compatibility.OCaml.Pervasives
+
+#nowarn "62" // compatibility warnings
+#nowarn "35"  // 'deprecated' warning about redefining '<' etc.
+#nowarn "86"  // 'deprecated' warning about redefining '<' etc.
+#nowarn "60"  // override implementations in intrinsic extensions
+#nowarn "69"  // interface implementations in intrinsic extensions
+
+open System.Collections.Generic
+
+exception Match_failure = Microsoft.FSharp.Core.MatchFailureException
+exception Assert_failure of string * int * int 
+
+exception Undefined 
+
+exception End_of_file      = System.IO.EndOfStreamException
+exception Out_of_memory    = System.OutOfMemoryException
+exception Division_by_zero = System.DivideByZeroException
+exception Stack_overflow   = System.StackOverflowException 
+
+let Not_found<'a> = (new KeyNotFoundException("The item was not found during a search or in a collection") :> exn)
+let (|Not_found|_|) (inp:exn) = match inp with :? KeyNotFoundException -> Some() | _ -> None
+
+let Invalid_argument (msg:string) = (new System.ArgumentException(msg) :> exn)
+let (|Invalid_argument|_|) (inp:exn) = match inp with :? System.ArgumentException as e -> Some(e.Message) | _ -> None
+
+let invalid_arg s = raise (System.ArgumentException(s))
+
+let not_found() = raise Not_found
+
+let inline (==)    (x:'a) (y:'a) = LanguagePrimitives.PhysicalEquality x y
+let inline (!=)    (x:'a) (y:'a) = not (LanguagePrimitives.PhysicalEquality x y)
+let inline (mod)  (x:int) (y:int)  = Operators.(%) x y
+let inline (land) (x:int) (y:int)  = Operators.(&&&) x y
+let inline (lor)  (x:int) (y:int)  = Operators.(|||) x y
+let inline (lxor) (x:int) (y:int)  = Operators.(^^^) x y
+let inline lnot   (x:int)          = Operators.(~~~) x
+let inline (lsl)  (x:int) (y:int)  = Operators.(<<<) x y
+let inline (lsr)  (x:int) (y:int)  = int32 (uint32 x >>> y)
+let inline (asr)  (x:int) (y:int)  = Operators.(>>>) x y
+
+let int_neg (x:int) = -x
+let (~-.)  (x:float)           =  -x
+let (~+.)  (x:float)           =  x
+let (+.)   (x:float) (y:float) =  x+y
+let (-.)   (x:float) (y:float) =  x-y
+let ( *.)  (x:float) (y:float) =  x*y
+let ( /.)  (x:float) (y:float) =  x/y
+
+let inline (.())   (arr: _[]) n = arr.[n]
+let inline (.()<-) (arr: _[]) n x = arr.[n] <- x
+
+let succ (x:int) = x + 1
+let pred (x:int) = x - 1
+let max_int = 0x7FFFFFFF // 2147483647 
+let min_int = 0x80000000 // -2147483648 
+
+(*  mod_float x y = x - y * q where q = truncate(a/b) and truncate x removes fractional part of x *)
+let truncate (x:float) : int = int32 x
+
+#if FX_NO_TRUNCATE
+let truncatef (x:float) = 
+    if x >= 0.0 then 
+        System.Math.Floor x
+    else
+        System.Math.Ceiling x
+#else
+let truncatef (x:float) = System.Math.Truncate x
+#endif
+let mod_float x y = x - y * truncatef(x/y)
+let float_of_int (x:int) =  float x
+let ldexp x (n:int) = x * (2.0 ** float n)
+let modf x = let integral = Operators.floor x in (integral, x - integral)
+let int_of_float x =  truncate x
+
+let neg_infinity = System.Double.NegativeInfinity
+let max_float    = System.Double.MaxValue 
+let min_float    =  0x0010000000000000LF
+let epsilon_float = 0x3CB0000000000000LF // Int64.float_of_bits 4372995238176751616L
+
+type fpclass = FP_normal (* | FP_subnormal *)  | FP_zero| FP_infinite | FP_nan      
+
+let classify_float (x:float) = 
+    if System.Double.IsNaN x then FP_nan
+    elif System.Double.IsNegativeInfinity x then FP_infinite
+    elif System.Double.IsPositiveInfinity x then FP_infinite
+    elif x = 0.0 then FP_zero
+    else FP_normal
+       
+let abs_float (x:float)           = Operators.abs x
+
+let int_of_char (c:char) = System.Convert.ToInt32(c)
+let char_of_int (x:int) = System.Convert.ToChar(x)
+
+let string_of_bool b = if b then "true" else "false"
+let bool_of_string s = 
+  match s with 
+  | "true" -> true 
+  | "false" -> false
+  | _ -> raise (System.ArgumentException("bool_of_string"))
+
+let string_of_int (x:int) = x.ToString()
+let int_of_string (s:string) = try int32 s with _ -> failwith "int_of_string"
+let string_of_float (x:float) = x.ToString()
+let float_of_string (s:string) = try float s with _ -> failwith "float_of_string"
+
+let string_to_int   x = int_of_string x
+
+
+//--------------------------------------------------------------------------
+// I/O
+//
+// OCaml-compatible channels conflate binary and text IO. It is very inconvenient to introduce
+// out_channel as a new abstract type, as this means functions like fprintf can't be used in 
+// conjunction with TextWriter values.  Hence we pretend that OCaml channels are TextWriters, and 
+// implement TextWriters in such a way the the implementation contains an optional binary stream
+// which is utilized by the OCaml binary I/O methods.
+//
+// Notes on the implementation: We discriminate between three kinds of 
+// readers/writers since various operations are possible on each kind.
+// StreamReaders/StreamWriters inherit from text readers/writers and
+// thus support more functionality.  We could just support two 
+// constructors (Binary and Text) and use dynamic type tests on the underlying .NET
+// objects to detect the cases where we have StreamWriters.
+//--------------------------------------------------------------------------
+open System.Text
+open System.IO
+
+type writer = 
+  | StreamW of StreamWriter
+  | TextW of (unit -> TextWriter)
+  | BinaryW of BinaryWriter
+
+
+[<assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", Scope="member", Target="Internal.Utilities.Pervasives+OutChannelImpl.#.ctor(Internal.Utilities.Pervasives+writer)", MessageId="System.IO.TextWriter.#ctor")>]
+do()
+
+let defaultEncoding =
+#if FX_NO_DEFAULT_ENCODING
+        // default encoding on Silverlight is UTF8 (to aling with e.g. System.IO.StreamReader)
+        Encoding.UTF8
+#else
+        Encoding.Default
+#endif
+
+type out_channel = TextWriter
+type OutChannelImpl(w: writer) = 
+    inherit TextWriter()
+    let mutable writer = w
+    member x.Writer with get() = writer and set(w) = writer <- w
+    
+    member x.Stream = 
+        match writer with 
+        | TextW _ -> failwith "cannot access a stream for this channel"
+        | BinaryW bw -> bw.BaseStream 
+        | StreamW sw -> sw.BaseStream
+    member x.TextWriter = 
+        match writer with 
+        | StreamW sw -> (sw :> TextWriter)
+        | TextW tw -> tw()
+        | _ -> failwith "binary channels created using the OCaml-compatible Pervasives.open_out_bin cannot be used as TextWriters.  Consider using 'System.IO.BinaryWriter' in preference to creating channels using open_out_bin."
+        
+    member x.StreamWriter = 
+        match writer with 
+        | StreamW sw -> sw
+        | _ -> failwith "cannot access a stream writer for this channel"
+    member x.BinaryWriter = 
+        match writer with 
+        | BinaryW w -> w
+        | _ -> failwith "cannot access a binary writer for this channel"
+
+type open_flag =
+  | Open_rdonly | Open_wronly | Open_append
+  | Open_creat | Open_trunc | Open_excl
+  | Open_binary | Open_text 
+#if FX_NO_NONBLOCK_IO
+#else
+  | Open_nonblock
+#endif
+  | Open_encoding of Encoding
+
+type reader = 
+  | StreamR of StreamReader
+  | TextR of (unit -> TextReader)
+  | BinaryR of BinaryReader
+
+/// See OutChannelImpl
+type in_channel = System.IO.TextReader
+type InChannelImpl(r : reader) = 
+    inherit TextReader()
+    let mutable reader = r
+    member x.Reader with get() = reader and set(r) = reader <- r
+    
+    member x.Stream =
+        match reader with 
+        | TextR _ -> failwith "cannot access a stream for this channel"
+        | BinaryR bw -> bw.BaseStream 
+        | StreamR sw -> sw.BaseStream
+    member x.TextReader = 
+        match reader with 
+        | StreamR sw -> (sw :> TextReader)
+        | TextR tw -> tw()
+        | _ -> failwith "binary channels created using the OCaml-compatible Pervasives.open_in_bin cannot be used as TextReaders  If necessary use the OCaml compatible binary input methods Pervasvies.input etc. to read from this channel. Consider using 'System.IO.BinaryReader' in preference to channels created using open_in_bin."
+        
+    member x.StreamReader = 
+        match reader with 
+        | StreamR sw -> sw
+        | _ -> failwith "cannot access a stream writer for this channel"
+    member x.BinaryReader = 
+        match reader with 
+        | BinaryR w -> w
+        | _ -> failwith "cannot access a binary writer for this channel"
+
+let (!!) (os : out_channel) = 
+    match os with 
+    | :? OutChannelImpl as os -> os.Writer
+    | :? StreamWriter as sw -> StreamW sw
+    | _ -> TextW (fun () -> os)
+let (<--) (os: out_channel) os' = 
+    match os with 
+    | :? OutChannelImpl as os -> os.Writer <- os'
+    | _ -> failwith "the mode may not be adjusted on a writer not created with one of the Pervasives.open_* functions"
+    
+let stream_to_BinaryWriter s    = BinaryW (new BinaryWriter(s))
+let stream_to_StreamWriter (encoding : Encoding) (s : Stream) =   StreamW (new StreamWriter(s,encoding))
+
+module OutChannel = 
+    let to_Stream (os:out_channel) =
+      match !!os with 
+      | BinaryW bw -> bw.BaseStream 
+      | StreamW sw -> sw.BaseStream
+      | TextW _ -> failwith "to_Stream: cannot access a stream for this channel"
+      
+    let to_StreamWriter (os:out_channel) =
+      match !!os with 
+      | StreamW sw -> sw
+      | _ -> failwith "to_StreamWriter: cannot access a stream writer for this channel"
+      
+    let to_TextWriter (os:out_channel) =
+      match !!os with 
+      | StreamW sw -> (sw :> TextWriter)
+      | TextW tw -> tw()
+      | _ -> os
+      
+    let of_StreamWriter w =
+      new OutChannelImpl(StreamW(w)) :> out_channel
+
+    let to_BinaryWriter (os:out_channel) =
+      match !!os with 
+      | BinaryW bw -> bw
+      | _ -> failwith "to_BinaryWriter: cannot access a binary writer for this channel"
+      
+    let of_BinaryWriter w =
+      new OutChannelImpl(BinaryW w) :> out_channel
+      
+    let of_TextWriter (w:TextWriter) =
+      let absw = 
+        match w with 
+        | :? StreamWriter as sw -> StreamW sw
+        | tw -> TextW (fun () -> tw) in
+      new OutChannelImpl(absw) :> out_channel
+        
+    let of_Stream encoding (s : Stream) =   new OutChannelImpl(stream_to_StreamWriter encoding s) :> out_channel
+      
+let listContains x l = List.exists (fun y -> x = y) l
+
+let open_out_gen flags (_perm:int) (s:string) = 
+    // permissions are ignored 
+    let app = listContains Open_append flags in 
+    let access = 
+        match listContains Open_rdonly flags, listContains Open_wronly flags with
+        | true, true -> invalidArg "flags" "invalid access for reading"
+        | true, false -> invalidArg "flags" "invalid access for writing" // FileAccess.Read 
+        | false, true ->  FileAccess.Write
+        | false, false -> (if app then FileAccess.Write else FileAccess.ReadWrite)  
+    let mode =
+        match (listContains Open_excl flags,app, listContains Open_creat flags, listContains Open_trunc flags) with
+        | (true,false,false,false) -> FileMode.CreateNew
+        | false,false,true,false -> FileMode.Create
+        | false,false,false,false -> FileMode.OpenOrCreate
+        | false,false,false,true -> FileMode.Truncate
+        | false,false,true,true -> FileMode.OpenOrCreate
+        | false,true,false,false -> FileMode.Append
+        | _ -> invalidArg "flags" "invalid mode" 
+    let share = FileShare.Read 
+    let bufferSize = 0x1000 
+#if FX_NO_NONBLOCK_IO
+    let stream = (new FileStream(s,mode,access,share,bufferSize)) 
+#else
+    let allowAsync = listContains Open_nonblock flags 
+    let stream = (new FileStream(s,mode,access,share,bufferSize,allowAsync)) 
+#endif
+    match listContains Open_binary flags, listContains Open_text flags with 
+    | true,true -> invalidArg "flags" "mixed text/binary flags"
+    | true,false -> (new OutChannelImpl(stream_to_BinaryWriter stream ) :> out_channel)
+    | false,_ ->
+        let encoding = List.tryPick (function Open_encoding e -> Some(e) | _ -> None) flags 
+        let encoding = match encoding with None -> defaultEncoding | Some e -> e 
+        OutChannel.of_Stream encoding (stream :> Stream)
+        
+let open_out (s:string) = open_out_gen [Open_text; Open_wronly; Open_creat] 777 s
+
+// NOTE: equiv to
+//       new BinaryWriter(new FileStream(s,FileMode.OpenOrCreate,FileAccess.Write,FileShare.Read ,0x1000,false)) 
+let open_out_bin (s:string) = open_out_gen [Open_binary; Open_wronly; Open_creat] 777 s
+
+
+let flush (os:out_channel) = 
+    match !!os with 
+    | TextW tw   -> (tw()).Flush() // the default method does not flush, is it overriden for the console? 
+    | BinaryW bw -> bw.Flush()
+    | StreamW sw -> sw.Flush()
+
+let close_out (os:out_channel) = 
+    match !!os with 
+    | TextW tw -> (tw()).Close()
+    | BinaryW bw -> bw.Close()
+    | StreamW sw -> sw.Close()
+
+let prim_output_newline (os:out_channel) = 
+    match !!os with 
+    | TextW tw -> (tw()).WriteLine()
+    | BinaryW _ -> invalidArg "os" "the channel is a binary channel"
+    | StreamW sw -> sw.WriteLine()
+
+let output_string (os:out_channel) (s:string) = 
+    match !!os with 
+    | TextW tw -> (tw()).Write(s)
+    | BinaryW bw -> 
+         // Write using a char array - writing a string writes it length-prefixed! 
+         bw.Write (Array.init s.Length (fun i -> s.[i]) )
+    | StreamW sw -> sw.Write(s)
+
+let prim_output_int (os:out_channel) (s:int) = 
+    match !!os with 
+    | TextW tw -> (tw()).Write(s)
+    | BinaryW _ -> invalidArg "os" "the channel is a binary channel"
+    | StreamW sw -> sw.Write(s)
+
+let prim_output_float (os:out_channel) (s:float) = 
+    match !!os with 
+    | TextW tw -> (tw()).Write(s)
+    | BinaryW _ -> invalidArg "os" "the channel is a binary channel"
+    | StreamW sw -> sw.Write(s)
+
+let output_char (os:out_channel) (c:char) = 
+    match !!os with 
+    | TextW tw -> 
+        (tw()).Write(c)
+    | BinaryW bw -> 
+        if int c > 255 then invalidArg "c" "unicode characters of value > 255 may not be written to binary channels"
+        bw.Write(byte c)
+    | StreamW sw -> 
+        sw.Write(c)
+
+let output_chars (os:out_channel) (c:char[]) start len  = 
+    match !!os with 
+    | TextW tw -> (tw()).Write(c,start,len)
+    | BinaryW bw -> bw.Write(c,start,len)
+    | StreamW sw -> sw.Write(c,start,len)
+
+let seek_out (os:out_channel) (n:int) = 
+    match !!os with 
+    | StreamW sw -> 
+        sw.Flush();   
+        (OutChannel.to_Stream os).Seek(int64 n,SeekOrigin.Begin) |> ignore
+    | TextW _ ->
+        (OutChannel.to_Stream os).Seek(int64 n,SeekOrigin.Begin) |> ignore
+    | BinaryW bw -> 
+        bw.Flush();
+        bw.Seek(n,SeekOrigin.Begin) |> ignore
+
+let pos_out (os:out_channel) = flush os; int32 ((OutChannel.to_Stream os).Position)
+let out_channel_length (os:out_channel) = flush os; int32 ((OutChannel.to_Stream os).Length)
+
+let output (os:out_channel) (buf: byte[]) (x:int) (len: int) = 
+    match !!os with 
+    | BinaryW bw -> bw.Write(buf,x,len)
+    | TextW _ | StreamW _ -> 
+        output_string os (defaultEncoding.GetString(buf,x,len))
+
+let output_byte (os:out_channel) (x:int) = 
+    match !!os with 
+    | BinaryW bw -> bw.Write(byte (x % 256))
+    | TextW _  | StreamW _ -> output_char os (char (x % 256))
+
+let output_binary_int (os:out_channel) (x:int) = 
+    match !!os with 
+    | BinaryW bw -> bw.Write x
+    | _ -> failwith "output_binary_int: not a binary stream"
+
+let set_binary_mode_out (os:out_channel) b = 
+    match !!os with 
+    | StreamW _ when not b -> ()
+    | BinaryW _ when b -> ()
+    | BinaryW bw -> 
+            os <--  stream_to_StreamWriter defaultEncoding (OutChannel.to_Stream os)
+    | StreamW bw -> os <-- stream_to_BinaryWriter (OutChannel.to_Stream os)
+    | TextW _ when b -> failwith "cannot set this stream to binary mode"
+    | TextW _ -> ()
+
+let print_int (x:int)        = prim_output_int stdout x
+let print_float (x:float)    = prim_output_float stdout x
+let print_string (x:string)  = output_string stdout x
+let print_newline ()         = prim_output_newline stdout
+let print_endline (x:string) = print_string x; print_newline ()
+let print_char (c:char)      = output_char stdout c
+
+let prerr_int (x:int)        = prim_output_int stderr x
+let prerr_float (x:float)    = prim_output_float stderr x
+let prerr_string (x:string)  = output_string stderr x
+let prerr_newline ()         = prim_output_newline stderr
+let prerr_endline (x:string) = prerr_string x; prerr_newline ()
+let prerr_char (c:char)      = output_char stderr c
+
+#if FX_NO_BINARY_SERIALIZATION
+#else
+let output_value (os:out_channel) (x: 'a) = 
+    let formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter() 
+    formatter.Serialize(OutChannel.to_Stream os,box [x]);
+    flush os
+#endif
+
+let (!!!) (c : in_channel) = 
+    match c with 
+    | :? InChannelImpl as c -> c.Reader
+    | :? StreamReader as sr -> StreamR sr
+    | _ -> TextR (fun () -> c)
+let (<---) (c: in_channel) r = 
+    match c with 
+    | :? InChannelImpl as c -> c.Reader<- r
+    | _ -> failwith "the mode may only be adjusted channels created with one of the Pervasives.open_* functions"
+
+let mk_BinaryReader (s: Stream) = BinaryR (new BinaryReader(s))
+let mk_StreamReader e (s: Stream) = StreamR (new StreamReader(s, e,false))
+module InChannel = 
+
+    let of_Stream (e:Encoding) (s: Stream) =   new InChannelImpl(mk_StreamReader e s) :> in_channel
+    let of_StreamReader w =
+      new InChannelImpl (StreamR w) :> in_channel
+
+    let of_BinaryReader r =
+      new InChannelImpl (BinaryR r) :> in_channel
+      
+    let of_TextReader (r: TextReader) =
+      let absr = 
+        match r with 
+        | :? StreamReader as sr -> StreamR sr
+        | tr -> TextR (fun () -> tr) 
+      new InChannelImpl(absr) :> in_channel
+
+    let to_StreamReader (c:in_channel) =
+      match !!!c with 
+      | StreamR sr -> sr
+      | _ -> failwith "to_StreamReader: cannot access a stream reader for this channel"
+      
+    let to_BinaryReader (is:in_channel) =
+      match !!!is with 
+      | BinaryR sr -> sr
+      | _ -> failwith "to_BinaryReader: cannot access a binary reader for this channel"
+      
+    let to_TextReader (is:in_channel) =
+      match !!!is with 
+      | TextR tr ->tr()
+      | _ -> is
+      
+    let to_Stream (is:in_channel) =
+      match !!!is with 
+      | BinaryR bw -> bw.BaseStream
+      | StreamR sw -> sw.BaseStream
+      | _ -> failwith "cannot seek, set position or calculate length of this stream"
+
+// permissions are ignored 
+let open_in_gen flags (_perm:int) (s:string) = 
+    let access = 
+      match listContains Open_rdonly flags, listContains Open_wronly flags with
+      | true, true -> invalidArg "flags" "invalid access"
+      | true, false -> FileAccess.Read 
+      | false, true -> invalidArg "flags" "invalid access for reading"
+      | false, false -> FileAccess.ReadWrite 
+    let mode = 
+      match listContains Open_excl flags,listContains Open_append flags, listContains Open_creat flags, listContains Open_trunc flags with
+      | false,false,false,false -> FileMode.Open
+      | _ -> invalidArg "flags" "invalid mode for reading" 
+    let share = FileShare.Read 
+    let bufferSize = 0x1000 
+#if FX_NO_NONBLOCK_IO
+    let stream = new FileStream(s,mode,access,share,bufferSize) :> Stream 
+#else
+    let allowAsync = listContains Open_nonblock flags 
+    let stream = new FileStream(s,mode,access,share,bufferSize,allowAsync) :> Stream 
+#endif
+    match listContains Open_binary flags, listContains Open_text flags with 
+    | true,true -> invalidArg "flags" "mixed text/binary flags specified"
+    | true,false -> new InChannelImpl (mk_BinaryReader stream ) :> in_channel
+    | false,_ ->
+        let encoding = List.tryPick (function Open_encoding e -> Some(e) | _ -> None) flags 
+        let encoding = match encoding with None -> defaultEncoding | Some e -> e 
+        InChannel.of_Stream encoding stream
+  
+let open_in_encoded (e:Encoding) (s:string) = open_in_gen [Open_text; Open_rdonly; Open_encoding e] 777 s
+let open_in (s:string) = open_in_gen [Open_text; Open_rdonly] 777 s
+
+// NOTE: equivalent to
+//     new BinaryReader(new FileStream(s,FileMode.Open,FileAccess.Read,FileShare.Read,0x1000,false))
+let open_in_bin (s:string) = open_in_gen [Open_binary; Open_rdonly] 777 s
+
+let close_in (is:in_channel) = 
+  match !!!is with 
+  | TextR tw -> (tw()).Close()
+  | BinaryR bw -> bw.Close()
+  | StreamR sw -> sw.Close()
+
+let input_line (is:in_channel) = 
+    match !!!is with 
+    | BinaryR _ -> failwith "input_line: binary mode"
+    | TextR tw -> match tw().ReadLine() with null -> raise End_of_file | res -> res
+    | StreamR sw -> match sw.ReadLine() with null -> raise End_of_file | res -> res
+
+let input_byte (is:in_channel) = 
+    match !!!is with 
+    | BinaryR bw ->  int (bw.ReadByte())
+    | TextR tr -> let b = (tr()).Read() in if b = -1 then raise End_of_file else int (byte b)
+    | StreamR sr -> let b = sr.Read() in if b = -1 then raise End_of_file else int (byte b)
+
+let prim_peek (is:in_channel) = 
+    match !!!is with 
+    | BinaryR bw ->  bw.PeekChar()
+    | TextR tr -> (tr()).Peek()
+    | StreamR sr -> sr.Peek()
+
+let prim_input_char (is:in_channel) = 
+    match !!!is with 
+    | BinaryR bw ->  (try int(bw.ReadByte()) with End_of_file -> -1)
+    | TextR tr -> (tr()).Read() 
+    | StreamR sr -> sr.Read()
+
+let input_char (is:in_channel) = 
+    match !!!is with 
+    | BinaryR _ ->  char_of_int (input_byte is)
+    | TextR tr -> let b = (tr()).Read() in if b = -1 then raise End_of_file else (char b)
+    | StreamR sr -> let b = sr.Read() in if b = -1 then raise End_of_file else (char b)
+
+let input_chars (is:in_channel) (buf:char[]) start len = 
+    match !!!is with 
+    | BinaryR bw ->  bw.Read(buf,start,len)
+    | TextR trf -> let tr = trf() in tr.Read(buf,start,len) 
+    | StreamR sr -> sr.Read(buf,start,len) 
+
+let seek_in (is:in_channel) (n:int) = 
+    begin match !!!is with 
+    | StreamR sw -> sw.DiscardBufferedData() 
+    | TextR _ | BinaryR _ -> ()
+    end;
+    ignore ((InChannel.to_Stream is).Seek(int64 n,SeekOrigin.Begin))
+
+let pos_in (is:in_channel)  = int32 ((InChannel.to_Stream is).Position)
+let in_channel_length (is:in_channel)  = int32 ((InChannel.to_Stream is).Length)
+
+let input_bytes_from_TextReader (tr : TextReader) (enc : Encoding) (buf: byte[]) (x:int) (len: int) = 
+    /// Don't read too many characters!
+    let lenc = (len * 99) / enc.GetMaxByteCount(100) 
+    let charbuf : char[] = Array.zeroCreate lenc 
+    let nRead = tr.Read(charbuf,x,lenc) 
+    let count = enc.GetBytes(charbuf,x,nRead,buf,x) 
+    count
+
+let input (is: in_channel) (buf: byte[]) (x:int) (len: int) = 
+    match !!!is with 
+    | StreamR _  ->  (InChannel.to_Stream is).Read(buf,x,len)
+    | TextR trf   -> 
+        input_bytes_from_TextReader (trf()) defaultEncoding buf x len  
+    | BinaryR br -> br.Read(buf,x,len)
+
+let really_input (is:in_channel) (buf: byte[]) (x:int) (len: int) = 
+    let mutable n = 0 
+    let mutable i = 1 
+    while (if i > 0 then n < len else false) do 
+        i <- input is buf (x+n) (len-n);
+        n <- n + i
+    
+let unsafe_really_input (is:in_channel) buf x len = really_input is buf x len
+
+let input_binary_int (is:in_channel) = 
+    match !!!is with 
+    | BinaryR bw -> bw.ReadInt32()
+    | _ -> failwith "input_binary_int: not a binary stream"
+
+let set_binary_mode_in (is:in_channel) b = 
+    match !!!is with 
+    | StreamR _ when not b -> ()
+    | BinaryR _ when b -> ()
+    | BinaryR bw -> is <---  mk_StreamReader defaultEncoding (InChannel.to_Stream is)
+    | StreamR bw -> is <--- mk_BinaryReader (InChannel.to_Stream is)
+    | TextR _ when b -> failwith "set_binary_mode_in: cannot set this stream to binary mode"
+    | TextR _ -> ()
+
+let read_line ()  = stdout.Flush(); input_line stdin
+let read_int ()   = int_of_string (read_line())
+let read_float () = float_of_string (read_line ())
+
+#if FX_NO_BINARY_SERIALIZATION
+#else
+let input_value (is:in_channel) = 
+    let formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter() 
+    let res = formatter.Deserialize(InChannel.to_Stream is) 
+    match ((unbox res) : 'a list) with 
+    | [x] -> x
+    | _ -> failwith "input_value: expected one item"
+#endif
+
+type InChannelImpl with 
+    override x.Dispose(deep:bool) = if deep then close_in (x :> in_channel)
+    override x.Peek() = prim_peek (x :> in_channel) 
+    override x.Read() = prim_input_char (x :> in_channel) 
+    override x.Read((buffer:char[]),(index:int),(count:int)) = input_chars (x :> in_channel) buffer index count
+    
+
+type OutChannelImpl with 
+    override x.Dispose(deep:bool) = if deep then close_out (x :> out_channel)
+    override x.Encoding = x.TextWriter.Encoding
+    override x.FormatProvider = x.TextWriter.FormatProvider
+    override x.NewLine = x.TextWriter.NewLine
+    override x.Write(s:string) = output_string (x :> out_channel) s
+    override x.Write(c:char) = output_char (x :> out_channel) c
+    override x.Write(c:char[]) = output_chars (x :> out_channel) c 0 c.Length
+    override x.Write((c:char[]),(index:int),(count:int)) = output_chars (x :> out_channel) c index count
+    
+type ('a,'b,'c,'d) format4 = Microsoft.FSharp.Core.Format<'a,'b,'c,'d>
+type ('a,'b,'c) format = Microsoft.FSharp.Core.Format<'a,'b,'c,'c>
+
+exception Exit
+
+
+module Pervasives = 
+
+    let hash  (x: 'a) = LanguagePrimitives.GenericHash x
+
+#if FX_NO_EXIT
+#else
+    let exit (n:int) = Operators.exit n
+#endif
+
+    let incr x = x.contents <- x.contents + 1
+    let decr x = x.contents <- x.contents - 1
+
+    let (@) l1 l2 = l1 @ l2
+    // NOTE: inline to call site since LanguagePrimitives.<funs> have static type optimisation 
+    let (=)     (x:'a) (y:'a) = Operators.(=) x y
+    let (<>)    (x:'a) (y:'a) = Operators.(<>) x y 
+    let (<)     (x:'a) (y:'a) = Operators.(<) x y
+    let (>)     (x:'a) (y:'a) = Operators.(>) x y
+    let (<=)    (x:'a) (y:'a) = Operators.(<=) x y
+    let (>=)    (x:'a) (y:'a) = Operators.(>=) x y
+    let min     (x:'a) (y:'a) = Operators.min x y
+    let max     (x:'a) (y:'a) = Operators.max x y
+    let compare (x:'a) (y:'a) = LanguagePrimitives.GenericComparison x y
+
+    let (~+) x = Operators.(~+) x
+    //  inline (~-) x = LanguagePrimitives.(~-) x 
+
+    let (+) (x:int) (y:int)   = Operators.(+) x y
+    let (-) (x:int) (y:int)   = Operators.(-) x y
+    let ( * ) (x:int) (y:int) = Operators.( * ) x y
+    let (/) (x:int) (y:int)   = Operators.(/) x y
+    let not (b:bool) = Operators.not b
+    type 'a ref = Microsoft.FSharp.Core.Ref<'a>
+    type 'a option = Microsoft.FSharp.Core.Option<'a>
+    type 'a list = Microsoft.FSharp.Collections.List<'a>
+    type exn = System.Exception
+    let raise (e:exn) = Operators.raise e
+    let failwith s = raise (Failure s)
+    let fst (x,_y) = x
+    let snd (_x,y) = y
+
+    let ref x = { contents=x }
+    let (!) x = x.contents
+    let (:=) x y = x.contents <- y
+
+    let float (x:int) =  Operators.float x
+    let float32 (n:int) =  Operators.float32 n
+    let abs (x:int) = Operators.abs x
+    let ignore _x = ()
+    let invalid_arg s = raise (System.ArgumentException(s))
+    let (^) (x:string) (y:string) = System.String.Concat(x,y)
+    let sqrt      (x:float)           = Operators.sqrt x
+    let exp       (x:float)           = Operators.exp x
+    let log       (x:float)           = Operators.log x
+    let log10     (x:float)           = Operators.log10 x
+    let cos       (x:float)           = Operators.cos x
+    let sin       (x:float)           = Operators.sin x
+    let tan       (x:float)           = Operators.tan x
+    let acos      (x:float)           = Operators.acos x
+    let asin      (x:float)           = Operators.asin x
+    let atan      (x:float)           = Operators.atan x
+    let atan2     (x:float) (y:float) = Operators.atan2 x y
+    let cosh      (x:float)           = Operators.cosh x
+    let sinh      (x:float)           = Operators.sinh x
+    let tanh      (x:float)           = Operators.tanh x
+    let ceil      (x:float)           = Operators.ceil x
+    let floor     (x:float)           = Operators.floor x
+
+    let ( ** ) (x:float) (y:float) = Operators.( ** ) x y
+    let truncate (x:float) = Operators.int32 x
+    let nan          = System.Double.NaN 
+    let infinity     = System.Double.PositiveInfinity
diff --git a/src/FSharp.PowerPack.Compatibility/pervasives.fsi b/src/FSharp.PowerPack.Compatibility/pervasives.fsi
new file mode 100755
index 0000000..6c8fbf8
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/pervasives.fsi
@@ -0,0 +1,795 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008. The interface to the module 
+// is similar to that found in versions of other ML implementations, 
+// but is not an exact match. The type signatures in this interface
+// are an edited version of those generated automatically by running 
+// "bin\fsc.exe -i" on the implementation file.
+//===========================================================================
+///Pervasives: Additional OCaml-compatible bindings 
+[<CompilerMessage("This module is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<AutoOpen>]
+module Microsoft.FSharp.Compatibility.OCaml.Pervasives
+
+#nowarn "62" // compatibility warnings
+#nowarn "35"  // 'deprecated' warning about redefining '<' etc.
+#nowarn "86"  // 'deprecated' warning about redefining '<' etc.
+
+
+open System
+open System.IO
+open System.Collections.Generic
+
+#if COMPILER
+#endif
+ 
+//--------------------------------------------------------------------------
+//Pointer (physical) equality and hashing.
+
+///Reference/physical equality. 
+///True if boxed versions of the inputs are reference-equal, OR if
+///both are value types and the implementation of Object.Equals for the type
+///of the first argument returns true on the boxed versions of the inputs. 
+///
+///In normal use on reference types or non-mutable value types this function 
+///has the following properties:
+///   - returns 'true' for two F# values where mutation of data
+///     in mutable fields of one affects mutation of data in the other
+///   - will return 'true' if (=) returns true
+///   - hashq will return equal hashes if (==) returns 'true'
+///
+///The use on mutable value types is not recommended.
+[<CompilerMessage("This construct is for ML compatibility. Using the physical equality operator '==' is not recommended except in cross-compiled code. Consider using generic structural equality 'x = y' or 'LanguagePrimitives.PhysicalEquality x y'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline (==): 'T -> 'T -> bool when 'T : not struct
+
+/// Negation of the '==' operator, see also Obj.eq
+[<CompilerMessage("This construct is for ML compatibility. Using the physical inequality operator '!=' is not recommended except in cross-compiled code. Consider using generic structual inequality 'x <> y' or 'not(LanguagePrimitives.PhysicalEquality x y)'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline (!=): 'T -> 'T -> bool when 'T : not struct
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x % y' instead of 'x mod y'. The precedence of these operators differs, so you may need to add parentheses. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline (mod): int -> int -> int 
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x &&& y' instead of 'x land y'. The precedence of these operators differs, so you may need to add parentheses. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+
+val inline (land): int -> int -> int 
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x ||| y' instead of 'x lor y'. The precedence of these operators differs, so you may need to add parentheses. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline (lor) : int -> int -> int 
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x ^^^ y' instead of 'x lxor y'. The precedence of these operators differs, so you may need to add parentheses. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline (lxor): int -> int -> int
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator '~~~x' instead of 'lnot x'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline lnot  : int -> int
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x <<< y' instead of 'x lsl y'. The precedence of these operators differs, so you may need to add parentheses. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline (lsl): int -> int -> int
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x >>> y' on an unsigned type instead of 'x lsr y'. The precedence of these operators differs, so you may need to add parentheses. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline (lsr): int -> int -> int
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x >>> y' instead of 'x asr y'. The precedence of these operators differs, so you may need to add parentheses. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline (asr): int -> int -> int
+
+/// 1D Array element get-accessor ('getter')
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'arr.[idx]' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline ( .() ) : 'T array -> int -> 'T
+
+/// 1D Array element set-accessor ('setter')
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'arr.[idx] <- v' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val inline ( .()<- ) : 'T array -> int -> 'T -> unit
+
+//--------------------------------------------------------------------------
+//Integer-specific arithmetic
+
+/// n-1 (no overflow checking)
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val pred: int -> int
+
+/// n+1 (no overflow checking)
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val succ: int -> int
+
+/// The lowest representable value in the 'int' type
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Int32.MinValue' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val min_int : int
+
+/// The highest representable value in the 'int' type
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Int32.MaxValue' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val max_int : int
+
+/// Negation on integers of the 'int' type
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator '-x' instead of 'int_neg x'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val int_neg : int -> int
+
+//--------------------------------------------------------------------------
+//Exceptions
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.IO.EndOfStreamException instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+exception End_of_file = System.IO.EndOfStreamException
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.OutOfMemoryException instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+exception Out_of_memory = System.OutOfMemoryException
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.DivideByZeroException instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+exception Division_by_zero = System.DivideByZeroException
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.StackOverflowException instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+exception Stack_overflow = System.StackOverflowException 
+
+[<CompilerMessage("This construct is for ML compatibility. This is a synonym for 'System.Collections.Generic.KeyNotFoundException'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val Not_found<'T> : exn
+
+[<CompilerMessage("This construct is for ML compatibility. This is a synonym for 'System.Collections.Generic.KeyNotFoundException'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val (|Not_found|_|) : exn -> unit option
+
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+exception Exit 
+
+///  Non-exhaustive match failures will raise Match failures
+/// A future release of F# may map this exception to a corresponding .NET exception.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'MatchFailureException' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+exception Match_failure = Microsoft.FSharp.Core.MatchFailureException
+
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+exception Undefined 
+
+/// The exception thrown by 'assert' failures.
+/// A future release of F# may map this exception to a corresponding .NET exception.
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+exception Assert_failure of string * int * int 
+
+/// The exception thrown by <c>invalid_arg</c> and misues of F# library functions
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.ArgumentException' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val Invalid_argument : string -> exn
+
+[<CompilerMessage("This construct is for ML compatibility. Consider matching against 'System.ArgumentException' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val (|Invalid_argument|_|) : exn -> string option
+
+//--------------------------------------------------------------------------
+//Floating point.
+//
+//The following operators only manipulate 'float64' numbers. The operators  '+' etc. may also be used.
+
+/// This value is present primarily for compatibility with other versions of ML
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x * y' instead of 'x *. y'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val ( *. ): float -> float -> float
+
+/// This value is present primarily for compatibility with other versions of ML. In F#
+/// the overloaded operators may be used.
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x + y' instead of 'x +. y'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val ( +. ): float -> float -> float
+
+/// This value is present primarily for compatibility with other versions of ML. In F#
+/// the overloaded operators may be used.
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x - y' instead of 'x -. y'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val ( -. ): float -> float -> float
+
+/// This value is present primarily for compatibility with other versions of ML. In F#
+/// the overloaded operators may be used.
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator '-x' instead of '-. x'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val ( ~-. ): float -> float
+
+/// This value is present primarily for compatibility with other versions of ML. In F#
+/// the overloaded operators may be used.
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator '+x' instead of '+. x'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val ( ~+. ): float -> float
+
+/// This value is present primarily for compatibility with other versions of ML. In F#
+/// the overloaded operators may be used.
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'x / y' instead of 'x /. y'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val ( /. ): float -> float -> float
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the overloaded F# library function 'abs' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val abs_float: float -> float
+
+/// This value is present primarily for compatibility with other versions of ML
+/// The highest representable positive value in the 'float' type
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Double.MaxValue' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val max_float: float
+
+/// This value is present primarily for compatibility with other versions of ML
+/// The lowest non-denormalized positive IEEE64 float
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val min_float: float
+
+/// This value is present primarily for compatibility with other versions of ML
+/// The smallest value that when added to 1.0 gives a different value to 1.0
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val epsilon_float: float
+
+/// This value is present primarily for compatibility with other versions of ML
+[<CompilerMessage("This construct is for ML compatibility. Consider using the '%' operator instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val mod_float: float -> float -> float
+
+/// This value is present primarily for compatibility with other versions of ML
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val modf: float -> float * float
+
+/// This value is present primarily for compatibility with other versions of ML
+[<CompilerMessage("This construct is for ML compatibility. Consider using '-infinity' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val neg_infinity: float
+
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val ldexp: float -> int -> float
+
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+type fpclass = 
+  | FP_normal
+  | FP_zero
+  | FP_infinite
+  | FP_nan
+
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val classify_float: float -> fpclass
+
+//--------------------------------------------------------------------------
+//Common conversions. See also conversions such as
+//Float32.to_int etc.
+
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val bool_of_string: string -> bool
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'char' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val char_of_int: int -> char
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'int' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val int_of_char: char -> int
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'int' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val int_of_string: string -> int
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'int' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val int_of_float: float -> int
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'string' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val string_of_bool: bool -> string
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'string' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val string_of_float: float -> string
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the operator 'string' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val string_of_int: int -> string
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the overloaded conversion function 'float' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val float_of_int: int -> float
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using the overloaded conversion function 'float' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val float_of_string: string -> float
+
+
+//--------------------------------------------------------------------------
+//I/O
+//
+//Caveat: These functions do not have precisely the same behaviour as 
+//corresponding functions in other ML implementations, e.g. OCaml. 
+//For example they may raise .NET exceptions rather than Sys_error.
+
+  
+/// This type is present primarily for compatibility with other versions of ML. When
+/// not cross-compiling we recommend using the .NET I/O libraries
+[<CompilerMessage("This construct is for ML compatibility. For advanced I/O consider using the System.IO namespace. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+type open_flag = 
+  | Open_rdonly
+  | Open_wronly
+  | Open_append
+  | Open_creat
+  | Open_trunc
+  | Open_excl
+  | Open_binary
+  | Open_text
+#if FX_NO_NONBLOCK_IO
+#else
+  | Open_nonblock
+#endif
+  | Open_encoding of System.Text.Encoding
+
+//--------------------------------------------------------------------------
+
+
+/// A pseudo-abstraction over binary and textual input channels.
+/// OCaml-compatible channels conflate binary and text IO, and for this reasons their
+/// use from F# is somewhat deprecated (direct use of System.IO StreamReader, TextReader and 
+/// BinaryReader objects is preferred, e.g. see System.IO.File.OpenText). 
+/// Well-written OCaml-compatible code that simply opens either a channel in text or binary 
+/// mode and then does text or binary I/O using the OCaml-compatible functions below
+/// will work, though care must be taken with regard to end-of-line characters (see 
+/// input_char below).
+///
+/// This library pretends that an in_channel is just a System.IO.TextReader. Channel values
+/// created using open_in_bin maintain a private System.IO.BinaryReader, which will be used whenever
+/// you do I/O using this channel. 
+///
+/// InChannel.of_BinaryReader and InChannel.of_StreamReader allow you to build input 
+/// channels out of the corresponding .NET abstractions.
+[<CompilerMessage("This construct is for ML compatibility. Consider using one of the types System.IO.TextReader, System.IO.BinaryReader or System.IO.StreamReader instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+type in_channel = System.IO.TextReader
+    
+
+/// Open the given file to read. 
+///
+///In the absence of an explicit encoding (e.g. using Open_encoding) open_in
+///uses the default text encoding (System.Text.Encoding.Default). If you want to read a file
+///regardless of encoding then you should use binary modes. Note that .NET's 
+///"new StreamReader" function defaults to use a utf8 encoding, and also attempts
+///to determine an automatic encoding by looking for "byteorder-marks" at the head
+///of a text file. This function does not do this.
+///
+/// No CR-LF translation is done on input.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.IO.File.OpenText(path)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val open_in: path:string -> in_channel
+
+/// Open the given file to read in binary-mode 
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'new System.IO.BinaryReader(System.IO.File.OpenRead(path))' and changing your type to be a BinaryReader instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val open_in_bin: path:string -> in_channel
+
+/// Open the given file in the mode specified by the given flags
+[<CompilerMessage("This construct is for ML compatibility. For advanced I/O consider using the System.IO namespace instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val open_in_gen: flags: open_flag list -> int -> path:string -> in_channel
+
+/// Close the channel
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.Close()' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val close_in: channel:in_channel -> unit
+
+/// Return the length of the input channel
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.BaseStream.Length' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val in_channel_length: channel:in_channel -> int
+
+/// Attempt to input the given number of bytes from the channel, writing them into the
+/// buffer at the given start position. Does not block if the bytes are not available.
+///
+/// The use of this function with a channel performing byte-to-character translation (e.g. one
+/// created with open_in, open_in_utf8 or open_in_encoded, or one 
+/// or built from a StreamReader or TextReader) is not recommended.
+/// Instead, open the channel using open_in_bin or InChannel.of_BinaryReader.
+///
+/// If used with a StreamReader channel, i.e. one created using 
+/// open_in, open_in_utf8 or open_in_encoded, or one 
+/// or built from a StreamReader, this function reads bytes directly from the underlying
+/// BaseStream. This may not be appropriate if any other input techniques are being
+/// used on the channel.
+///
+/// If used with a TextReader channel (e.g. stdin), this function reads characters from the
+/// stream and then fills some of the byte array with the decoding of these into 
+/// bytes, where the decoding is performed using the System.Text.Encoding.Default encoding
+///
+/// Raise End_of_file (= System.IO.EndOfStreamException) if end of file reached.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.Read(buffer,index,count)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val input: channel:in_channel -> buffer:byte[] -> index:int -> count:int -> int
+
+/// Attempt to input characters from a channel. Does not block if inpout is not available.
+/// Raise End_of_file (= System.IO.EndOfStreamException) if end of file reached.
+///
+/// No CRLF translation is done on input, even in text mode. That is, if an input file
+/// has '\r\n' (CRLF) line terminators both characters will be seen in the input.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.Read(buffer,index,count)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val input_chars: channel:in_channel -> buffer:char[] -> index:int -> count:int -> int
+
+/// Input a binary integer from a binary channel. Compatible with output_binary_int.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.ReadInt32()' on a BinaryReader instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val input_binary_int: channel:in_channel -> int
+
+/// Input a single byte. 
+/// For text channels this only accepts characters with a UTF16 encoding that fits in a byte, e.g. ASCII.
+/// Raise End_of_file (= System.IO.EndOfStreamException) if end of file reached.
+[<CompilerMessage("This construct is for ML compatibility. Consider using the 'Read()' method on a 'BinaryReader' instead, which returns -1 if no byte is available. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val input_byte: channel:in_channel -> int
+
+/// Input a single character. Raise End_of_file (= System.IO.EndOfStreamException) if end of file reached.
+[<CompilerMessage("This construct is for ML compatibility. Consider using the 'channel.Read()' method instead, which returns -1 if no character is available. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val input_char: channel:in_channel -> char
+
+/// Input a single line. Raise End_of_file (= System.IO.EndOfStreamException) if end of file reached.
+[<CompilerMessage("This construct is for ML compatibility. Consider using the 'channel.ReadLine()' method instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val input_line: channel:in_channel -> string
+
+#if FX_NO_BINARY_SERIALIZATION
+#else
+/// Input a single serialized value from a binary stream. Raise End_of_file (= System.IO.EndOfStreamException) if end of file reached.
+[<CompilerMessage("This construct is for ML compatibility. Consider deserializing using an object of type 'System.Runtime.Serialization.Formatters.Binary.BinaryFormatter' method instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val input_value: channel:in_channel -> 'T
+#endif
+/// Report the current position in the input channel
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.BaseStream.Position' property instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val pos_in: channel:in_channel -> int
+
+/// Reads bytes from the channel. Blocks if the bytes are not available.
+/// See 'input' for treatment of text channels.
+/// Raise End_of_file (= System.IO.EndOfStreamException) if end of file reached.
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val really_input: channel:in_channel -> buffer:byte[] -> index:int -> count:int -> unit
+
+/// Reads bytes from the channel. Blocks if the bytes are not available.
+/// For text channels this only accepts UTF-16 bytes with an encoding less than 256.
+/// Raise End_of_file (= System.IO.EndOfStreamException) if end of file reached.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.BaseStream.Seek' method instead, or using a 'System.IO.BinaryReader' and related types for binary I/O. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val seek_in: channel:in_channel -> int -> unit
+
+/// Set the binary mode to true or false. If the binary mode is changed from "true" to 
+/// "false" then a StreamReader is created to read the binary stream. The StreamReader uses 
+/// the default text encoding System.Text.Encoding.Default
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.IO.BinaryReader' and related types for binary I/O. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val set_binary_mode_in: channel:in_channel -> bool -> unit
+
+[<Obsolete("For F# code unsafe_really_input is identical to really_input")>]
+val unsafe_really_input: channel:in_channel -> byte[] -> int -> int -> unit
+
+//--------------------------------------------------------------------------
+//Output channels (out_channel). 
+
+/// An pseudo-abstraction over binary and textual output channels.
+/// OCaml-compatible channels conflate binary and text IO, and for this reasons their
+/// use from F# is somewhat deprecated The direct use of System.IO StreamWriter, TextWriter and 
+/// BinaryWriter objects is preferred, e.g. see System.IO.File.CreateText). Well-written OCaml code 
+/// that simply opens either a channel in text or binary mode and then does text 
+/// or binary I/O using the OCaml functions will work, though care must 
+/// be taken with regard to end-of-line characters (see output_char below).
+///
+/// This library pretends that an out_channel is just a System.IO.TextWriter. Channels
+/// created using open_out_bin maintain a private System.IO.BinaryWriter, which will be used whenever
+/// do I/O using this channel. 
+[<CompilerMessage("This construct is for ML compatibility. Consider using one of the types 'System.IO.TextWriter', 'System.IO.StreamWriter' or 'System.IO.BinaryWriter' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+type out_channel  = System.IO.TextWriter
+
+/// Open the given file to write in text-mode using the
+/// System.Text.Encoding.Default encoding
+///
+/// See output_char for a description of CR-LF translation
+/// done on output.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.IO.File.CreateText(path)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val open_out: path:string -> out_channel
+
+/// Open the given file to write in binary-mode 
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'new System.IO.BinaryWriter(System.IO.File.Create(path))' and changing your type to be a BinaryWriter instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val open_out_bin: path:string -> out_channel
+
+/// Open the given file to write in the mode according to the specified flags
+[<CompilerMessage("This construct is for ML compatibility. For advanced I/O consider using the System.IO namespace. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val open_out_gen: open_flag list -> int -> path:string -> out_channel
+
+/// Close the given output channel
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.Close()' instead, or create the channel via a 'use' binding to ensure automatic cleanup. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val close_out: channel:out_channel -> unit
+
+/// Return the length of the output channel. 
+/// Raise an exception if not an app
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.BaseStream.Length' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val out_channel_length: channel:out_channel -> int
+
+/// Write the given range of bytes to the output channel. 
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.Write(buffer,index,count)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val output: channel:out_channel -> bytes:byte[] -> index:int -> count:int -> unit
+
+/// Write the given integer to the output channel in binary format.
+/// Only valid on binary channels.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.Write(int)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val output_binary_int: channel:out_channel -> int:int -> unit
+
+/// Write the given byte to the output channel. No CRLF translation is
+/// performed.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.Write(byte)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val output_byte: channel:out_channel -> byte:int -> unit
+
+/// Write the given Unicode character to the output channel. 
+///
+/// If the output channel is a binary stream and the UTF-16 value of the Unicode character is greater
+/// than 255 then ArgumentException is thrown.
+///
+/// No CRLF translation is done on output. That is, if the output character is
+/// '\n' (LF) characters they will not be written as '\r\n' (CRLF) characters, regardless
+/// of whether the underlying operating system or output stream uses CRLF as the default
+/// line-feed character.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.Write(char)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val output_char: channel:out_channel -> char -> unit
+
+/// Write the given Unicode string to the output channel. See output_char for the treatment of
+/// '\n' characters within the string.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.Write(string)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val output_string: channel:out_channel -> string -> unit
+
+#if FX_NO_BINARY_SERIALIZATION
+#else
+/// Serialize the given value to the output channel.
+[<CompilerMessage("This construct is for ML compatibility. Consider serializing using an object of type 'System.Runtime.Serialization.Formatters.Binary.BinaryFormatter' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val output_value: channel:out_channel -> 'T -> unit
+#endif
+/// Return the current position in the output channel, measured from the
+/// start of the channel. Not valid on all channels.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.BaseStream.Position' on a TextWriter or '.Position' on a Stream instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val pos_out: channel:out_channel -> int
+
+/// Set the current position in the output channel, measured from the
+/// start of the channel.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.BaseStream.Seek' on a TextReader or 'channel.Seek' on a Stream instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val seek_out: channel:out_channel -> int -> unit
+
+/// Set the binary mode. If the binary mode is changed from "true" to 
+/// "false" then a StreamWriter is created to write the binary stream. The StreamWriter uses 
+/// the default text encoding System.Text.Encoding.Default.
+[<CompilerMessage("This construct is for ML compatibility. For advanced I/O consider using the System.IO namespace. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val set_binary_mode_out: channel:out_channel -> bool -> unit
+
+/// Flush all pending output on the channel to the physical
+/// output device.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'channel.Flush()' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val flush: channel:out_channel -> unit
+
+//--------------------------------------------------------------------------
+//Printing data to stdout/stderr
+
+
+/// Print a character to the stderr stream
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.Error.Write(char)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val prerr_char: char -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.Error.WriteLine(string)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val prerr_endline: string -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.Error.Write(double)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val prerr_float: float -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.Error.Write(int)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val prerr_int: int -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.Error.WriteLine()' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val prerr_newline: unit -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.Error.Write(string)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val prerr_string: string -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.Write(char)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val print_char: char -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.WriteLine(string)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val print_endline: string -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.Write(double)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val print_float: float -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.Write(int)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val print_int: int -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.WriteLine()' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val print_newline: unit -> unit
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.Write(string)' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val print_string: string -> unit
+
+//--------------------------------------------------------------------------
+//Reading data from the console.
+
+
+///Read a floating point number from the console.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.ReadLine() |> float' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val read_float: unit -> float
+
+///Read an integer from the console.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.ReadLine() |> int' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val read_int: unit -> int
+
+///Read a line from the console, without the end-of-line character.
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'System.Console.ReadLine()' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val read_line: unit -> string
+
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using Microsoft.FSharp.Core.Format<_,_,_,_> instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+type ('a,'b,'c,'d) format4 = Microsoft.FSharp.Core.Format<'a,'b,'c,'d>
+
+[<CompilerMessage("This construct is for ML compatibility. Consider using Microsoft.FSharp.Core.Format<_,_,_,_> instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+type ('a,'b,'c) format = Microsoft.FSharp.Core.Format<'a,'b,'c,'c>
+
+/// Throw an ArgumentException
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'invalidArg' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val invalid_arg: string -> 'T
+
+/// Throw an <c>KeyNotFoundException</c> exception
+[<CompilerMessage("This construct is for ML compatibility. Consider using 'raise (KeyNotFoundException(message))' instead. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val not_found : unit -> 'T 
+
+
+//--------------------------------------------------------------------------
+// OCaml path-lookup compatibility. All these constructs are in scope already
+// for F# from Microsoft.FSharp.Operators and elsewhere. This module 
+// is Microsoft.FSharp.Compatibility.OCaml.Pervasives.Pervasives and is only included 
+// to resolve references in OCaml code written "compare" etc.
+// We hide these away in the sub-module called "Pervasives" because we don't
+// particularly want normal references such as "compare" to resolve to the 
+// values in Pervasives.
+
+
+[<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+module Pervasives = 
+    //--------------------------------------------------------------------------
+    // Comparison based on F# term structure and/or calls to System.IComparable
+
+    ///Structural less-than comparison
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (<): 'T -> 'T -> bool when 'T : comparison
+
+    ///Structural less-than-or-equal comparison
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (<=): 'T -> 'T -> bool when 'T : comparison
+
+    ///Structural inequality
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (<>): 'T -> 'T -> bool when 'T : equality
+
+    ///Structural equality
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (=): 'T -> 'T -> bool when 'T : equality
+
+    ///Structural greater-than
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (>): 'T -> 'T -> bool when 'T : comparison
+
+    ///Structural greater-than-or-equal
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (>=): 'T -> 'T -> bool when 'T : comparison
+
+    ///Structural comparison
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val compare: 'T -> 'T -> int when 'T : comparison
+
+    ///Maximum based on structural comparison
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val max: 'T -> 'T -> 'T when 'T : comparison
+
+    ///Minimum based on structural comparison
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val min: 'T -> 'T -> 'T when 'T : comparison
+
+    ///The "hash" function is a structural hash function. It is 
+    ///designed to return equal hash values for items that are 
+    ///equal according to the polymorphic equality 
+    ///function Pervasives.(=) (i.e. the standard "=" operator).
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val hash: 'T -> int
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (+)  : int -> int -> int
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (-)  : int -> int -> int
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val ( * ): int -> int -> int
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (/)  : int -> int -> int
+
+    ///Absolute value of the given integer
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val abs : int -> int
+
+    ///Dereference a mutable reference cell
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (!) : 'T ref -> 'T
+
+    ///Assign to a mutable reference cell
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (:=): 'T ref -> 'T -> unit
+
+    ///Create a mutable reference cell
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val ref : 'T -> 'T ref
+
+    /// Throw a 'Failure' exception
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val failwith: string -> 'T
+
+    /// Throw an exception
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val raise: exn -> 'T
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val fst: ('T1 * 'T2) -> 'T1
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val snd: ('T1 * 'T2) -> 'T2
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val ignore: 'T -> unit
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val not: bool -> bool
+
+    ///Decrement a mutable reference cell containing an integer
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val decr: int ref -> unit
+
+    ///Increment a mutable reference cell containing an integer
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val incr: int ref -> unit
+    
+#if FX_NO_EXIT
+#else
+    ///Exit the current hardware isolated process, if security settings permit,
+    ///otherwise raise an exception. Calls System.Environment.Exit.
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val exit: int -> 'T   
+#endif
+    /// Concatenate two strings. The overlaoded operator '+' may also be used.
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (^): string -> string -> string
+
+    /// Concatenate two lists.
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val (@): 'T list -> 'T list -> 'T list
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val float: int -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val acos: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val asin: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val atan: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val atan2: float -> float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val ceil: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val exp: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val floor: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val log: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val log10: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val sqrt: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val cos: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val cosh: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val sin: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val sinh: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val tan: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val tanh: float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val truncate: float -> int
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val ( **  ): float -> float -> float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val nan: float
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val infinity: float
+
+    ///The type of pointers to mutable reference cells
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    type 'T ref = Microsoft.FSharp.Core.Ref<'T>
+
+    ///The type of None/Some options
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    type 'T option = Microsoft.FSharp.Core.Option<'T>
+
+    ///The type of simple immutable lists 
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    type 'T list = Microsoft.FSharp.Collections.List<'T>
+
+    [<CompilerMessage("This construct is for ML compatibility. Consider replacing uses of the functions accessible via Pervasives.* with their F# equivalents, usually by deleting 'Pervasives.'. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    type exn = System.Exception
diff --git a/src/FSharp.PowerPack.Compatibility/printexc.fs b/src/FSharp.PowerPack.Compatibility/printexc.fs
new file mode 100755
index 0000000..d336ed2
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/printexc.fs
@@ -0,0 +1,18 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008. The interface to the module 
+// is similar to that found in versions of other ML implementations, 
+// but is not an exact match.
+//===========================================================================
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Printexc
+
+
+let to_string (e:exn) = 
+  match e with 
+  | Failure s -> s
+  | :? System.ArgumentException as e -> sprintf "invalid argument: %s" e.Message
+  | MatchFailureException(s,n,m) -> sprintf "match failure, file '%s', line %d, column %d" s n m
+  | _ -> sprintf "%A\n" e
+
+let print f x = try f x with e -> stderr.WriteLine (to_string e) ; raise e 
diff --git a/src/FSharp.PowerPack.Compatibility/printexc.fsi b/src/FSharp.PowerPack.Compatibility/printexc.fsi
new file mode 100755
index 0000000..f62b294
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/printexc.fsi
@@ -0,0 +1,16 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008.  The interface to the module 
+// is similar to that found in versions of other ML implementations, 
+// but is not an exact match.  The type signatures in this interface
+// are an edited version of those generated automatically by running 
+// "bin\fsc.exe -i" on the implementation file.
+//===========================================================================
+
+/// Compatibility module to display data about exceptions.
+[<CompilerMessage("This module is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Printexc
+
+val print: mapping:('a -> 'b) -> 'a -> 'b
+val to_string: exn -> string
+
diff --git a/src/FSharp.PowerPack.Compatibility/sbyte.fs b/src/FSharp.PowerPack.Compatibility/sbyte.fs
new file mode 100755
index 0000000..58f4fcf
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/sbyte.fs
@@ -0,0 +1,47 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+open System
+
+/// Simple operations on signed bytes
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<System.Obsolete("Consider using operators such as 'sbyte' and 'int32' to convert numbers")>]
+module SByte = 
+
+    let compare (x:int8) y = compare x y
+
+    let zero = 0y
+    let one = 1y
+    let minus_one = - 1y
+    let neg (x:int8) =  - x
+    let add (x:int8) (y:int8) = x + y
+    let sub (x:int8) (y:int8) = x - y
+    let mul (x:int8) (y:int8) = x * y
+    let div (x:int8) (y:int8) = x / y
+    let rem (x:int8) (y:int8) = x % y
+    let succ (x:int8) = x + 1y
+    let pred (x:int8) = x - 1y
+    let abs (x:int8) = if x < zero then neg x else x
+    let max_int = 0x7Fuy
+    let min_int = 0x80y
+    let logand (x:int8) (y:int8) = x &&& y
+    let logor (x:int8) (y:int8) = x ||| y
+    let logxor (x:int8) (y:int8) = x ^^^ y
+    let lognot (x:int8) = ~~~ x
+    let shift_left (x:int8) (n:int) =  x <<< n
+    let shift_right (x:int8) (n:int) =  x >>> n
+    let of_uint8 (n:byte)   = sbyte n
+    let to_uint8 (x:int8) = byte x
+
+    let of_byte (n:byte)   = sbyte n
+    let to_byte (x:int8) = byte x
+
+    let of_int (n:int)   = sbyte n
+    let to_int (x:int8) = int x
+
+    let of_int16 (n:int16) = sbyte n
+    let to_int16 (x:int8)  = int16 x
+
+    let of_int32 (n:int32) = sbyte n
+    let to_int32 (x:int8) = int32 x
diff --git a/src/FSharp.PowerPack.Compatibility/set.fs b/src/FSharp.PowerPack.Compatibility/set.fs
new file mode 100755
index 0000000..f27b795
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/set.fs
@@ -0,0 +1,96 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+open System.Collections.Generic
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Set = 
+    let cardinal (s : Set<'T>) = s.Count
+    let elements (s : Set<'T>) = Set.toList s
+
+        // Fold, left-to-right. 
+        //
+        // NOTE: This matches OCaml behaviour, though differs from the
+        // behaviour of Map.fold which folds right-to-left.
+    // let fold f m z = Set.fold_left (fun z x ->  f x z) z m
+    let inter s1 s2 = Set.intersect s1 s2
+
+
+
+    open Microsoft.FSharp.Collections
+
+    // Functor
+    type Provider<'T,'Tag> when 'Tag :> IComparer<'T> =
+       interface
+         //type t = Tagged.Set<'T,'Tag>
+         abstract empty    : Tagged.Set<'T,'Tag>;
+         abstract is_empty : Tagged.Set<'T,'Tag> -> bool;
+         abstract mem      : 'T -> Tagged.Set<'T,'Tag> -> bool;
+         abstract add      : 'T -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract singleton: 'T -> Tagged.Set<'T,'Tag>;
+         abstract remove   : 'T -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract union    : Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract inter    : Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract diff     : Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract iter     : ('T -> unit) -> Tagged.Set<'T,'Tag> -> unit;
+         abstract elements : Tagged.Set<'T,'Tag> -> 'T list;
+         abstract equal    : Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> bool;
+         abstract subset   : Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> bool;
+         abstract compare  : Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> int;
+         abstract for_all  : ('T -> bool) -> Tagged.Set<'T,'Tag> -> bool;
+         abstract exists   : ('T -> bool) -> Tagged.Set<'T,'Tag> -> bool;
+         abstract filter   : ('T -> bool) -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract partition: ('T -> bool) -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> * Tagged.Set<'T,'Tag>;
+         abstract fold     : ('T -> 'b -> 'b) -> Tagged.Set<'T,'Tag> -> 'b -> 'b;
+         abstract cardinal : Tagged.Set<'T,'Tag> -> int;
+         abstract min_elt  : Tagged.Set<'T,'Tag> -> 'T;
+         abstract max_elt  : Tagged.Set<'T,'Tag> -> 'T;
+         abstract choose   : Tagged.Set<'T,'Tag> -> 'T 
+       end
+
+    let gen_inter (s1 : Tagged.Set<_,_>)  (s2 : Tagged.Set<_,_>)  = Tagged.Set<_,_>.Intersection(s1,s2)
+    let gen_diff (s1 : Tagged.Set<_,_>)  (s2 : Tagged.Set<_,_>)   = Tagged.Set<_,_>.Difference(s1,s2)
+    let gen_iter f (s : Tagged.Set<_,_>)  = s.Iterate(f)
+    let gen_elements (s : Tagged.Set<_,_>) = s.ToList()
+    let gen_equal (s1 : Tagged.Set<_,_>)  (s2 : Tagged.Set<_,_>)  =  Tagged.Set<_,_>.Equality(s1,s2)
+    let gen_subset (s1 : Tagged.Set<_,_>)  (s2 : Tagged.Set<_,_>)  = s1.IsSubsetOf(s2)
+    let gen_compare (s1 : Tagged.Set<_,_>)  (s2 : Tagged.Set<_,_>) = Tagged.Set<_,_>.Compare(s1,s2)
+    let gen_for_all f (s : Tagged.Set<_,_>) = s.ForAll f
+    let gen_exists f (s : Tagged.Set<_,_>) = s.Exists f
+    let gen_filter f (s : Tagged.Set<_,_>) = s.Filter f
+    let gen_partition f (s : Tagged.Set<_,_>) = s.Partition f 
+    let gen_fold f (s : Tagged.Set<_,_>) acc = s.Fold f acc
+    let gen_cardinal (s : Tagged.Set<_,_>) = s.Count
+    let gen_size (s : Tagged.Set<_,_>) = s.Count
+    let gen_min_elt (s : Tagged.Set<_,_>) = s.MinimumElement
+    let gen_max_elt (s : Tagged.Set<_,_>) = s.MaximumElement
+
+    let MakeTagged (cf : 'Tag) : Provider<'T,'Tag> when 'Tag :> IComparer<'T> =
+       { new Provider<_,_> with 
+           member p.empty = Tagged.Set<_,_>.Empty(cf);
+           member p.is_empty s = s.IsEmpty;
+           member p.mem x s = s.Contains(x);
+           member p.add x s = s.Add(x);
+           member p.singleton x = Tagged.Set<'T,'Tag>.Singleton(cf,x);
+           member p.remove x s = s.Remove(x);
+           member p.union (s1 : Tagged.Set<_,_>)  (s2 : Tagged.Set<_,_>) = Tagged.Set<_,_>.Union(s1,s2);
+           member p.inter s1 s2 = gen_inter s1 s2 ;
+           member p.diff s1 s2 = gen_diff s1 s2;
+           member p.iter f s= gen_iter f s;
+           member p.elements s = gen_elements s;
+           member p.equal s1 s2= gen_equal s1 s2;
+           member p.subset s1 s2= gen_subset s1 s2;
+           member p.compare s1 s2 = gen_compare s1 s2;
+           member p.for_all f s = gen_for_all f s;
+           member p.fold f s z = gen_fold f s z;
+           member p.exists f s = gen_exists f s;
+           member p.filter f s = gen_filter f s;
+           member p.partition f s = gen_partition f s ;
+           member p.cardinal s = gen_cardinal s;
+           member p.min_elt s = s.MinimumElement;
+           member p.max_elt s = s.MaximumElement; 
+           member p.choose s  = s.Choose }
+
+    type Provider<'T> = Provider<'T, IComparer<'T>>
+    let Make cf  = MakeTagged (ComparisonIdentity.FromFunction cf)
diff --git a/src/FSharp.PowerPack.Compatibility/set.fsi b/src/FSharp.PowerPack.Compatibility/set.fsi
new file mode 100755
index 0000000..dd264b9
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/set.fsi
@@ -0,0 +1,86 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+#nowarn "62" // ocaml compat
+
+open System
+open System.Collections.Generic
+open Microsoft.FSharp.Collections
+
+/// Immutable sets implemented via binary trees
+[<CompilerMessage("This module is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<RequireQualifiedAccess>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Set = 
+
+    [<Obsolete("Use Set.count instead")>]
+    val cardinal: Set<'T> -> int
+
+    [<Obsolete("Use Set.toList instead")>]
+    val elements: Set<'T> -> 'T list
+
+    [<Obsolete("Use Set.intersect instead")>]
+    val inter: Set<'T> -> Set<'T> -> Set<'T>
+
+    ///A collection of operations for creating and using sets based on a particular comparison function.
+    ///The 'Tag' type parameter is used to track information about the comparison function.
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    type Provider<'T,'Tag> when 'Tag :> IComparer<'T> =
+       interface
+         abstract empty: Tagged.Set<'T,'Tag>;
+         abstract is_empty: Tagged.Set<'T,'Tag> -> bool;
+         abstract mem: 'T -> Tagged.Set<'T,'Tag> -> bool;
+         abstract add: 'T -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract singleton: 'T -> Tagged.Set<'T,'Tag>;
+         abstract remove: 'T -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract union: Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract inter: Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract diff: Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract iter: ('T -> unit) -> Tagged.Set<'T,'Tag> -> unit;
+         abstract elements: Tagged.Set<'T,'Tag> -> 'T list;
+         abstract equal: Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> bool;
+         abstract subset: Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> bool;
+         abstract compare: Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> -> int;
+         abstract for_all: ('T -> bool) -> Tagged.Set<'T,'Tag> -> bool;
+         abstract exists: ('T -> bool) -> Tagged.Set<'T,'Tag> -> bool;
+         abstract filter: ('T -> bool) -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag>;
+         abstract partition: ('T -> bool) -> Tagged.Set<'T,'Tag> -> Tagged.Set<'T,'Tag> * Tagged.Set<'T,'Tag>;
+         abstract fold:  ('T -> 'State -> 'State) -> Tagged.Set<'T,'Tag> -> 'State -> 'State;
+         abstract cardinal: Tagged.Set<'T,'Tag> -> int;
+         abstract min_elt: Tagged.Set<'T,'Tag> -> 'T;
+         abstract max_elt: Tagged.Set<'T,'Tag> -> 'T;
+         abstract choose: Tagged.Set<'T,'Tag> -> 'T 
+       end
+         
+
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    type Provider<'T> = Provider<'T, IComparer<'T>>
+
+    /// Build a collection of operations for creating and using 
+    /// maps based on a single consistent comparison function. This returns a record
+    /// that contains the functions you use to create and manipulate maps all of which 
+    /// use this comparison function.  The returned value is much like an ML module. 
+    ///
+    /// Use MakeTagged if you want additional type safety that guarantees that two sets
+    /// based on different comparison functions can never be combined in inconsistent ways.
+    
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val Make: ('T -> 'T -> int) -> Provider<'T>
+
+    ///A functor to build a collection of operations for creating and using 
+    /// sets based on the given comparison function. This returns a record that 
+    /// contains the functions you use to create and manipulate maps of
+    /// this kind.  The returned value is much like an ML module. 
+    ///
+    /// To use this function you need to define a new named class that implements IComparer and
+    /// pass an instance of that class as the first argument. For example:
+    ///      type MyComparer() = 
+    ///          interface IComparer<string> with 
+    ///            member self.Compare(x,y) = ...
+    ///
+    /// let MyStringSetProvider = Set.MakeTagged(new MyComparer())
+    [<CompilerMessage("This construct is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+    val MakeTagged: ('Tag :> IComparer<'T>) -> Provider<'T,'Tag>
+
+
diff --git a/src/FSharp.PowerPack.Compatibility/sys.fs b/src/FSharp.PowerPack.Compatibility/sys.fs
new file mode 100755
index 0000000..b11dcb7
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/sys.fs
@@ -0,0 +1,66 @@
+// (c) Microsoft Corporation 2005-2009. 
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Sys
+
+#nowarn "52" // defensive value copy warning, only with warning level 4
+
+open System
+open System.Reflection
+open Microsoft.FSharp.Control
+
+#if FX_NO_COMMAND_LINE_ARGS
+#else
+let argv = System.Environment.GetCommandLineArgs()
+#endif
+let file_exists  (s:string) = System.IO.File.Exists(s)
+let remove (s:string) = System.IO.File.Delete(s)
+let rename (s:string) (s2:string) = System.IO.File.Move(s,s2)
+
+#if FX_NO_ENVIRONMENT
+#else
+let getenv (s:string) =
+    match System.Environment.GetEnvironmentVariable(s) with 
+    | null -> raise (System.Collections.Generic.KeyNotFoundException("the given environment variable was not found"))
+    | s -> s
+#endif
+
+#if FX_NO_PROCESS_START
+#else
+let command (s:string) = 
+    let psi = new System.Diagnostics.ProcessStartInfo("cmd","/c "^s) 
+    psi.UseShellExecute <- false;
+    let p = System.Diagnostics.Process.Start(psi) 
+    p.WaitForExit();
+    p.ExitCode
+#endif
+
+let chdir (s:string) = System.IO.Directory.SetCurrentDirectory(s)
+let getcwd () = System.IO.Directory.GetCurrentDirectory()
+
+let word_size = sizeof<int> * 8
+
+#if FX_NO_PROCESS_DIAGNOSTICS
+#else
+// Sys.time only returns the process time from the main thread
+// The documentation doesn't guarantee that thread 0 is the main thread, 
+// but it always appears to be.  
+let mainThread = 
+    lazy 
+      (let thisProcess = System.Diagnostics.Process.GetCurrentProcess() 
+       let threads = thisProcess.Threads 
+       threads.[0])
+
+
+let time() = 
+    try mainThread.Force().TotalProcessorTime.TotalSeconds
+    with _ -> 
+      // If the above failed, e.g. because main thread has exited, then do the following
+      System.Diagnostics.Process.GetCurrentProcess().UserProcessorTime.TotalSeconds
+#endif
+
+#if FX_NO_APP_DOMAINS
+#else
+let executable_name = 
+    System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory,
+                           System.AppDomain.CurrentDomain.FriendlyName)  
+#endif
diff --git a/src/FSharp.PowerPack.Compatibility/sys.fsi b/src/FSharp.PowerPack.Compatibility/sys.fsi
new file mode 100755
index 0000000..1e7706e
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/sys.fsi
@@ -0,0 +1,85 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2008.  The interface to the module 
+// is similar to that found in versions of other ML implementations, 
+// but is not an exact match.  The type signatures in this interface
+// are an edited version of those generated automatically by running 
+// "bin\fsc.exe -i" on the implementation file.
+//===========================================================================
+
+/// Sys: Basic system operations (for ML compatibility)
+///
+/// This module is only included to make it possible to cross-compile 
+/// code with other ML compilers.  It may be deprecated and/or removed in 
+/// a future release. You may wish to use .NET functions directly instead. 
+[<CompilerMessage("This module is for ML compatibility. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Compatibility.OCaml.Sys
+
+#if FX_NO_COMMAND_LINE_ARGS
+#else
+/// The array of command line options. Gives the command line arguments
+/// as returned by <c>System.Environment.GetCommandLineArgs</c>.
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.Environment.GetCommandLineArgs directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val argv: string array
+#endif
+
+/// Returns true if a file currently exists, using System.IO.File.Exists(s).
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.IO.File.Exists directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val file_exists: string -> bool
+
+#if FX_NO_ENVIRONMENT
+#else
+/// Call System.Environment.GetEnvironmentVariable. Raise <c>KeyNotFoundException</c> if the variable is not defined.
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.Environment.GetEnvironmentVariable directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val getenv: string -> string
+#endif
+
+/// Deletes a file using <c>System.IO.File.Delete</c>.
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.IO.File.Delete directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val remove: string -> unit
+
+/// Rename a file on disk using System.IO.File.Move  
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.IO.File.Move directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val rename: string -> string -> unit
+
+/// Sets the current working directory for the process using <c>System.IO.Directory.SetCurrentDirectory</c> 
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.IO.Directory.SetCurrentDirectory directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val chdir: string -> unit
+
+/// Returns the current working directory for the process using <c>System.IO.Directory.GetCurrentDirectory</c>
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.IO.Directory.GetCurrentDirectory directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val getcwd: unit -> string
+
+#if FX_NO_PROCESS_START
+#else
+/// Run the command and return it's exit code.
+///
+/// Warning: 'command' currently attempts to execute the string using 
+/// the 'cmd.exe' shell processor.  If it is not present on the system 
+/// then the operation will fail.  Use System.Diagnostics.Process 
+/// directly to run commands in a portable way, which involves specifying 
+/// the program to run and the arguments independently.
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.Diagnostics.Process directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val command: string -> int
+#endif
+
+#if FX_NO_APP_DOMAINS
+#else
+/// Path of the current executable, using
+/// <c>System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory,System.AppDomain.CurrentDomain.FriendlyName)</c>
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.AppDomain.CurrentDomain.FriendlyName directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val executable_name: string
+#endif
+
+/// The number of bits in the "int" type.
+[<CompilerMessage("This construct is for ML compatibility. Consider using sizeof<int> directly, where this returns a size in bytes. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val word_size: int
+
+#if FX_NO_PROCESS_DIAGNOSTICS
+#else
+/// Time consumed by the main thread. (for approximate timings).
+/// Generally returns only the processor time used by the main 
+/// thread of the application.
+[<CompilerMessage("This construct is for ML compatibility. Consider using System.Diagnostics.Process.GetCurrentProcess().UserProcessorTime.TotalSeconds directly. This message can be disabled using '--nowarn:62' or '#nowarn \"62\"'.", 62, IsHidden=true)>]
+val time: unit -> float
+#endif
diff --git a/src/FSharp.PowerPack.Compatibility/uint32.fs b/src/FSharp.PowerPack.Compatibility/uint32.fs
new file mode 100755
index 0000000..0455a05
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/uint32.fs
@@ -0,0 +1,59 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module UInt32 = 
+
+    let compare (x:uint32) y = compare x y
+
+    let zero = 0ul
+    let one = 1ul
+    let add (x:uint32) (y:uint32) = x + y
+    let sub (x:uint32) (y:uint32) = x - y
+    let mul (x:uint32) (y:uint32) = x * y
+    let div (x:uint32) (y:uint32) = x / y
+    let rem (x:uint32) (y:uint32) = x % y
+    let succ (x:uint32) = x + 1ul
+    let pred (x:uint32) = x - 1ul
+    let max_int = 0xFFFFFFFFul
+    let min_int = 0ul 
+    let logand (x:uint32) (y:uint32) = x &&& y
+    let logor (x:uint32) (y:uint32) = x ||| y
+    let logxor (x:uint32) (y:uint32) = x ^^^ y
+    let lognot (x:uint32) = ~~~x
+    let shift_left (x:uint32) (n:int) =  x <<< n
+    let shift_right (x:uint32) (n:int) =  x >>> n
+    let of_int (x:int) =  uint32 x
+    let to_int (x:uint32) = int x
+    let of_int32 (x:int32) =  uint32 x
+    let to_int32 (x:uint32) = int32 x
+
+    let of_float (x:float) =  uint32 x
+    let to_float (x:uint32) =  float x
+
+    let of_string (s:string) = try uint32 s with _ -> failwith "UInt32.of_string"
+    let to_string (x:uint32) = (box x).ToString()
+
+    let bits_of_float32 (x:float32) = 
+        System.BitConverter.ToUInt32(System.BitConverter.GetBytes(x),0)
+          
+    let float32_of_bits (x:uint32) = 
+        System.BitConverter.ToSingle(System.BitConverter.GetBytes(x),0)
+
+    let float32_to_float (x:float32) = float x
+    let float_to_float32 (x:float) = float32 x
+
+    let float_of_bits x = float32_to_float (float32_of_bits x)
+    let bits_of_float x = bits_of_float32 (float_to_float32 x)
+
+    let of_unativeint (x:unativeint) =  uint32 x
+    let to_unativeint (x:uint32) =  unativeint x
+
+    let of_uint64 (x:uint64) =  uint32 x
+    let to_uint64 (x:uint32) =  uint64 x
+
+
+
+    let of_float32 (x:float32) =  uint32 x
+    let to_float32 (x:uint32) =  float32 x
diff --git a/src/FSharp.PowerPack.Compatibility/uint32.fsi b/src/FSharp.PowerPack.Compatibility/uint32.fsi
new file mode 100755
index 0000000..61a6482
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/uint32.fsi
@@ -0,0 +1,61 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+/// UInt32: ML-like operations on 32-bit System.UInt32 numbers.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<System.Obsolete("Consider using operators such as 'int32' and 'uint32' to convert numbers")>]
+module UInt32 = 
+
+    val zero: uint32
+    val one: uint32
+    val pred: uint32 -> uint32
+    val max_int: uint32
+    val min_int: uint32
+    val succ: uint32 -> uint32
+
+    val add: uint32 -> uint32 -> uint32
+    val div: uint32 -> uint32 -> uint32
+    val mul: uint32 -> uint32 -> uint32
+    val rem: uint32 -> uint32 -> uint32
+    val sub: uint32 -> uint32 -> uint32
+
+    val compare: uint32 -> uint32 -> int
+
+    val logand: uint32 -> uint32 -> uint32
+    val lognot: uint32 -> uint32
+    val logor: uint32 -> uint32 -> uint32
+    val logxor: uint32 -> uint32 -> uint32
+    val shift_left: uint32 -> int -> uint32
+    val shift_right: uint32 -> int -> uint32
+
+    val of_float: float -> uint32
+    val to_float: uint32 -> float
+
+    val of_float32: float32 -> uint32
+    val to_float32: uint32 -> float32
+
+    (* Conversions to int are included because int is the most convenient *)
+    (* integer type to use from F#.  Otherwise conversions are either to *)
+    (* integers of the same size or same sign *)
+    val of_int: int -> uint32
+    val to_int: uint32 -> int
+
+    val of_int32: int32 -> uint32
+    val to_int32: uint32 -> int32
+
+    val of_uint64: uint64 -> uint32
+    val to_uint64: uint32 -> uint64
+
+    val of_unativeint: unativeint -> uint32
+    val to_unativeint: uint32 -> unativeint
+
+    val of_string: string -> uint32
+    val to_string: uint32 -> string
+
+    val float_of_bits: uint32 -> float
+    val bits_of_float: float -> uint32
+
+    val float32_of_bits: uint32 -> float32
+    val bits_of_float32: float32 -> uint32
+
diff --git a/src/FSharp.PowerPack.Compatibility/uint64.fs b/src/FSharp.PowerPack.Compatibility/uint64.fs
new file mode 100755
index 0000000..0526cd9
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/uint64.fs
@@ -0,0 +1,44 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module UInt64 = 
+
+    let compare (x:uint64) y = compare x y
+
+    let zero = 0UL
+    let one = 1UL
+    let add (x:uint64) (y:uint64) = x + y
+    let sub (x:uint64) (y:uint64) = x - y
+    let mul (x:uint64) (y:uint64) = x * y
+    let div (x:uint64) (y:uint64) = x / y
+    let rem (x:uint64) (y:uint64) = x % y
+    let succ (x:uint64) = x + 1UL
+    let pred (x:uint64) = x - 1UL
+    let max_int = 0xFFFFFFFFFFFFFFFFUL
+    let min_int = 0x0UL
+    let logand (x:uint64) (y:uint64)   = x &&& y
+    let logor  (x:uint64) (y:uint64)   = x ||| y
+    let logxor (x:uint64) (y:uint64)   = x ^^^ y
+    let lognot (x:uint64)              = ~~~x
+    let shift_left  (x:uint64) (n:int) =  x <<< n
+    let shift_right (x:uint64) (n:int) =  x >>> n
+    let of_int        (n:int)             = uint64 n
+    let to_int        (x:uint64)          = int x
+    let of_uint32     (n:uint32)          = uint64 n
+    let to_uint32     (x:uint64)          = uint32 x
+    let of_int64      (n:int64)           = uint64 n
+    let to_int64      (x:uint64)          = int64 x
+    let of_unativeint (n:unativeint)      = uint64 n
+    let to_unativeint (x:uint64)          = unativeint x
+    let of_float      (f:float)           = uint64 f
+    let to_float      (x:uint64)          = float x
+
+    let of_string (s:string) = try uint64 s with _ -> failwith "UInt64.of_string"
+    let to_string (x:uint64) = (box x).ToString()
+    let bits_of_float (x:float) = System.BitConverter.ToUInt64(System.BitConverter.GetBytes(x),0)
+    let float_of_bits (x:uint64) = System.BitConverter.ToDouble(System.BitConverter.GetBytes(x),0)
+
+    let of_float32 (f:float32) =  uint64 f
+    let to_float32 (x:uint64) =  float32 x
diff --git a/src/FSharp.PowerPack.Compatibility/uint64.fsi b/src/FSharp.PowerPack.Compatibility/uint64.fsi
new file mode 100755
index 0000000..f4a88bb
--- /dev/null
+++ b/src/FSharp.PowerPack.Compatibility/uint64.fsi
@@ -0,0 +1,55 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Compatibility.OCaml
+
+/// UInt64: basic operations on 64-bit System.UInt64 numbers.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<System.Obsolete("Consider using operators such as 'int32' and 'uint64' to convert numbers")>]
+module UInt64 = 
+
+    val zero: uint64
+    val one: uint64
+    val pred: uint64 -> uint64
+    val succ: uint64 -> uint64
+    val max_int: uint64
+    val min_int: uint64
+
+    val add: uint64 -> uint64 -> uint64
+    val div: uint64 -> uint64 -> uint64
+    val mul: uint64 -> uint64 -> uint64
+    val rem: uint64 -> uint64 -> uint64
+    val sub: uint64 -> uint64 -> uint64
+
+    val compare: uint64 -> uint64 -> int
+
+    val logand: uint64 -> uint64 -> uint64
+    val lognot: uint64 -> uint64
+    val logor: uint64 -> uint64 -> uint64
+    val logxor: uint64 -> uint64 -> uint64
+    val shift_left: uint64 -> int -> uint64
+    val shift_right: uint64 -> int -> uint64
+
+    val of_float: float -> uint64
+    val to_float: uint64 -> float
+
+    val of_float32: float32 -> uint64
+    val to_float32: uint64 -> float32
+
+    val of_int: int -> uint64
+    val to_int: uint64 -> int
+
+    val of_uint32: uint32 -> uint64
+    val to_uint32: uint64 -> uint32
+
+    val of_int64: int64 -> uint64
+    val to_int64: uint64 -> int64
+
+    val of_unativeint: unativeint -> uint64
+    val to_unativeint: uint64 -> unativeint
+
+    val of_string: string -> uint64
+    val to_string: uint64 -> string
+
+    val float_of_bits: uint64 -> float
+    val bits_of_float: float -> uint64
+
diff --git a/src/FSharp.PowerPack.Linq/Assembly.fs b/src/FSharp.PowerPack.Linq/Assembly.fs
new file mode 100755
index 0000000..41e22e5
--- /dev/null
+++ b/src/FSharp.PowerPack.Linq/Assembly.fs
@@ -0,0 +1,8 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp
+
+//[<assembly: System.Security.SecurityTransparent>]
+[<assembly: AutoOpen("Microsoft.FSharp")>]
+[<assembly: AutoOpen("Microsoft.FSharp")>]
+do()
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj b/src/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj
new file mode 100755
index 0000000..880ae7d
--- /dev/null
+++ b/src/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{4c2ed03b-5ace-427b-8285-ad333e60f35e}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>FSharp.PowerPack.Linq</AssemblyName>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <DocumentationFile>FSharp.PowerPack.Linq.xml</DocumentationFile>
+    <NoWarn>$(NoWarn);9</NoWarn>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <!-- References -->
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core"/>   
+  </ItemGroup>
+  <!-- Files -->
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="assemblyinfo.FSharp.PowerPack.Linq.dll.fs">
+      <Link>assemblyinfo.FSharp.PowerPack.Linq.dll.fs</Link>
+    </Compile>
+    <Compile Include="FuncConvertExtensions.fsi" />
+    <Compile Include="FuncConvertExtensions.fs" />
+    <Compile Include="Linq.fsi" />
+    <Compile Include="Linq.fs" />
+    <Compile Include="LinqQueries.fsi" />
+    <Compile Include="LinqQueries.fs" />
+    <Compile Include="Assembly.fs" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Condition="'$(TargetFramework)'=='Silverlight'" Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.Common.targets"/>
+</Project>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj.vspscc b/src/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FSharp.PowerPack.Linq/FuncConvertExtensions.fs b/src/FSharp.PowerPack.Linq/FuncConvertExtensions.fs
new file mode 100755
index 0000000..fc76275
--- /dev/null
+++ b/src/FSharp.PowerPack.Linq/FuncConvertExtensions.fs
@@ -0,0 +1,28 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Core
+    open System
+    open System.Linq
+
+    [<Sealed; AbstractClass>]
+    type FuncConvertExtensions = 
+
+        static member  ToFSharpFunc( f : Action<_,_>) = (fun a1 a2 -> f.Invoke(a1,a2))
+        static member  ToFSharpFunc( f : Func<_>) = (fun () -> f.Invoke())
+        static member  ToFSharpFunc( f : Func<_,_>) = (fun a1 -> f.Invoke(a1))
+        static member  ToFSharpFunc( f : Func<_,_,_>) = (fun a1 a2 -> f.Invoke(a1,a2))
+        static member  ToFSharpFunc( f : Action<_,_,_>) = (fun a1 a2 a3 -> f.Invoke(a1,a2,a3))
+        static member  ToFSharpFunc( f : Func<_,_,_,_>) = (fun a1 a2 a3 -> f.Invoke(a1,a2,a3))
+        static member  ToFSharpFunc( f : Action<_,_,_,_>) = (fun a1 a2 a3 a4 -> f.Invoke(a1,a2,a3,a4))
+        static member  ToFSharpFunc( f : Func<_,_,_,_,_>) = (fun a1 a2 a3 a4 -> f.Invoke(a1,a2,a3,a4))
+        static member  ToTupledFSharpFunc( f : Func<_>) = (fun () -> f.Invoke())
+        static member  ToTupledFSharpFunc( f : Func<_,_>) = (fun a1 -> f.Invoke(a1))
+        static member  ToTupledFSharpFunc( f : Action<_,_>) = (fun (a1,a2) -> f.Invoke(a1,a2))
+        static member  ToTupledFSharpFunc( f : Func<_,_,_>) = (fun (a1,a2) -> f.Invoke(a1,a2))
+        static member  ToTupledFSharpFunc( f : Action<_,_,_>) = (fun (a1,a2,a3) -> f.Invoke(a1,a2,a3))
+        static member  ToTupledFSharpFunc( f : Func<_,_,_,_>) = (fun (a1,a2,a3) -> f.Invoke(a1,a2,a3))
+        static member  ToTupledFSharpFunc( f : Action<_,_,_,_>) = (fun (a1,a2,a3,a4) -> f.Invoke(a1,a2,a3,a4))
+        static member  ToTupledFSharpFunc( f : Func<_,_,_,_,_>) = (fun (a1,a2,a3,a4) -> f.Invoke(a1,a2,a3,a4))
+
+
diff --git a/src/FSharp.PowerPack.Linq/FuncConvertExtensions.fsi b/src/FSharp.PowerPack.Linq/FuncConvertExtensions.fsi
new file mode 100755
index 0000000..fcdf7d5
--- /dev/null
+++ b/src/FSharp.PowerPack.Linq/FuncConvertExtensions.fsi
@@ -0,0 +1,40 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Core
+    open System
+
+    [<Sealed; AbstractClass>]
+    type FuncConvertExtensions =
+
+        static member  ToFSharpFunc       : Func<'U>     -> (unit -> 'U)
+        
+        static member  ToFSharpFunc       : Func<'T1,'U>     -> ('T1 -> 'U)
+        
+        static member  ToFSharpFunc       : Action<'T1,'T2>           -> ('T1 -> 'T2 -> unit)
+        
+        static member  ToFSharpFunc       : Func<'T1,'T2,'U>     -> ('T1 -> 'T2 -> 'U)
+        
+        static member  ToFSharpFunc       : Action<'T1,'T2,'T3>       -> ('T1 -> 'T2 -> 'T3 -> unit)
+        
+        static member  ToFSharpFunc       : Func<'T1,'T2,'T3,'U> -> ('T1 -> 'T2 -> 'T3 -> 'U)
+
+        static member  ToFSharpFunc       : Action<'T1,'T2,'T3,'T4>       -> ('T1 -> 'T2 -> 'T3 -> 'T4 -> unit)
+        
+        static member  ToFSharpFunc       : Func<'T1,'T2,'T3,'T4,'U> -> ('T1 -> 'T2 -> 'T3 -> 'T4 -> 'U)
+
+        static member  ToTupledFSharpFunc : Func<'U>     -> (unit -> 'U)
+        
+        static member  ToTupledFSharpFunc : Func<'T1,'U>     -> ('T1 -> 'U)
+        
+        static member  ToTupledFSharpFunc : Action<'T1,'T2>           -> ('T1 * 'T2 -> unit)
+        
+        static member  ToTupledFSharpFunc : Func<'T1,'T2,'U>     -> ('T1 * 'T2 -> 'U)
+        
+        static member  ToTupledFSharpFunc : Action<'T1,'T2,'T3>       -> ('T1 * 'T2 * 'T3 -> unit)
+        
+        static member  ToTupledFSharpFunc : Func<'T1,'T2,'T3,'U> -> ('T1 * 'T2 * 'T3 -> 'U)
+
+        static member  ToTupledFSharpFunc : Action<'T1,'T2,'T3,'T4>       -> ('T1 * 'T2 * 'T3 * 'T4 -> unit)
+        
+        static member  ToTupledFSharpFunc : Func<'T1,'T2,'T3,'T4,'U> -> ('T1 * 'T2 * 'T3 * 'T4 -> 'U)
+
diff --git a/src/FSharp.PowerPack.Linq/Linq.fs b/src/FSharp.PowerPack.Linq/Linq.fs
new file mode 100755
index 0000000..eab276c
--- /dev/null
+++ b/src/FSharp.PowerPack.Linq/Linq.fs
@@ -0,0 +1,881 @@
+// Copyright (c) Microsoft Corporation 2005-2008.
+// This sample code is provided "as is" without warranty of any kind. 
+// We disclaim all warranties, either express or implied, including the 
+// warranties of merchantability and fitness for a particular purpose. 
+//
+
+
+namespace Microsoft.FSharp.Linq
+
+open System
+open System.Linq
+open System.Collections.Generic
+open System.Linq.Expressions
+open System.Reflection
+open System.Reflection.Emit
+open Microsoft.FSharp
+open Microsoft.FSharp.Reflection
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Quotations.Patterns
+open Microsoft.FSharp.Quotations.DerivedPatterns
+
+module ExtraHashCompare =
+    let GenericNotEqualIntrinsic<'T> (x:'T) (y:'T) : bool = not (Microsoft.FSharp.Core.LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<'T> x y)
+
+
+module QuotationEvaluation = 
+    
+    type This = 
+        static member Assembly = typeof<This>.Assembly
+
+    let hashCompareType = typeof<list<_>>.Assembly.GetType("Microsoft.FSharp.Core.LanguagePrimitives+HashCompare")
+    let extraHashCompareType = This.Assembly.GetType("Microsoft.FSharp.Linq.ExtraHashCompare")
+    let genericEqualityIntrinsic = "GenericEqualityIntrinsic" |> hashCompareType.GetMethod
+    let genericNotEqualIntrinsic = "GenericNotEqualIntrinsic" |> extraHashCompareType.GetMethod
+    let genericLessThanIntrinsic = "GenericLessThanIntrinsic" |> hashCompareType.GetMethod
+    let genericGreaterThanIntrinsic = "GenericGreaterThanIntrinsic" |> hashCompareType.GetMethod
+    let genericGreaterOrEqualIntrinsic = "GenericGreaterOrEqualIntrinsic" |> hashCompareType.GetMethod
+    let genericLessOrEqualIntrinsic = "GenericLessOrEqualIntrinsic" |> hashCompareType.GetMethod
+
+
+    type ConvEnv = 
+        {   eraseEquality : bool;
+            varEnv : Map<Var,Expression>
+        }
+    let asExpr x = (x :> Expression)
+
+    let bindingFlags = BindingFlags.Public ||| BindingFlags.NonPublic
+    let instanceBindingFlags = BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.DeclaredOnly
+    let isNamedType(typ:Type) = not (typ.IsArray || typ.IsByRef || typ.IsPointer)
+    let equivHeadTypes (ty1:Type) (ty2:Type) = 
+        isNamedType(ty1) &&
+        if ty1.IsGenericType then 
+          ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition())
+        else 
+          ty1.Equals(ty2)
+
+    let isFunctionType typ = equivHeadTypes typ (typeof<(int -> int)>)
+    let getFunctionType typ = 
+        if not (isFunctionType typ) then invalidArg "typ" "cannot convert recursion except for function types"
+        let tyargs = typ.GetGenericArguments()
+        tyargs.[0], tyargs.[1]
+    
+    let WhileHelper gd b : 'T = 
+        let rec loop () = if gd() then (b(); loop())
+        loop();
+        unbox (box ())
+
+    let ArrayAssignHelper (arr : 'T[]) (idx:int) (elem:'T) : 'unt = 
+        arr.[idx] <- elem;
+        unbox (box ())
+
+
+    let TryFinallyHelper e h = 
+        try e() 
+        finally h()
+
+    let TryWithHelper e filter handler = 
+        try e() 
+        with e when (filter e <> 0) -> handler e
+
+    let WhileMethod = match <@@ WhileHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+    let ArrayAssignMethod = match <@@ ArrayAssignHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+    let TryFinallyMethod = match <@@ TryFinallyHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+    let TryWithMethod = match <@@ TryWithHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+
+    module HelperTypes = 
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 * 'T20 -> unit
+
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> 'T6
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> 'T7 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> 'T8 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> 'T9 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> 'T10 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> 'T11 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> 'T12 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> 'T13 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> 'T14 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> 'T15 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> 'T16 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> 'T17 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 -> 'T18 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 -> 'T19 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 -> 'T20 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20, 'T21> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 * 'T20 -> 'T21 
+
+    open HelperTypes
+    
+    let GetActionType (args:Type[])  = 
+        if args.Length <= 4 then 
+            Expression.GetActionType args
+        else
+            match args.Length with 
+            | 5 -> typedefof<ActionHelper<_,_,_,_,_>>.MakeGenericType args
+            | 6 -> typedefof<ActionHelper<_,_,_,_,_,_>>.MakeGenericType args
+            | 7 -> typedefof<ActionHelper<_,_,_,_,_,_,_>>.MakeGenericType args
+            | 8 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 9 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 10 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 11 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 12 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 13 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 14 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 15 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 16 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 17 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 18 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 19 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 20 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | _ -> raise <| new NotSupportedException("Quotation expressions with statements or closures containing more then 20 free variables may not be translated in this release of the F# PowerPack. This is due to limitations in the variable binding expression forms available in LINQ expression trees")
+
+    let GetFuncType (args:Type[])  = 
+        if args.Length <= 5 then 
+            Expression.GetFuncType args
+        else
+            match args.Length with 
+            | 6 -> typedefof<FuncHelper<_,_,_,_,_,_>>.MakeGenericType args
+            | 7 -> typedefof<FuncHelper<_,_,_,_,_,_,_>>.MakeGenericType args
+            | 8 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 9 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 10 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 11 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 12 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 13 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 14 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 15 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 16 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 17 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 18 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 19 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 20 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 21 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | _ -> raise <| new NotSupportedException("Quotation expressions with statements or closures containing more then 20 free variables may not be translated in this release of the F# PowerPack. This is due to limitations in the variable binding expression forms available in LINQ expression trees")
+            
+
+    let LetRec1Helper (F1:System.Func<_,_,_>) (B:System.Func<_,_>) = 
+        let fhole = ref (Unchecked.defaultof<_>)
+        let f = new System.Func<_,_>(fun x -> F1.Invoke(fhole.Value,x))
+        fhole := f
+        B.Invoke f
+
+    let LetRec2Helper (F1:System.Func<_,_,_,_>) (F2:System.Func<_,_,_,_>) (B:System.Func<_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        B.Invoke(f1,f2)
+
+    let LetRec3Helper (F1:System.Func<_,_,_,_,_>) (F2:System.Func<_,_,_,_,_>) (F3:System.Func<_,_,_,_,_>) (B:System.Func<_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        B.Invoke(f1,f2,f3)
+
+    let LetRec4Helper 
+           (F1:FuncHelper<_,_,_,_,_,_>) 
+           (F2:FuncHelper<_,_,_,_,_,_>) 
+           (F3:FuncHelper<_,_,_,_,_,_>) 
+           (F4:FuncHelper<_,_,_,_,_,_>) 
+           (B:System.Func<_,_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f4hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,x))
+        let f4 = new System.Func<_,_>(fun x -> F4.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        f4hole := f4
+        B.Invoke(f1,f2,f3,f4)
+
+
+    let LetRec5Helper 
+           (F1:FuncHelper<_,_,_,_,_,_,_>) 
+           (F2:FuncHelper<_,_,_,_,_,_,_>) 
+           (F3:FuncHelper<_,_,_,_,_,_,_>) 
+           (F4:FuncHelper<_,_,_,_,_,_,_>) 
+           (F5:FuncHelper<_,_,_,_,_,_,_>) 
+           (B:FuncHelper<_,_,_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f4hole = ref (Unchecked.defaultof<_>)
+        let f5hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,x))
+        let f4 = new System.Func<_,_>(fun x -> F4.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,x))
+        let f5 = new System.Func<_,_>(fun x -> F5.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        f4hole := f4
+        f5hole := f5
+        B.Invoke(f1,f2,f3,f4,f5)
+
+    let LetRec6Helper 
+           (F1:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (F2:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (F3:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (F4:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (F5:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (F6:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (B:FuncHelper<_,_,_,_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f4hole = ref (Unchecked.defaultof<_>)
+        let f5hole = ref (Unchecked.defaultof<_>)
+        let f6hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        let f4 = new System.Func<_,_>(fun x -> F4.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        let f5 = new System.Func<_,_>(fun x -> F5.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        let f6 = new System.Func<_,_>(fun x -> F6.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        f4hole := f4
+        f5hole := f5
+        f6hole := f6
+        B.Invoke(f1,f2,f3,f4,f5,f6)
+
+
+    let LetRec7Helper 
+           (F1:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F2:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F3:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F4:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F5:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F6:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F7:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (B:FuncHelper<_,_,_,_,_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f4hole = ref (Unchecked.defaultof<_>)
+        let f5hole = ref (Unchecked.defaultof<_>)
+        let f6hole = ref (Unchecked.defaultof<_>)
+        let f7hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f4 = new System.Func<_,_>(fun x -> F4.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f5 = new System.Func<_,_>(fun x -> F5.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f6 = new System.Func<_,_>(fun x -> F6.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f7 = new System.Func<_,_>(fun x -> F7.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        f4hole := f4
+        f5hole := f5
+        f6hole := f6
+        f7hole := f7
+        B.Invoke(f1,f2,f3,f4,f5,f6,f7)
+
+
+    let LetRec8Helper 
+           (F1:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F2:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F3:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F4:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F5:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F6:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F7:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F8:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (B:FuncHelper<_,_,_,_,_,_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f4hole = ref (Unchecked.defaultof<_>)
+        let f5hole = ref (Unchecked.defaultof<_>)
+        let f6hole = ref (Unchecked.defaultof<_>)
+        let f7hole = ref (Unchecked.defaultof<_>)
+        let f8hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f4 = new System.Func<_,_>(fun x -> F4.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f5 = new System.Func<_,_>(fun x -> F5.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f6 = new System.Func<_,_>(fun x -> F6.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f7 = new System.Func<_,_>(fun x -> F7.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f8 = new System.Func<_,_>(fun x -> F8.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        f4hole := f4
+        f5hole := f5
+        f6hole := f6
+        f7hole := f7
+        f8hole := f8
+        B.Invoke(f1,f2,f3,f4,f5,f6,f7,f8)
+
+
+    let IsVoidType (ty:System.Type)  = (ty = typeof<System.Void>)
+
+    let SequentialHelper (x:'T) (y:'U) = y
+ 
+    let LinqExpressionHelper (x:'T) : Expression<'T> = failwith ""
+    
+    let MakeFakeExpression (x:Expr) = 
+        let minfo = match <@@ LinqExpressionHelper @@> with Lambda(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find method info"
+        Expr.Call(minfo.GetGenericMethodDefinition().MakeGenericMethod [| x.Type |], [ x ])
+
+    let showAll = BindingFlags.Public ||| BindingFlags.NonPublic 
+
+    let WrapVoid b objOpt args (env: ConvEnv) (e:Expression) = 
+        if b then 
+            let frees (e:Expr) = e.GetFreeVars()
+            let addFrees e acc = List.foldBack Set.add (frees e |> Seq.toList) acc
+            let fvs = Option.foldBack addFrees objOpt (List.foldBack addFrees args Set.empty) |> Set.toArray
+            let fvsP = fvs |> Array.map (fun v -> (Map.find v env.varEnv :?> ParameterExpression))
+            let fvtys = fvs |> Array.map (fun v -> v.Type) 
+
+            let dty = GetActionType fvtys 
+            let e = Expression.Lambda(dty,e,fvsP)
+            let d = e.Compile()
+
+            let argtys = Array.append fvtys [| dty |]
+            let delP = Expression.Parameter(dty, "del")
+
+            let m = new System.Reflection.Emit.DynamicMethod("wrapper",typeof<unit>,argtys)
+            let ilg = m.GetILGenerator()
+            
+            ilg.Emit(OpCodes.Ldarg ,fvs.Length)
+            fvs |> Array.iteri (fun i _ -> ilg.Emit(OpCodes.Ldarg ,int16 i))
+            ilg.EmitCall(OpCodes.Callvirt,dty.GetMethod("Invoke",instanceBindingFlags),null)
+            ilg.Emit(OpCodes.Ldnull)
+            ilg.Emit(OpCodes.Ret)
+            let args = Array.append (fvsP |> Array.map asExpr) [| (Expression.Constant(d) |> asExpr) |]
+            Expression.Call((null:Expression),(m:>MethodInfo),args) |> asExpr
+        else
+            e
+
+    let (|GenericEqualityQ|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.GenericEquality @>
+    let (|EqualsQ|_|)    = (|SpecificCall|_|) <@ ( = ) @>
+    let (|GreaterQ|_|)   = (|SpecificCall|_|) <@ ( > ) @>
+    let (|GreaterEqQ|_|) = (|SpecificCall|_|) <@ ( >=) @>
+    let (|LessQ|_|)      = (|SpecificCall|_|) <@ ( <)  @>
+    let (|LessEqQ|_|) = (|SpecificCall|_|) <@ ( <=) @>
+    let (|NotEqQ|_|) = (|SpecificCall|_|) <@ ( <>) @>
+    let (|NotQ|_|) =  (|SpecificCall|_|) <@ not   @>
+    let (|NegQ|_|) = (|SpecificCall|_|) <@ ( ~-) : int -> int @>
+    let (|PlusQ|_|)      = (|SpecificCall|_|) <@ ( + ) @>
+    let (|DivideQ|_|) = (|SpecificCall|_|) <@ ( / ) @> 
+    let (|MinusQ|_|) = (|SpecificCall|_|) <@ ( - ) @>
+    let (|MultiplyQ|_|) = (|SpecificCall|_|) <@ ( * ) @>
+    let (|ModuloQ|_|) = (|SpecificCall|_|) <@ ( % ) @>
+    let (|ShiftLeftQ|_|) = (|SpecificCall|_|) <@ ( <<< ) @>
+    let (|ShiftRightQ|_|) = (|SpecificCall|_|) <@ ( >>> ) @>
+    let (|BitwiseAndQ|_|) = (|SpecificCall|_|) <@ ( &&& ) @>
+    let (|BitwiseOrQ|_|) = (|SpecificCall|_|) <@ ( ||| ) @>
+    let (|BitwiseXorQ|_|) = (|SpecificCall|_|) <@ ( ^^^ ) @>
+    let (|BitwiseNotQ|_|) = (|SpecificCall|_|) <@ ( ~~~ ) @>
+    let (|CheckedNeg|_|) = (|SpecificCall|_|) <@ Checked.( ~-) : int -> int @>
+    let (|CheckedPlusQ|_|)      = (|SpecificCall|_|) <@ Checked.( + ) @>
+    let (|CheckedMinusQ|_|) = (|SpecificCall|_|) <@ Checked.( - ) @>
+    let (|CheckedMultiplyQ|_|) = (|SpecificCall|_|) <@ Checked.( * ) @>
+    let (|ConvCharQ|_|) = (|SpecificCall|_|) <@ char @>
+    let (|ConvDecimalQ|_|) = (|SpecificCall|_|) <@ decimal @>
+    let (|ConvFloatQ|_|) = (|SpecificCall|_|) <@ float @>
+    let (|ConvFloat32Q|_|) = (|SpecificCall|_|) <@ float32 @>
+    let (|ConvSByteQ|_|) = (|SpecificCall|_|) <@ sbyte @>
+    let (|ConvInt16Q|_|) = (|SpecificCall|_|) <@ int16 @>
+    let (|ConvInt32Q|_|) = (|SpecificCall|_|) <@ int32 @>
+    let (|ConvIntQ|_|) = (|SpecificCall|_|) <@ int @>
+    let (|ConvInt64Q|_|) = (|SpecificCall|_|) <@ int64 @>
+    let (|ConvByteQ|_|) = (|SpecificCall|_|) <@ byte @>
+    let (|ConvUInt16Q|_|) = (|SpecificCall|_|) <@ uint16 @>
+    let (|ConvUInt32Q|_|) = (|SpecificCall|_|) <@ uint32 @>
+    let (|ConvUInt64Q|_|) = (|SpecificCall|_|) <@ uint64 @>
+
+    let (|CheckedConvCharQ|_|) = (|SpecificCall|_|) <@ Checked.char @>
+    let (|CheckedConvSByteQ|_|) = (|SpecificCall|_|) <@ Checked.sbyte @>
+    let (|CheckedConvInt16Q|_|) = (|SpecificCall|_|) <@ Checked.int16 @>
+    let (|CheckedConvInt32Q|_|) = (|SpecificCall|_|) <@ Checked.int32 @>
+    let (|CheckedConvInt64Q|_|) = (|SpecificCall|_|) <@ Checked.int64 @>
+    let (|CheckedConvByteQ|_|) = (|SpecificCall|_|) <@ Checked.byte @>
+    let (|CheckedConvUInt16Q|_|) = (|SpecificCall|_|) <@ Checked.uint16 @>
+    let (|CheckedConvUInt32Q|_|) = (|SpecificCall|_|) <@ Checked.uint32 @>
+    let (|CheckedConvUInt64Q|_|) = (|SpecificCall|_|) <@ Checked.uint64 @>
+    let (|LinqExpressionHelperQ|_|) = (|SpecificCall|_|) <@ LinqExpressionHelper @>
+    let (|ArrayLookupQ|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.GetArray : int[] -> int -> int @>
+    let (|ArrayAssignQ|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.SetArray : int[] -> int -> int -> unit @>
+    let (|ArrayTypeQ|_|) (ty:System.Type) = if ty.IsArray && ty.GetArrayRank() = 1 then Some(ty.GetElementType()) else None
+    
+    /// Convert F# quotations to LINQ expression trees.
+    /// A more polished LINQ-Quotation translator will be published
+    /// concert with later versions of LINQ.
+    let rec ConvExpr (env:ConvEnv) (inp:Expr) = 
+       //printf "ConvExpr : %A\n" e;
+        match inp with 
+
+        // Generic cases 
+        | Patterns.Var(v) -> 
+                try
+                    Map.find v env.varEnv
+                with
+                |   :? KeyNotFoundException when v.Name = "this" ->
+                        let message = 
+                            "Encountered unxpected variable named 'this'. This might happen because " +
+                            "quotations used in queries can’t contain references to let-bound values in classes unless the quotation literal occurs in an instance member. " +
+                            "If this is the case, workaround by replacing references to implicit fields with references to " +
+                            "local variables, e.g. rewrite\r\n" +
+                            "   type Foo() =\r\n" +
+                            "       let x = 1\r\n" +
+                            "       let bar() = <@ x @>\r\n" +
+                            "as: \r\n" +
+                            "   type Foo() =\r\n" +
+                            "       let x = 1\r\n" +
+                            "       let bar() = let x = x in <@ x @>\r\n";
+
+                        NotSupportedException(message) |> raise    
+        | DerivedPatterns.AndAlso(x1,x2)             -> Expression.AndAlso(ConvExpr env x1, ConvExpr env x2) |> asExpr
+        | DerivedPatterns.OrElse(x1,x2)              -> Expression.OrElse(ConvExpr env x1, ConvExpr env x2)  |> asExpr
+        | Patterns.Value(x,ty)                -> Expression.Constant(x,ty)              |> asExpr
+
+        // REVIEW: exact F# semantics for TypeAs and TypeIs
+        | Patterns.Coerce(x,toTy)             -> Expression.TypeAs(ConvExpr env x,toTy)     |> asExpr
+        | Patterns.TypeTest(x,toTy)           -> Expression.TypeIs(ConvExpr env x,toTy)     |> asExpr
+        
+        // Expr.*Get
+        | Patterns.FieldGet(objOpt,fieldInfo) -> 
+            Expression.Field(ConvObjArg env objOpt None, fieldInfo) |> asExpr
+
+        | Patterns.TupleGet(arg,n) -> 
+             let argP = ConvExpr env arg 
+             let rec build ty argP n = 
+                 match Reflection.FSharpValue.PreComputeTuplePropertyInfo(ty,n) with 
+                 | propInfo,None -> 
+                     Expression.Property(argP, propInfo)  |> asExpr
+                 | propInfo,Some(nestedTy,n2) -> 
+                     build nestedTy (Expression.Property(argP,propInfo) |> asExpr) n2
+             build arg.Type argP n
+              
+        | Patterns.PropertyGet(objOpt,propInfo,args) -> 
+            let coerceTo = 
+                if objOpt.IsSome && FSharpType.IsUnion propInfo.DeclaringType && FSharpType.IsUnion propInfo.DeclaringType.BaseType  then  
+                    Some propInfo.DeclaringType
+                else 
+                    None
+            match args with 
+            | [] -> 
+                Expression.Property(ConvObjArg env objOpt coerceTo, propInfo) |> asExpr
+            | _ -> 
+                let argsP = ConvExprs env args
+                Expression.Call(ConvObjArg env objOpt coerceTo, propInfo.GetGetMethod(true),argsP) |> asExpr
+
+        // Expr.*Set
+        | Patterns.PropertySet(objOpt,propInfo,args,v) -> 
+            let args = (args @ [v])
+            let argsP = ConvExprs env args 
+            let minfo = propInfo.GetSetMethod(true)
+            Expression.Call(ConvObjArg env objOpt None, minfo,argsP) |> asExpr |> WrapVoid (IsVoidType minfo.ReturnType) objOpt args env 
+
+        // Expr.(Call,Application)
+        | Patterns.Call(objOpt,minfo,args) -> 
+            let transComparison x1 x2 exprConstructor exprErasedConstructor (intrinsic : MethodInfo) =
+                let e1 = ConvExpr env x1
+                let e2 = ConvExpr env x2
+
+                if env.eraseEquality then
+                    exprErasedConstructor(e1,e2) |> asExpr
+                else 
+                    exprConstructor(e1, e2, false, intrinsic.MakeGenericMethod([|x1.Type|])) |> asExpr
+
+            match inp with 
+            // Special cases for this translation
+            |  PlusQ (_, [ty1;ty2;ty3],[x1;x2]) when (ty1 = typeof<string>) && (ty2 = typeof<string>) ->
+                 ConvExpr env (<@@  System.String.Concat( [| %%x1 ; %%x2 |] : string array ) @@>)
+
+            //| SpecificCall <@ LanguagePrimitives.GenericEquality @>([ty1],[x1;x2]) 
+            //| SpecificCall <@ ( = ) @>([ty1],[x1;x2]) when (ty1 = typeof<string>) ->
+            //     ConvExpr env (<@@  System.String.op_Equality(%%x1,%%x2) @@>)
+
+            | GenericEqualityQ (_, _,[x1;x2]) 
+            | EqualsQ (_, _,[x1;x2]) ->     transComparison x1 x2 Expression.Equal Expression.Equal genericEqualityIntrinsic
+
+            | GreaterQ (_, _,[x1;x2]) ->    transComparison x1 x2 Expression.GreaterThan Expression.GreaterThan genericGreaterThanIntrinsic
+
+            | GreaterEqQ (_, _,[x1;x2]) ->  transComparison x1 x2 Expression.GreaterThanOrEqual Expression.GreaterThanOrEqual genericGreaterOrEqualIntrinsic
+
+            | LessQ (_, _,[x1;x2]) ->       transComparison x1 x2 Expression.LessThan Expression.LessThan genericLessThanIntrinsic
+
+            | LessEqQ (_, _,[x1;x2]) ->     transComparison x1 x2 Expression.LessThanOrEqual Expression.LessThanOrEqual genericLessOrEqualIntrinsic
+
+            | NotEqQ (_, _,[x1;x2]) ->      transComparison x1 x2 Expression.NotEqual Expression.NotEqual genericNotEqualIntrinsic
+
+            | NotQ (_, _,[x1])    -> Expression.Not(ConvExpr env x1)                                   |> asExpr
+
+
+            | NegQ (_, _,[x1])    -> Expression.Negate(ConvExpr env x1)                                |> asExpr
+            | PlusQ (_, _,[x1;x2]) -> Expression.Add(ConvExpr env x1, ConvExpr env x2)      |> asExpr
+            | DivideQ (_, _,[x1;x2]) -> Expression.Divide (ConvExpr env x1, ConvExpr env x2)  |> asExpr
+            | MinusQ (_, _,[x1;x2]) -> Expression.Subtract(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | MultiplyQ (_, _,[x1;x2]) -> Expression.Multiply(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | ModuloQ (_, _,[x1;x2]) -> Expression.Modulo (ConvExpr env x1, ConvExpr env x2) |> asExpr
+                 /// REVIEW: basic arithmetic with method witnesses
+                 /// REVIEW: negate,add, divide, multiply, subtract with method witness
+
+            | ShiftLeftQ (_, _,[x1;x2]) -> Expression.LeftShift(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | ShiftRightQ (_, _,[x1;x2]) -> Expression.RightShift(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | BitwiseAndQ (_, _,[x1;x2]) -> Expression.And(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | BitwiseOrQ (_, _,[x1;x2]) -> Expression.Or(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | BitwiseXorQ (_, _,[x1;x2]) -> Expression.ExclusiveOr(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | BitwiseNotQ (_, _,[x1]) -> Expression.Not(ConvExpr env x1) |> asExpr
+                 /// REVIEW: bitwise operations with method witnesses
+
+            | CheckedNeg (_, _,[x1]) -> Expression.NegateChecked(ConvExpr env x1)                                |> asExpr
+            | CheckedPlusQ (_, _,[x1;x2]) -> Expression.AddChecked(ConvExpr env x1, ConvExpr env x2)      |> asExpr
+            | CheckedMinusQ (_, _,[x1;x2]) -> Expression.SubtractChecked(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | CheckedMultiplyQ (_, _,[x1;x2]) -> Expression.MultiplyChecked(ConvExpr env x1, ConvExpr env x2) |> asExpr
+
+            | ConvCharQ (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<char>) |> asExpr
+            | ConvDecimalQ (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<decimal>) |> asExpr
+            | ConvFloatQ (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<float>) |> asExpr
+            | ConvFloat32Q (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<float32>) |> asExpr
+            | ConvSByteQ (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<sbyte>) |> asExpr
+            | ConvInt16Q (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<int16>) |> asExpr
+            | ConvInt32Q (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<int32>) |> asExpr
+            | ConvIntQ (_, [ty],[x1])    -> Expression.Convert(ConvExpr env x1, typeof<int32>) |> asExpr
+            | ConvInt64Q (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<int64>) |> asExpr
+            | ConvByteQ (_, [ty],[x1])   -> Expression.Convert(ConvExpr env x1, typeof<byte>) |> asExpr
+            | ConvUInt16Q (_, [ty],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<uint16>) |> asExpr
+            | ConvUInt32Q (_, [ty],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<uint32>) |> asExpr
+            | ConvUInt64Q (_, [ty],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<uint64>) |> asExpr
+             /// REVIEW: convert with method witness
+
+            | CheckedConvCharQ (_, [ty],[x1])  -> Expression.ConvertChecked(ConvExpr env x1, typeof<char>) |> asExpr
+            | CheckedConvSByteQ (_, [ty],[x1])  -> Expression.ConvertChecked(ConvExpr env x1, typeof<sbyte>) |> asExpr
+            | CheckedConvInt16Q (_, [ty],[x1])  -> Expression.ConvertChecked(ConvExpr env x1, typeof<int16>) |> asExpr
+            | CheckedConvInt32Q (_, [ty],[x1])  -> Expression.ConvertChecked(ConvExpr env x1, typeof<int32>) |> asExpr
+            | CheckedConvInt64Q (_, [ty],[x1])  -> Expression.ConvertChecked(ConvExpr env x1, typeof<int64>) |> asExpr
+            | CheckedConvByteQ (_, [ty],[x1])   -> Expression.ConvertChecked(ConvExpr env x1, typeof<byte>) |> asExpr
+            | CheckedConvUInt16Q (_, [ty],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<uint16>) |> asExpr
+            | CheckedConvUInt32Q (_, [ty],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<uint32>) |> asExpr
+            | CheckedConvUInt64Q (_, [ty],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<uint64>) |> asExpr
+            | ArrayLookupQ (_, [ArrayTypeQ(elemTy);_;_],[x1;x2]) -> 
+                Expression.ArrayIndex(ConvExpr env x1, ConvExpr env x2) |> asExpr
+
+            | ArrayAssignQ (_, [ArrayTypeQ(elemTy);_;_],[arr;idx;elem]) -> 
+                let minfo = ArrayAssignMethod.GetGenericMethodDefinition().MakeGenericMethod [| elemTy;typeof<unit> |]
+                Expression.Call(minfo,[| ConvExpr env arr; ConvExpr env idx; ConvExpr env elem |]) |> asExpr
+            
+            // Throw away markers inserted to satisfy C#'s design where they pass an argument
+            // or type T to an argument expecting Expr<T>.
+            | LinqExpressionHelperQ (_, [_],[x1]) -> ConvExpr env x1
+             
+              /// ArrayLength
+              /// ListBind
+              /// ListInit
+              /// ElementInit
+            | _ -> 
+                let argsP = ConvExprs env args 
+                Expression.Call(ConvObjArg env objOpt None, minfo, argsP) |> asExpr |> WrapVoid (IsVoidType minfo.ReturnType) objOpt args env 
+
+        // f x1 x2 x3 x4 --> InvokeFast4
+        | Patterns.Application(Patterns.Application(Patterns.Application(Patterns.Application(f,arg1),arg2),arg3),arg4) -> 
+            let domainTy1, rangeTy = getFunctionType f.Type
+            let domainTy2, rangeTy = getFunctionType rangeTy
+            let domainTy3, rangeTy = getFunctionType rangeTy
+            let domainTy4, rangeTy = getFunctionType rangeTy
+            let (-->) ty1 ty2 = Reflection.FSharpType.MakeFunctionType(ty1,ty2)
+            let ty = domainTy1 --> domainTy2 
+            let meth = (ty.GetMethods() |> Array.find (fun minfo -> minfo.Name = "InvokeFast" && minfo.GetParameters().Length = 5)).MakeGenericMethod [| domainTy3; domainTy4; rangeTy |]
+            let argsP = ConvExprs env [f; arg1;arg2;arg3; arg4]
+            Expression.Call((null:Expression), meth, argsP) |> asExpr
+
+        // f x1 x2 x3 --> InvokeFast3
+        | Patterns.Application(Patterns.Application(Patterns.Application(f,arg1),arg2),arg3) -> 
+            let domainTy1, rangeTy = getFunctionType f.Type
+            let domainTy2, rangeTy = getFunctionType rangeTy
+            let domainTy3, rangeTy = getFunctionType rangeTy
+            let (-->) ty1 ty2 = Reflection.FSharpType.MakeFunctionType(ty1,ty2)
+            let ty = domainTy1 --> domainTy2 
+            let meth = (ty.GetMethods() |> Array.find (fun minfo -> minfo.Name = "InvokeFast" && minfo.GetParameters().Length = 4)).MakeGenericMethod [| domainTy3; rangeTy |]
+            let argsP = ConvExprs env [f; arg1;arg2;arg3]
+            Expression.Call((null:Expression), meth, argsP) |> asExpr
+
+        // f x1 x2 --> InvokeFast2
+        | Patterns.Application(Patterns.Application(f,arg1),arg2) -> 
+            let domainTy1, rangeTy = getFunctionType f.Type
+            let domainTy2, rangeTy = getFunctionType rangeTy
+            let (-->) ty1 ty2 = Reflection.FSharpType.MakeFunctionType(ty1,ty2)
+            let ty = domainTy1 --> domainTy2 
+            let meth = (ty.GetMethods() |> Array.find (fun minfo -> minfo.Name = "InvokeFast" && minfo.GetParameters().Length = 3)).MakeGenericMethod [| rangeTy |]
+            let argsP = ConvExprs env [f; arg1;arg2]
+            Expression.Call((null:Expression), meth, argsP) |> asExpr
+
+        // f x1 --> Invoke
+        | Patterns.Application(f,arg) -> 
+            let fP = ConvExpr env f
+            let argP = ConvExpr env arg
+            let meth = f.Type.GetMethod("Invoke")
+            Expression.Call(fP, meth, [| argP |]) |> asExpr
+
+        // Expr.New*
+        | Patterns.NewRecord(recdTy,args) -> 
+            let ctorInfo = Reflection.FSharpValue.PreComputeRecordConstructorInfo(recdTy,showAll) 
+            Expression.New(ctorInfo,ConvExprs env args) |> asExpr
+
+        | Patterns.NewArray(ty,args) -> 
+            Expression.NewArrayInit(ty,ConvExprs env args) |> asExpr
+
+        | Patterns.DefaultValue(ty) -> 
+            Expression.New(ty) |> asExpr
+
+        | Patterns.NewUnionCase(unionCaseInfo,args) -> 
+            let methInfo = Reflection.FSharpValue.PreComputeUnionConstructorInfo(unionCaseInfo,showAll)
+            let argsR = ConvExprs env args 
+            Expression.Call((null:Expression),methInfo,argsR) |> asExpr
+
+        | Patterns.UnionCaseTest(e,unionCaseInfo) -> 
+            let methInfo = Reflection.FSharpValue.PreComputeUnionTagMemberInfo(unionCaseInfo.DeclaringType,showAll)
+            let obj = ConvExpr env e 
+            let tagE = 
+                match methInfo with 
+                | :? PropertyInfo as p -> 
+                    Expression.Property(obj,p) |> asExpr
+                | :? MethodInfo as m -> 
+                    Expression.Call((null:Expression),m,[| obj |]) |> asExpr
+                | _ -> failwith "unreachable case"
+            Expression.Equal(tagE, Expression.Constant(unionCaseInfo.Tag)) |> asExpr
+
+        | Patterns.NewObject(ctorInfo,args) -> 
+            Expression.New(ctorInfo,ConvExprs env args) |> asExpr
+
+        | Patterns.NewDelegate(dty,vs,b) -> 
+            let vsP = List.map ConvVar vs 
+            let env = {env with varEnv = List.foldBack2 (fun (v:Var) vP -> Map.add v (vP |> asExpr)) vs vsP env.varEnv }
+            let bodyP = ConvExpr env b 
+            Expression.Lambda(dty, bodyP, vsP) |> asExpr 
+
+        | Patterns.NewTuple(args) -> 
+             let tupTy = args |> List.map (fun arg -> arg.Type) |> Array.ofList |> Reflection.FSharpType.MakeTupleType
+             let argsP = ConvExprs env args 
+             let rec build ty (argsP: Expression[]) = 
+                 match Reflection.FSharpValue.PreComputeTupleConstructorInfo(ty) with 
+                 | ctorInfo,None -> Expression.New(ctorInfo,argsP) |> asExpr 
+                 | ctorInfo,Some(nestedTy) -> 
+                     let n = ctorInfo.GetParameters().Length - 1
+                     Expression.New(ctorInfo, Array.append argsP.[0..n-1] [| build nestedTy argsP.[n..] |]) |> asExpr
+             build tupTy argsP
+
+        | Patterns.IfThenElse(g,t,e) -> 
+            Expression.Condition(ConvExpr env g, ConvExpr env t,ConvExpr env e) |> asExpr
+
+        | Patterns.Sequential (e1,e2) -> 
+            let e1P = ConvExpr env e1
+            let e2P = ConvExpr env e2
+            let minfo = match <@@ SequentialHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+            let minfo = minfo.GetGenericMethodDefinition().MakeGenericMethod [| e1.Type; e2.Type |]
+            Expression.Call(minfo,[| e1P; e2P |]) |> asExpr
+
+        | Patterns.Let (v,e,b) -> 
+            let vP = ConvVar v
+            let envinner = { env with varEnv = Map.add v (vP |> asExpr) env.varEnv } 
+            let bodyP = ConvExpr envinner b 
+            let eP = ConvExpr env e
+            let ty = GetFuncType [| v.Type; b.Type |] 
+            let lam = Expression.Lambda(ty,bodyP,[| vP |]) |> asExpr
+            Expression.Call(lam,ty.GetMethod("Invoke",instanceBindingFlags),[| eP |]) |> asExpr
+
+        | Patterns.Lambda(v,body) -> 
+            let vP = ConvVar v
+            let env = { env with varEnv = Map.add v (vP |> asExpr) env.varEnv }
+            let tyargs = [| v.Type; body.Type |]
+            let bodyP = ConvExpr env body
+            let convType = typedefof<System.Converter<obj,obj>>.MakeGenericType tyargs
+            let convDelegate = Expression.Lambda(convType, bodyP, [| vP |]) |> asExpr
+            Expression.Call(typeof<FuncConvert>,"ToFSharpFunc",tyargs,[| convDelegate |]) |> asExpr
+    
+        | Patterns.WhileLoop(gd,b) -> 
+            let gdP = ConvExpr env <@@ (fun () -> (%%gd:bool)) @@>
+            let bP = ConvExpr env <@@ (fun () -> (%%b:unit)) @@>
+            let minfo = WhileMethod.GetGenericMethodDefinition().MakeGenericMethod [| typeof<unit> |]
+            Expression.Call(minfo,[| gdP; bP |]) |> asExpr
+        
+        | Patterns.TryFinally(e,h) -> 
+            let eP = ConvExpr env (Expr.Lambda(new Var("unitVar",typeof<unit>), e))
+            let hP = ConvExpr env <@@ (fun () -> (%%h:unit)) @@>
+            let minfo = TryFinallyMethod.GetGenericMethodDefinition().MakeGenericMethod [| e.Type |]
+            Expression.Call(minfo,[| eP; hP |]) |> asExpr
+        
+        | Patterns.TryWith(e,vf,filter,vh,handler) -> 
+            let eP = ConvExpr env (Expr.Lambda(new Var("unitVar",typeof<unit>), e))
+            let filterP = ConvExpr env (Expr.Lambda(vf,filter))
+            let handlerP = ConvExpr env (Expr.Lambda(vh,handler))
+            let minfo = TryWithMethod.GetGenericMethodDefinition().MakeGenericMethod [| e.Type |]
+            Expression.Call(minfo,[| eP; filterP; handlerP |]) |> asExpr
+
+        | Patterns.LetRecursive(binds,body) -> 
+
+            let vfs = List.map fst binds
+            
+            let pass1 = 
+                binds |> List.map (fun (vf,expr) -> 
+                    match expr with 
+                    | Lambda(vx,expr) -> 
+                        let domainTy,rangeTy = getFunctionType vf.Type
+                        let vfdTy = GetFuncType [| domainTy; rangeTy |]
+                        let vfd = new Var("d",vfdTy)
+                        (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd)
+                    | _ -> failwith "cannot convert recursive bindings that do not define functions")
+
+            let trans = pass1 |> List.map (fun (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd) -> (vf,vfd)) |> Map.ofList
+
+            // Rewrite uses of the recursively defined functions to be invocations of the delegates
+            // We do this because the delegate are allocated "once" and we can normally just invoke them efficiently
+            let rec rw t = 
+                match t with 
+                | Application(Var(vf),t) when trans.ContainsKey(vf) -> 
+                     let vfd = trans.[vf]
+                     Expr.Call(Expr.Var(vfd),vfd.Type.GetMethod("Invoke",instanceBindingFlags),[t])
+                | ExprShape.ShapeVar(vf) when trans.ContainsKey(vf)-> 
+                     let vfd = trans.[vf]
+                     let nv = new Var("nv",fst(getFunctionType vf.Type)) 
+                     Expr.Lambda(nv,Expr.Call(Expr.Var(vfd),vfd.Type.GetMethod("Invoke",instanceBindingFlags),[Expr.Var(nv)]))
+                | ExprShape.ShapeVar(_) -> t
+                | ExprShape.ShapeCombination(obj,args) -> ExprShape.RebuildShapeCombination(obj,List.map rw args)
+                | ExprShape.ShapeLambda(v,arg) -> Expr.Lambda(v,rw arg)
+
+            let vfdTys    = pass1 |> List.map (fun (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd) -> vfdTy) |> Array.ofList
+            let vfds      = pass1 |> List.map (fun (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd) -> vfd)
+
+            let FPs = 
+                [| for (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd) in pass1 do
+                      let expr = rw expr
+                      let tyF = GetFuncType (Array.append vfdTys [| vx.Type; expr.Type |])
+                      let F = Expr.NewDelegate(tyF,vfds@[vx],expr)
+                      let FP = ConvExpr env F
+                      yield FP |]
+
+            let body = rw body
+
+            let methTys   = 
+                [| for (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd) in pass1 do
+                      yield domainTy
+                      yield rangeTy
+                   yield body.Type |]
+
+            let B = Expr.NewDelegate(GetFuncType (Array.append vfdTys [| body.Type |]),vfds,body)
+            let BP = ConvExpr env B
+
+            let minfo = 
+                let q = 
+                    match vfds.Length with 
+                    | 1 -> <@@ LetRec1Helper @@>
+                    | 2 -> <@@ LetRec2Helper @@>
+                    | 3 -> <@@ LetRec3Helper @@>
+                    | 4 -> <@@ LetRec4Helper @@>
+                    | 5 -> <@@ LetRec5Helper @@>
+                    | 6 -> <@@ LetRec6Helper @@>
+                    | 7 -> <@@ LetRec7Helper @@>
+                    | 8 -> <@@ LetRec8Helper @@>
+                    | _ -> raise <| new NotSupportedException("In this release of the F# Power Pack, mutually recursive function groups involving 9 or more functions may not be converted to LINQ expressions")
+                match q with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+
+            let minfo = minfo.GetGenericMethodDefinition().MakeGenericMethod methTys
+            Expression.Call(minfo,Array.append FPs [| BP |]) |> asExpr
+
+        | Patterns.AddressOf _ -> raise <| new NotSupportedException("Address-of expressions may not be converted to LINQ expressions")
+        | Patterns.AddressSet _ -> raise <| new NotSupportedException("Address-set expressions may not be converted to LINQ expressions")
+        | Patterns.FieldSet _ -> raise <| new NotSupportedException("Field-set expressions may not be converted to LINQ expressions")
+
+        | _ -> 
+            raise <| new NotSupportedException(sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)
+
+    and ConvObjArg env objOpt coerceTo : Expression = 
+        match objOpt with
+        | Some(obj) -> 
+            let expr = ConvExpr env obj
+            match coerceTo with 
+            | None -> expr
+            | Some ty -> Expression.TypeAs(expr, ty) :> Expression
+        | None -> 
+            null
+
+    and ConvExprs env es : Expression[] = 
+        es |> List.map (ConvExpr env) |> Array.ofList 
+
+    and ConvVar (v: Var) = 
+        //printf "** Expression .Parameter(%a, %a)\n" output_any ty output_any nm;
+        Expression.Parameter(v.Type, v.Name)
+
+    let Conv (e: #Expr,eraseEquality) = ConvExpr { eraseEquality = eraseEquality; varEnv = Map.empty } (e :> Expr)
+
+    let CompileImpl (e: #Expr, eraseEquality) = 
+       let ty = e.Type
+       let e = Expr.NewDelegate(GetFuncType([|typeof<unit>; ty |]), [new Var("unit",typeof<unit>)],e)
+       let linqExpr = Conv (e,eraseEquality)
+       let linqExpr = (linqExpr :?> LambdaExpression)
+       let d = linqExpr.Compile()
+       (fun () -> 
+           try 
+             d.DynamicInvoke [| box () |]
+           with :? System.Reflection.TargetInvocationException as exn -> 
+               raise exn.InnerException)
+
+    let Compile (e: #Expr) = CompileImpl(e,false)
+
+    let Eval e = Compile e ()
+
+
+    type Microsoft.FSharp.Quotations.Expr with 
+        member x.ToLinqExpression() = Conv(x, false)
+        member x.CompileUntyped() = Compile(x)
+        member x.EvalUntyped() = Eval(x)
+
+    type Microsoft.FSharp.Quotations.Expr<'T> with 
+        member x.Compile() = 
+            let f = Compile(x)  
+            (fun () -> (f()) :?> 'T)
+        member x.Eval() = (Eval(x) :?> 'T)
+
+  
+open QuotationEvaluation
+  
+[<Sealed>]
+type QuotationEvaluator() = 
+
+    static member ToLinqExpression (e: Microsoft.FSharp.Quotations.Expr) = e.ToLinqExpression()
+
+   
+    static member CompileUntyped (e : Microsoft.FSharp.Quotations.Expr) = e.CompileUntyped()
+
+    static member EvaluateUntyped (e : Microsoft.FSharp.Quotations.Expr) = e.EvalUntyped()
+
+    static member internal EvaluateUntypedUsingQueryApproximations (e: Microsoft.FSharp.Quotations.Expr) = CompileImpl(e, true) ()
+
+    static member Compile (e : Microsoft.FSharp.Quotations.Expr<'T>) = e.Compile()
+
+    static member Evaluate (e : Microsoft.FSharp.Quotations.Expr<'T>) = e.Eval()
+
+    
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Linq/Linq.fsi b/src/FSharp.PowerPack.Linq/Linq.fsi
new file mode 100755
index 0000000..623a247
--- /dev/null
+++ b/src/FSharp.PowerPack.Linq/Linq.fsi
@@ -0,0 +1,164 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Linq
+
+    open System
+    open System.Linq.Expressions
+
+    module ExtraHashCompare =
+        /// An intrinsic for compiling <c><@ x <> y @></c> to expression trees
+        val GenericNotEqualIntrinsic : 'T -> 'T -> bool
+
+    [<Sealed>]
+    type QuotationEvaluator = 
+
+        /// Convert the quotation expression to LINQ expression trees
+        ///
+        /// This operation will only succeed for a subset of quotation expressions.
+        ///
+        /// Exceptions: InvalidArgumentException will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        static member ToLinqExpression : Microsoft.FSharp.Quotations.Expr -> System.Linq.Expressions.Expression
+
+        /// Compile the quotation expression by first converting to LINQ expression trees
+        ///
+        /// Exceptions: InvalidArgumentException will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        static member CompileUntyped : Microsoft.FSharp.Quotations.Expr -> (unit -> obj)
+
+        /// Compile the quotation expression by first converting to LINQ expression trees
+        ///
+        /// Exceptions: InvalidArgumentException will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        static member EvaluateUntyped : Microsoft.FSharp.Quotations.Expr -> obj
+
+        static member internal EvaluateUntypedUsingQueryApproximations : Microsoft.FSharp.Quotations.Expr -> obj
+    
+        /// Compile the quotation expression by first converting to LINQ expression trees
+        ///
+        /// Exceptions: InvalidArgumentException will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        static member Compile : Microsoft.FSharp.Quotations.Expr<'T> -> (unit -> 'T)
+
+        /// Evaluate the quotation expression by first converting to LINQ expression trees
+        ///
+        /// Exceptions: InvalidArgumentException will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        static member Evaluate : Microsoft.FSharp.Quotations.Expr<'T> -> 'T
+        
+    /// This module provides Compile and Eval extension members
+    /// for F# quotation values, implemented by translating to LINQ
+    /// expression trees and using the LINQ dynamic compiler.
+    module QuotationEvaluation =
+
+        type Microsoft.FSharp.Quotations.Expr with 
+              /// Convert the quotation expression to LINQ expression trees
+              ///
+              /// This operation will only succeed for a subset of quotation expressions.
+              ///
+              /// Exceptions: InvalidArgumentException will be raised if the input expression is
+              /// not in the subset that can be converted to a LINQ expression tree
+              member ToLinqExpression : unit -> System.Linq.Expressions.Expression
+
+              /// Compile the quotation expression by first converting to LINQ expression trees
+              ///
+              /// Exceptions: InvalidArgumentException will be raised if the input expression is
+              /// not in the subset that can be converted to a LINQ expression tree
+              member CompileUntyped : unit -> (unit -> obj)
+
+              /// Compile the quotation expression by first converting to LINQ expression trees
+              ///
+              /// Exceptions: InvalidArgumentException will be raised if the input expression is
+              /// not in the subset that can be converted to a LINQ expression tree
+              member EvalUntyped : unit -> obj
+
+        type Microsoft.FSharp.Quotations.Expr<'T> with 
+              /// Compile the quotation expression by first converting to LINQ expression trees
+              ///
+              /// Exceptions: InvalidArgumentException will be raised if the input expression is
+              /// not in the subset that can be converted to a LINQ expression tree
+              member Compile : unit -> (unit -> 'T)
+
+              /// Evaluate the quotation expression by first converting to LINQ expression trees
+              ///
+              /// Exceptions: InvalidArgumentException will be raised if the input expression is
+              /// not in the subset that can be converted to a LINQ expression tree
+              member Eval : unit -> 'T
+
+        /// This function should not be called directly. 
+        //
+        // NOTE: when an F# expression tree is converted to a Linq expression tree using ToLinqExpression 
+        // the transformation of <c>LinqExpressionHelper(e)</c> is simple the same as the transformation of
+        // 'e'. This allows LinqExpressionHelper to be used as a marker to satisfy the C# design where 
+        // certain expression trees are constructed using methods with a signature that expects an
+        // expression tree of type <c>Expression<T></c> but are passed an expression tree of type T.
+        val LinqExpressionHelper : 'T -> Expression<'T>
+
+        /// A set of types used for implementing quotation conversions.
+        /// These are public only because targets of Linq Lambda expressions require them to be so
+        module HelperTypes = 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 * 'T20 -> unit
+
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> 'T6
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> 'T7 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> 'T8 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> 'T9 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> 'T10 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> 'T11 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> 'T12 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> 'T13 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> 'T14 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> 'T15 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> 'T16 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> 'T17 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 -> 'T18 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 -> 'T19 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 -> 'T20 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20, 'T21> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 * 'T20 -> 'T21 
diff --git a/src/FSharp.PowerPack.Linq/LinqQueries.fs b/src/FSharp.PowerPack.Linq/LinqQueries.fs
new file mode 100755
index 0000000..ddb8f44
--- /dev/null
+++ b/src/FSharp.PowerPack.Linq/LinqQueries.fs
@@ -0,0 +1,781 @@
+// Copyright (c) Microsoft Corporation 2005-2008.
+// This sample code is provided "as is" without warranty of any kind. 
+// We disclaim all warranties, either express or implied, including the 
+// warranties of merchantability and fitness for a particular purpose. 
+//
+
+namespace Microsoft.FSharp.Linq
+
+open System
+open System.Linq
+open System.Collections.Generic
+open System.Linq.Expressions
+open System.Reflection
+open System.Reflection.Emit
+open Microsoft.FSharp
+open Microsoft.FSharp.Linq.QuotationEvaluation
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Quotations.Patterns
+open Microsoft.FSharp.Quotations.DerivedPatterns
+
+#nowarn "57"
+#nowarn "44" //deprecation 
+      
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Query =
+
+    let debug = false
+        
+    let contains key source = 
+        System.Linq.Enumerable.Contains(source,key)
+
+    let minBy<'T1,'T2> keySelector source = 
+        System.Linq.Enumerable.Min(source,Func<'T1,'T2>(keySelector))
+
+    let maxBy<'T1,'T2> keySelector source = 
+        System.Linq.Enumerable.Max(source,Func<'T1,'T2>(keySelector))
+
+    let groupBy keySelector source = 
+        System.Linq.Enumerable.GroupBy(source,Func<_,_>(keySelector))
+
+    let join  outerSource innerSource outerKeySelector innerKeySelector resultSelector = 
+        System.Linq.Enumerable.Join(outerSource,innerSource,Func<_,_>(outerKeySelector),Func<_,_>(innerKeySelector),Func<_,_,_>(resultSelector))
+
+    let groupJoin  outerSource innerSource outerKeySelector innerKeySelector resultSelector = 
+        System.Linq.Enumerable.GroupJoin(outerSource,innerSource,Func<_,_>(outerKeySelector),Func<_,_>(innerKeySelector),Func<_,_,_>(resultSelector))
+
+    let ConvVar (v: Var) = 
+        Expression.Parameter(v.Type, v.Name)
+
+    let asExpr x = (x :> Expression)
+            
+    let (|Getter|_|) (prop: #PropertyInfo) =
+        match prop.GetGetMethod(true) with 
+        | null -> None
+        | v -> Some v
+
+    let (|CallPipe|_|) = (|SpecificCall|_|) <@ (|>) @>
+    // Match 'f x' or 'x |> f' or 'x |> (fun x -> f (x :> ty))'
+    let (|SpecificPipedCall0|_|) q = 
+       let (|CallQ|_|) = (|SpecificCall|_|) q
+       function
+       | CallPipe (None, [_;_],[arg1;Lambda(arg1v,CallQ (None, tyargs,[arg1E])) ]) -> 
+           let arg1 = arg1E.Substitute (Map.ofSeq [ (arg1v,arg1) ]).TryFind 
+           Some(tyargs,arg1)
+
+       | CallQ (None, tyargs,[arg1]) -> 
+           Some(tyargs,arg1)
+
+       | _ -> None           
+
+    // Match 
+    //     'f x y' or 
+    //     'y |> f x' or
+    //     'y |> (fun y -> f (x :> ty) (y :> ty))'
+    //     'y |> let x = e in (fun y -> f (x :> ty) (y :> ty))'
+    let (|SpecificPipedCall1|_|) q = 
+       let (|CallQ|_|) = (|SpecificCall|_|) q
+       function
+       // Encoded form of some uses of 'T1rg2 |> f arg1'
+       | CallPipe (None, [_;_],[arg2;Let(arg1v,arg1,Lambda(arg2v,CallQ (None, tyargs,[arg1E;arg2E]))) ]) -> 
+              let arg1 = arg1E.Substitute (Map.ofSeq [ (arg1v,arg1) ]).TryFind 
+              let arg2 = arg2E.Substitute (Map.ofSeq [ (arg2v,arg2) ]).TryFind 
+              Some(tyargs,arg1,arg2)
+
+       | CallPipe (None, [_;_],[arg2;Lambda(arg2v,CallQ (None, tyargs,[arg1;arg2E])) ]) -> 
+              let arg2 = arg2E.Substitute (Map.ofSeq [ (arg2v,arg2) ]).TryFind 
+              Some(tyargs,arg1,arg2)
+
+       | CallQ (None, tyargs,[arg1;arg2]) -> 
+              Some(tyargs,arg1,arg2)
+       | _ -> None           
+
+        
+    let GetGenericMethodDefinition (m:MethodInfo) = 
+        if m.IsGenericMethod then m.GetGenericMethodDefinition() else m
+
+    let FindGenericStaticMethodInfo mexpr =
+        match mexpr with 
+        | Lambdas(_,Call(None,methInfo,_)) -> GetGenericMethodDefinition methInfo
+        | _ -> failwithf "FindGenericStaticMethodInfo: %A is not a static method call lambda" mexpr
+
+    let CallGenericStaticMethod mexpr  =
+        let m = FindGenericStaticMethodInfo mexpr in
+        //printf "m = %A\n" m;
+        fun (tyargs,args) -> 
+            //printf "invoking %A\n" m;
+            
+            let m = 
+                if m.IsGenericMethod then 
+                    m.MakeGenericMethod(Array.ofList tyargs) 
+                else
+                    m
+            m.Invoke(null,Array.ofList args)
+
+    let FT1 = typedefof<System.Func<_,_>>
+    let FT2 = typedefof<System.Func<_,_,_>>
+    let boolTy = typeof<bool>
+    let MakeQueryFuncTy (dty,rty) = FT1.MakeGenericType([| dty; rty |])
+    let MakeQueryFunc2Ty (dty1,dty2,rty) = FT2.MakeGenericType([| dty1; dty2; rty |])
+
+    let IEnumerableTypeDef = typedefof<IEnumerable<_>>
+    let IQueryableTypeDef = typedefof<IQueryable<_>>
+    let MakeIEnumerableTy dty= IEnumerableTypeDef.MakeGenericType([| dty|])
+    let MakeIQueryableTy dty= IQueryableTypeDef.MakeGenericType([| dty|])
+
+    let isNamedType(typ:Type) = not (typ.IsArray || typ.IsByRef || typ.IsPointer)
+    let equivHeadTypes (ty1:Type) (ty2:Type) = 
+        isNamedType(ty1) &&
+        if ty1.IsGenericType then 
+          ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition())
+        else 
+          ty1.Equals(ty2)
+
+    let IsIQueryableTy ty = equivHeadTypes IQueryableTypeDef ty
+   
+
+    let CallSeqToList = 
+        let F = CallGenericStaticMethod <@ Seq.toList @> 
+        fun (srcTy,src) -> 
+            F ([srcTy],[src])
+
+    let CallSeqToArray = 
+        let F = CallGenericStaticMethod <@ Seq.toArray @> 
+        fun (srcTy,src) -> 
+            F ([srcTy],[src])
+
+    let CallQueryableContains = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Contains : _ * _ -> _ @> 
+        fun (srcTy,src,key:Expression) -> 
+            F ([srcTy],[src;box key])
+
+    let CallQueryableMinBy = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Min : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,destTy,src,predicate:Expression) -> 
+            F ([srcTy;destTy],[src;box predicate])
+
+    let CallQueryableMin = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Min : _ -> _ @> 
+        fun (srcTy,src) -> 
+            F ([srcTy],[src])
+
+    let CallQueryableMaxBy = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Max : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,destTy,src,predicate:Expression) -> 
+            F ([srcTy;destTy],[src;box predicate])
+
+    let CallQueryableMax = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Max : _ -> _ @> 
+        fun (srcTy,src) -> 
+            F ([srcTy],[src])
+
+    let CallQueryableAverageBy = 
+        let F_float = CallGenericStaticMethod <@ System.Linq.Queryable.Average : _ * Expression<Func<_,float>> -> _ @> 
+        let F_float32 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : _ * Expression<Func<_,float32>> -> _ @> 
+        let F_decimal = CallGenericStaticMethod <@ System.Linq.Queryable.Average : _ * Expression<Func<_,decimal>> -> _ @> 
+        // Note these don't satisfy the F# constraints anyway
+        let F_int32 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : _ * Expression<Func<_,int32>> -> _ @> 
+        let F_int64 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : _ * Expression<Func<_,int64>> -> _ @> 
+        fun (srcTy,destTy,src,predicate:Expression) -> 
+            match srcTy with 
+            | ty when ty = typeof<float> -> F_float ([destTy],[src;box predicate])
+            | ty when ty = typeof<float32> -> F_float32 ([destTy],[src;box predicate])
+            | ty when ty = typeof<decimal> -> F_decimal ([destTy],[src;box predicate])
+            | ty when ty = typeof<int32> -> F_int32 ([destTy],[src;box predicate])
+            | ty when ty = typeof<int64> -> F_int64 ([destTy],[src;box predicate])
+            | _ -> failwith "unrecognized use of 'Seq.averageBy'"
+
+
+    let CallQueryableAverage = 
+        let F_float = CallGenericStaticMethod <@ System.Linq.Queryable.Average : IQueryable<float> -> _ @> 
+        let F_float32 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : IQueryable<float32>  -> _ @> 
+        let F_decimal = CallGenericStaticMethod <@ System.Linq.Queryable.Average : IQueryable<decimal>  -> _ @> 
+        // Note these don't satisfy the F# constraints anyway
+        let F_int32 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : IQueryable<int32>  -> _ @> 
+        let F_int64 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : IQueryable<int64>  -> _ @> 
+        fun (srcTy,src) -> 
+            match srcTy with 
+            | ty when ty = typeof<float> -> F_float ([],[src])
+            | ty when ty = typeof<float32> -> F_float32 ([],[src])
+            | ty when ty = typeof<decimal> -> F_decimal ([],[src])
+            | ty when ty = typeof<int32> -> F_int32 ([],[src])
+            | ty when ty = typeof<int64> -> F_int64 ([],[src])
+            | _ -> failwith "unrecognized use of 'Seq.average'"
+
+    let CallQueryableSumBy = 
+        let F_float = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : _ * Expression<Func<_,float>> -> _ @> 
+        let F_float32 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : _ * Expression<Func<_,float32>> -> _ @> 
+        let F_decimal = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : _ * Expression<Func<_,decimal>> -> _ @> 
+        let F_int32 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : _ * Expression<Func<_,int32>> -> _ @> 
+        let F_int64 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : _ * Expression<Func<_,int64>> -> _ @> 
+        fun (srcTy,destTy,src,predicate:Expression) -> 
+            match srcTy with 
+            | ty when ty = typeof<float> -> F_float ([destTy],[src;box predicate])
+            | ty when ty = typeof<float32> -> F_float32 ([destTy],[src;box predicate])
+            | ty when ty = typeof<decimal> -> F_decimal ([destTy],[src;box predicate])
+            | ty when ty = typeof<int32> -> F_int32 ([destTy],[src;box predicate])
+            | ty when ty = typeof<int64> -> F_int64 ([destTy],[src;box predicate])
+            | _ -> failwith "unrecognized use of 'Seq.sumBy'"
+
+    let CallQueryableSum = 
+        let F_float = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : IQueryable<float> -> _ @> 
+        let F_float32 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : IQueryable<float32>  -> _ @> 
+        let F_decimal = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : IQueryable<decimal>  -> _ @> 
+        // Note these don't satisfy the F# constraints anyway
+        let F_int32 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : IQueryable<int32>  -> _ @> 
+        let F_int64 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : IQueryable<int64>  -> _ @> 
+        fun (srcTy,src) -> 
+            match srcTy with 
+            | ty when ty = typeof<float> -> F_float ([],[src])
+            | ty when ty = typeof<float32> -> F_float32 ([],[src])
+            | ty when ty = typeof<decimal> -> F_decimal ([],[src])
+            | ty when ty = typeof<int32> -> F_int32 ([],[src])
+            | ty when ty = typeof<int64> -> F_int64 ([],[src])
+            | _ -> failwith "unrecognized use of 'Seq.sum"
+
+    let CallQueryableFirst = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.First : _ -> _ @> 
+        fun (srcTy,src) -> 
+            F ([srcTy],[src])
+
+    let CallQueryableFirstFind = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.First : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,src,predicate:Expression) -> 
+            F ([srcTy],[src;box predicate])
+
+    let CallQueryableCount = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Count : _ -> _ @> 
+        fun (srcTy:Type,src:obj) -> 
+            F ([srcTy],[src])
+
+    let BindGenericMethod (methInfo:MethodInfo) tyargs = 
+        if methInfo.IsGenericMethod then 
+            methInfo.GetGenericMethodDefinition().MakeGenericMethod(Array.ofList tyargs)
+        else
+            methInfo
+
+    let minfo = match <@@ LinqExpressionHelper @@> with Lambda(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find method info"
+    let MakeFakeExpression (x:Expr) = 
+        Expr.Call(minfo.GetGenericMethodDefinition().MakeGenericMethod [| x.Type |], [ x ])
+
+            
+    let MakeGenericStaticMethod lam  =
+        // Nb. the SelectMany/Where/Select methods theoretically expects an expression, but the
+        // LINQ team decided to only pass it a delegate construction. The coercion from
+        // the delegate construction to the expression is effectively implicit in LINQ, but
+        // not in F# quotations, so we have to use 'Unchecked' version (see also FSBUGS #970)
+        let methInfo = FindGenericStaticMethodInfo lam 
+        (fun (tyargs,args) -> Expr.Call(BindGenericMethod methInfo tyargs,args))
+           
+
+    let MakeQueryableSelect = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.Select : _ * Expression<Func<_,_>> -> _) @>
+        fun (srcTy,targetTy,src,v,f)  -> 
+            
+            let selector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,targetTy), v,f)
+
+            let selector = MakeFakeExpression selector
+            F ([srcTy;targetTy],[src;selector])
+
+    let MakeQueryableAppend = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.Concat ) @>
+        fun (srcTy,src1,src2)  -> 
+            F ([srcTy],[src1;src2])
+
+    let MakeQueryableContains = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.Contains : _ * _ -> _ ) @>
+        fun (srcTy,src1,src2)  -> 
+            F ([srcTy],[src1;src2])
+
+    let MakeQueryableAsQueryable = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.AsQueryable : seq<_>  -> IQueryable<_>) @>
+        fun (ty,src)  -> 
+            F ([ty],[src])
+
+    let MakeEnumerableEmpty = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Enumerable.Empty : unit -> seq<_>) @>
+        fun (ty)  -> 
+            F ([ty],[])
+
+    let MakeQueryableEmpty = 
+        fun (ty)  -> 
+            MakeQueryableAsQueryable (ty,MakeEnumerableEmpty ty)
+
+    let MakeQueryableSelectMany = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.SelectMany : IQueryable<_> * Expression<Func<_,_>> -> IQueryable<_>) @>
+        fun (srcTy,targetTy,src,v,f)  -> 
+            let selector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,MakeIEnumerableTy targetTy), [v],f)
+
+            let selector = MakeFakeExpression selector
+            F ([srcTy;targetTy],[src;selector])
+
+    let MakeQueryableWhere = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.Where : _ * Expression<Func<_,_>> -> _) @>
+        fun (srcTy,src,v,f)  -> 
+            let selector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,typeof<bool>), [v],f)
+
+            let selector = MakeFakeExpression selector
+            F ([srcTy],[src;selector])
+
+
+
+    let MakeQueryableOrderBy = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.OrderBy : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,keyTy,src,v,keySelector)  -> 
+            
+            let selector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,keyTy), [v],keySelector)
+
+            let selector = MakeFakeExpression selector
+            F ([srcTy;keyTy],[src;selector])
+
+    let MakeQueryableDistinct = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Distinct : _ -> _ @> 
+        fun (srcTy,src)  -> 
+            let src = Expr.Coerce(src,MakeIQueryableTy srcTy)
+            F ([srcTy],[src])
+
+    let MakeQueryableTake = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Take @> 
+        fun (srcTy,src,count)  -> 
+            let src = Expr.Coerce(src,MakeIQueryableTy srcTy)
+            F ([srcTy],[src;count])
+
+    let MakeQueryableGroupBy = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.GroupBy : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,keyTy,src,v,keySelector)  -> 
+            let keySelector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,keyTy), [v],keySelector) 
+
+            let keySelector = MakeFakeExpression keySelector
+            F ([srcTy;keyTy],[src;keySelector])
+
+    let MakeQueryableMinBy = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Min : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,keyTy,src,v,keySelector)  -> 
+            let keySelector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,keyTy), [v],keySelector) 
+
+            let keySelector = MakeFakeExpression keySelector
+            F ([srcTy;keyTy],[src;keySelector])
+
+    let MakeQueryableMaxBy = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Max : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,keyTy,src,v,keySelector)  -> 
+            let keySelector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,keyTy), [v],keySelector) 
+
+            let keySelector = MakeFakeExpression keySelector
+            F ([srcTy;keyTy],[src;keySelector])
+
+    let MakeQueryableAny = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Any : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,src,v,keySelector)  -> 
+            let keySelector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,boolTy), [v],keySelector) 
+
+            let keySelector = MakeFakeExpression keySelector
+            F ([srcTy],[src;keySelector])
+
+    let MakeQueryableAll = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.All : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,src,v,keySelector)  -> 
+            let keySelector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,boolTy), [v],keySelector) 
+
+            let keySelector = MakeFakeExpression keySelector
+            F ([srcTy],[src;keySelector])
+
+    let MakeQueryableJoin = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Join : _ * _ * Expression<Func<_,_>> * Expression<Func<_,_>> * Expression<Func<_,_,_>> -> _ @> 
+        fun (outerSourceTy,innerSourceTy,keyTy,resultTy,outerSource,innerSource,outerKeyVar,outerKeySelector,innerKeyVar,innerKeySelector,outerResultKeyVar,innerResultKeyVar,resultSelector)  -> 
+            let outerKeySelector = Expr.NewDelegate(MakeQueryFuncTy(outerSourceTy,keyTy), [outerKeyVar],outerKeySelector) |> MakeFakeExpression 
+            let innerKeySelector = Expr.NewDelegate(MakeQueryFuncTy(innerSourceTy,keyTy), [innerKeyVar],innerKeySelector) |> MakeFakeExpression 
+            let resultSelector = Expr.NewDelegate(MakeQueryFunc2Ty(outerSourceTy,innerSourceTy,resultTy), [outerResultKeyVar;innerResultKeyVar],resultSelector) |> MakeFakeExpression 
+            F ([outerSourceTy;innerSourceTy;keyTy;resultTy],[outerSource;innerSource;outerKeySelector;innerKeySelector;resultSelector])
+
+
+    let MakeQueryableGroupJoin = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.GroupJoin : _ * _ * Expression<Func<_,_>> * Expression<Func<_,_>> * Expression<Func<_,_,_>> -> _ @> 
+        fun (outerSourceTy,innerSourceTy,keyTy,resultTy,outerSource,innerSource,outerKeyVar,outerKeySelector,innerKeyVar,innerKeySelector,outerResultKeyVar,innerResultKeyVar,resultSelector)  -> 
+            let outerKeySelector = Expr.NewDelegate(MakeQueryFuncTy(outerSourceTy,keyTy), [outerKeyVar],outerKeySelector) |> MakeFakeExpression 
+            let innerKeySelector = Expr.NewDelegate(MakeQueryFuncTy(innerSourceTy,keyTy), [innerKeyVar],innerKeySelector) |> MakeFakeExpression 
+            let resultSelector = Expr.NewDelegate(MakeQueryFunc2Ty(outerSourceTy,MakeIEnumerableTy(innerSourceTy),resultTy), [outerResultKeyVar;innerResultKeyVar],resultSelector) |> MakeFakeExpression 
+            F ([outerSourceTy;innerSourceTy;keyTy;resultTy],[outerSource;innerSource;outerKeySelector;innerKeySelector;resultSelector])
+
+
+
+    let MakeLambda = 
+        let F = CallGenericStaticMethod <@ (fun (a:Expression,b:ParameterExpression[]) -> System.Linq.Expressions.Expression.Lambda<_>(a,b)) @> 
+        fun (srcTy,targetTy,arg:Expression,p:ParameterExpression) -> 
+            (F ([MakeQueryFuncTy(srcTy,targetTy)],[box arg;box [| p |] ]) :?> Expression)
+
+    /// Project F# function expressions to Linq LambdaExpression nodes
+    let FuncExprToLinqFunc2Expression (srcTy,targetTy,v,body) = 
+        Expr.NewDelegate(Linq.Expressions.Expression.GetFuncType [| srcTy; targetTy |], [v],body).ToLinqExpression()
+
+
+    let MakeMapConcat = 
+        let F = MakeGenericStaticMethod <@ Seq.collect @>
+        fun (srcTy,targetTy,f,src)  -> 
+            F ([srcTy;MakeIEnumerableTy targetTy;targetTy],[f;src])
+
+    let MakeFilter = 
+        let F = MakeGenericStaticMethod <@ Seq.filter @>
+        fun (srcTy,f,src)  -> 
+            F ([srcTy],[f;src])
+
+    let (|MacroReduction|_|) (p : Expr) = 
+        match p with 
+        | Applications(Lambdas(vs,body),args) when vs.Length = args.Length && List.forall2 (fun vs arg -> List.length vs = List.length args) vs args -> 
+            let tab = Map.ofSeq (List.concat (List.map2 List.zip vs args))
+            let body = body.Substitute tab.TryFind 
+            Some body
+
+        // Macro
+        | PropertyGet(None,Getter(MethodWithReflectedDefinition(body)),[]) -> 
+            Some body
+
+        // Macro
+        | Call(None,MethodWithReflectedDefinition(Lambdas(vs,body)),args) -> 
+            let tab = Map.ofSeq (List.concat (List.map2 (fun (vs:Var list) arg -> match vs,arg with [v],arg -> [(v,arg)] | vs,NewTuple(args) -> List.zip vs args | _ -> List.zip vs [arg]) vs args))
+            let body = body.Substitute tab.TryFind 
+            Some body
+
+        // Macro
+        | Let(v,e,body) ->
+            let tab = Map.ofSeq [ (v,e) ]
+            let body = body.Substitute tab.TryFind 
+            Some body
+        | _ -> None
+
+    let rec MacroExpand (p : Expr) = 
+        match p with 
+        // Macro reduction
+        | MacroReduction(reduced) -> 
+            MacroExpand reduced
+        | ExprShape.ShapeCombination(comb,args) ->
+            ExprShape.RebuildShapeCombination(comb, List.map MacroExpand args)
+        | ExprShape.ShapeLambda(v,body) ->
+            Expr.Lambda(v, MacroExpand body)
+        | ExprShape.ShapeVar _ -> p
+
+    let (|PipedCallMapConcat|_|) = (|SpecificPipedCall1|_|) <@ Seq.collect @>
+    let (|CallSingleton|_|) = (|SpecificCall|_|) <@ Seq.singleton @>
+    let (|CallEmpty|_|) = (|SpecificCall|_|) <@ Seq.empty @>
+    let (|PipedCallSort|_|) = (|SpecificPipedCall0|_|) <@ Seq.sort @>
+    let (|PipedCallSortBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.sortBy @>
+    let (|PipedCallSeqGroupBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.groupBy @>
+    let (|PipedCallSeqMinBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.minBy @>
+    let (|PipedCallSeqMaxBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.maxBy @>
+    let (|PipedCallQueryGroupBy|_|) = (|SpecificPipedCall1|_|) <@ groupBy @>
+    let (|PipedCallQueryMinBy|_|) = (|SpecificPipedCall1|_|) <@ minBy @>
+    let (|PipedCallQueryMaxBy|_|) = (|SpecificPipedCall1|_|) <@ maxBy @>
+    let (|PipedCallSeqMap|_|) = (|SpecificPipedCall1|_|) <@ Seq.map @>
+    let (|PipedCallSeqAppend|_|) = (|SpecificPipedCall1|_|) <@ Seq.append @>
+    let (|PipedCallSeqFilter|_|) = (|SpecificPipedCall1|_|) <@ Seq.filter @>
+    let (|PipedCallSeqExists|_|) = (|SpecificPipedCall1|_|) <@ Seq.exists @>
+    let (|PipedCallSeqForAll|_|) = (|SpecificPipedCall1|_|) <@ Seq.forall @>
+    let (|PipedCallSeqDelay|_|) = (|SpecificPipedCall0|_|) <@ Seq.delay @>
+    let (|PipedCallSeqDistinct|_|) = (|SpecificPipedCall0|_|) <@ Seq.distinct @>
+    let (|PipedCallSeqToList|_|) = (|SpecificPipedCall0|_|) <@ Seq.toList @>
+    let (|PipedCallSeqTake|_|) = (|SpecificPipedCall1|_|) <@ Seq.take @>
+    let (|PipedCallSeqTruncate|_|) = (|SpecificPipedCall1|_|) <@ Seq.truncate @>
+    let (|PipedCallSeqToArray|_|) = (|SpecificPipedCall0|_|) <@ Seq.toArray @>
+    let (|PipedCallSeqMin|_|) = (|SpecificPipedCall0|_|) <@ Seq.min @>
+    let (|PipedCallSeqMax|_|) = (|SpecificPipedCall0|_|) <@ Seq.max @>
+    let (|PipedCallQueryContains|_|) = (|SpecificPipedCall1|_|) <@ contains @>
+    let (|CallSeq|_|) = (|SpecificCall|_|) <@ seq @>
+    let (|CallQueryJoin|_|) = (|SpecificCall|_|) <@ join @>
+    let (|CallQueryGroupJoin|_|) = (|SpecificCall|_|) <@ groupJoin @>
+    let (|PipedCallAverageBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.averageBy : (float -> float) -> seq<float> -> float @> 
+    let (|PipedCallAverage|_|) = (|SpecificPipedCall0|_|) <@ Seq.average: seq<float> -> float @>
+    let (|PipedCallSumBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.sumBy : (float -> float) -> seq<float> -> float @>
+    let (|PipedCallSum|_|) = (|SpecificPipedCall0|_|) <@ Seq.sum: seq<float> -> float @>
+    let (|PipedCallSeqLength|_|) = (|SpecificPipedCall0|_|) <@ Seq.length @>
+    let (|PipedCallSeqHead|_|) = (|SpecificPipedCall0|_|) <@ Seq.head @>
+    let (|PipedCallSeqFind|_|) = (|SpecificPipedCall1|_|) <@ Seq.find @>
+
+    let query (p : Expr<'T1>) : 'T1 = 
+
+        let body = (p :> Expr)
+        let rec TransInner (tm:Expr) = 
+            match tm with 
+            // Look through coercions, e.g. to IEnumerable 
+            | Coerce (expr,ty) -> 
+                TransInner expr
+            
+            // Seq.collect (fun x -> if P x then tgt else Seq.empty)  sq @> 
+            //    ~~> TRANS(Seq.collect (x -> tgt) (sq.Where(x -> P x))
+            | PipedCallMapConcat ([srcTy;_;targetTy],Lambda(selectorVar, selector),sq) ->
+                let rec TransMapConcatSelector t = 
+                    match t with 
+                    | CallSingleton(None, _,[res]) -> 
+
+                        MakeQueryableSelect(srcTy,targetTy, TransInner sq, [selectorVar],MacroExpand res)
+
+
+                    | IfThenElse(g,tgt,CallEmpty (None, [_],[])) ->
+
+                        let sq = MakeFilter(srcTy,Expr.Lambda(selectorVar,g),sq)
+                        let sq = TransInner (MakeMapConcat(srcTy,targetTy,Expr.Lambda(selectorVar,tgt),sq))
+                        sq
+
+                    | MacroReduction(reduced) -> 
+                        TransMapConcatSelector reduced
+
+                    | selectorBody ->
+                        let selectorBody = TransInner selectorBody
+                        // For some reason IQueryable.SelectMany expects an IEnumerable return
+                        let selectorBody = Expr.Coerce(TransInner selectorBody,MakeIEnumerableTy targetTy)
+                        MakeQueryableSelectMany(srcTy,targetTy, TransInner sq, selectorVar,selectorBody)
+
+                TransMapConcatSelector selector
+            
+            | PipedCallSeqMap ([srcTy;targetTy],Lambda(v,res),sq) ->
+        
+                MakeQueryableSelect(srcTy,targetTy, TransInner sq, [v],MacroExpand res)
+
+            | PipedCallSeqAppend ([srcTy],sq1,sq2) ->
+        
+                MakeQueryableAppend(srcTy, TransInner sq1, TransInner sq2)
+
+            // These occur in the F# quotation form of F# sequence expressions            
+            | PipedCallSeqFilter ([srcTy],Lambda(v,res),sq) ->
+
+                MakeQueryableWhere(srcTy, TransInner sq, v,MacroExpand res)
+
+            // These occur in the F# quotation form of F# sequence expressions            
+            | PipedCallSeqDelay (_,Lambda(_,body)) ->
+        
+                TransInner body
+            
+            // These occur in the F# quotation form of F# sequence expressions            
+            | CallSeq (None, _,[body]) ->
+        
+                TransInner body
+
+                
+            | IfThenElse(g,t,e) ->
+
+                Expr.IfThenElse(g,TransInner t, TransInner e)
+
+
+            // These occur in the F# quotation form of F# sequence expressions            
+            | CallEmpty (None, [ty],[]) ->
+        
+                MakeQueryableEmpty ty
+
+
+            | PipedCallSortBy([ srcTy; keyTy ],Lambda(v,keySelector),source) ->
+
+                MakeQueryableOrderBy(srcTy,keyTy, TransInner source, v,MacroExpand keySelector)
+
+            | PipedCallSort([ srcTy ],source) ->
+
+                let v = new Var("x",srcTy)
+                MakeQueryableOrderBy(srcTy,srcTy, TransInner source, v,Expr.Var v)
+
+            | PipedCallSeqGroupBy _ ->
+
+                failwithf "The operator Seq.groupBy may not be used in queries. Use Microsoft.FSharp.Linq.Query.groupNy instead, which has a different return type to the standard F# operator" tm 
+
+            | PipedCallQueryGroupBy([ srcTy; keyTy ],Lambda(v,keySelector),source) ->
+
+                MakeQueryableGroupBy(srcTy,keyTy, TransInner source, v,MacroExpand keySelector)
+
+            | PipedCallSeqMinBy _ ->
+
+                failwithf "The operator Seq.minBy may not be used in queries. Use Microsoft.FSharp.Linq.Query.minBy instead, which has a different return type to the standard F# operator" tm 
+
+            | PipedCallQueryMinBy([ srcTy; keyTy ],Lambda(v,keySelector),source) ->
+
+                MakeQueryableMinBy(srcTy,keyTy, TransInner source, v,MacroExpand keySelector)
+
+            | PipedCallSeqMaxBy _ ->
+
+                failwithf "The operator Seq.maxBy may not be used in queries. Use Microsoft.FSharp.Linq.Query.maxBy instead, which has a different return type to the standard F# operator" tm 
+
+            | PipedCallQueryMaxBy([ srcTy; keyTy ],Lambda(v,keySelector),source) ->
+
+                MakeQueryableMaxBy(srcTy,keyTy, TransInner source, v,MacroExpand keySelector)
+
+            | PipedCallSeqExists([ srcTy],Lambda(v,keySelector),source) ->
+
+                MakeQueryableAny(srcTy,TransInner source, v,MacroExpand keySelector)
+
+            | PipedCallSeqForAll([ srcTy],Lambda(v,keySelector),source) ->
+
+                MakeQueryableAll(srcTy,TransInner source, v,MacroExpand keySelector)
+
+            | CallQueryJoin(None, [ outerSourceTy;innerSourceTy;keyTy;resultTy ],[outerSource;innerSource;Lambda(outerKeyVar,outerKeySelector);Lambda(innerKeyVar,innerKeySelector);Lambdas([[outerResultKeyVar];[innerResultKeyVar]],resultSelector)])->
+
+                MakeQueryableJoin(outerSourceTy,innerSourceTy,keyTy,resultTy,TransInner outerSource,TransInner innerSource,outerKeyVar,MacroExpand outerKeySelector,innerKeyVar,MacroExpand innerKeySelector,outerResultKeyVar,innerResultKeyVar,MacroExpand resultSelector)  
+
+            | CallQueryGroupJoin(None, [ outerSourceTy;innerSourceTy;keyTy;resultTy ],[outerSource;innerSource;Lambda(outerKeyVar,outerKeySelector);Lambda(innerKeyVar,innerKeySelector);Lambdas([[outerResultKeyVar];[innerResultKeyVar]],resultSelector)])->
+
+                MakeQueryableGroupJoin(outerSourceTy,innerSourceTy,keyTy,resultTy,TransInner outerSource,TransInner innerSource,outerKeyVar,MacroExpand outerKeySelector,innerKeyVar,MacroExpand innerKeySelector,outerResultKeyVar,innerResultKeyVar,MacroExpand resultSelector)  
+
+            | PipedCallSeqDistinct([ srcTy ],source) ->
+                MakeQueryableDistinct(srcTy, TransInner source)
+
+
+            | PipedCallSeqTake([ srcTy ],count,sq) 
+            | PipedCallSeqTruncate([ srcTy ],count,sq) ->
+                MakeQueryableTake(srcTy, TransInner sq, MacroExpand count)
+
+            | MacroReduction(reduced) -> 
+                TransInner reduced
+
+            // These occur in the F# quotation form of F# sequence expressions            
+            //
+            //       match i.Data with 
+            //       | 8 -> ...
+            //       | _ -> ()
+            | Sequential(Value( _, unitType), sq) when unitType  = typeof<unit> -> 
+        
+                TransInner sq
+
+            | expr when typeof<IQueryable>.IsAssignableFrom(expr.Type) ->
+                expr
+
+
+            // Error cases
+            | _  -> 
+                failwithf "The following construct was used in query but is not recognised by the F#-to-LINQ query translator:\n%A\nThis is not a valid query expression. Check the specification of permitted queries and consider moving some of the query out of the quotation" tm 
+
+        let EvalInner (tm:Expr) = TransInner tm |> QuotationEvaluator.EvaluateUntypedUsingQueryApproximations
+
+        let rec EvalOuterWithPostProcess (tm:Expr) = 
+            match tm with
+            
+            // Allow SQL <@ [ for x in ... ] @>
+            | PipedCallSeqToList ([srcTy],sq) ->
+        
+                CallSeqToList (srcTy,EvalInner sq)
+
+            | PipedCallSeqToArray ([srcTy],sq) ->
+        
+                CallSeqToArray (srcTy,EvalInner sq)
+
+
+            | PipedCallSeqMin ([srcTy],sq) ->
+
+                CallQueryableMin(srcTy,EvalInner sq)
+
+            | PipedCallSeqMax ([srcTy],sq) ->
+
+                CallQueryableMax(srcTy,EvalInner sq)
+
+            | PipedCallQueryContains ([srcTy],v,sq) ->
+
+                CallQueryableContains(srcTy,EvalInner sq,(MacroExpand v).ToLinqExpression())
+
+            | PipedCallAverageBy([srcTy;destTy],Lambda(v,res),sq) ->
+
+                CallQueryableAverageBy(srcTy, destTy, EvalInner sq, FuncExprToLinqFunc2Expression (srcTy,destTy,v,MacroExpand  res))
+
+            | PipedCallAverage ([srcTy],sq) ->
+
+                CallQueryableAverage(srcTy, EvalInner sq)
+
+            | PipedCallSumBy ([srcTy;destTy],Lambda(v,res),sq) ->
+
+                CallQueryableSumBy(srcTy, destTy, EvalInner sq, FuncExprToLinqFunc2Expression (srcTy,destTy,v,MacroExpand  res))
+
+            | PipedCallSum ([srcTy],sq) ->
+
+                CallQueryableSum(srcTy, EvalInner sq)
+
+            | PipedCallSeqLength ([ srcTy ],sq) ->
+                CallQueryableCount(srcTy, EvalInner sq)
+
+            | PipedCallSeqHead ([ srcTy ],sq) ->
+                CallQueryableFirst(srcTy, EvalInner sq)
+
+            | PipedCallSeqFind([ srcTy ],sq, NewDelegate(_,[v],f)) ->
+                CallQueryableFirstFind(srcTy, EvalInner sq, FuncExprToLinqFunc2Expression (srcTy,boolTy,v,MacroExpand f))
+
+            | MacroReduction(reduced) -> 
+                EvalOuterWithPostProcess reduced
+
+            | _  -> 
+                EvalInner tm
+        
+        let res = EvalOuterWithPostProcess body 
+        unbox res
+
+
+    let SQL x = query x
+
+
+    
+    
+
+    //-------------------------------------------------------------------------
+    // Nullable utilities for F#
+
+(*
+
+    /// This operator compares Nullable values with non-Nullable values using
+    /// structural comparison
+    [<ReflectedDefinition>]
+    let (>=?!) (x : Nullable<'T1>) (y: 'T1) = 
+        x.HasValue && x.Value >= y
+
+    [<ReflectedDefinition>]
+    let (>?!) (x : Nullable<'T1>) (y: 'T1) = 
+        x.HasValue && x.Value > y
+
+    [<ReflectedDefinition>]
+    let (<=?!) (x : Nullable<'T1>) (y: 'T1) = 
+        not x.HasValue || x.Value <= y
+
+    [<ReflectedDefinition>]
+    let (<?!) (x : Nullable<'T1>) (y: 'T1) = 
+        not x.HasValue || x.Value < y
+
+    [<ReflectedDefinition>]
+    let (=?!) (x : Nullable<'T1>) (y: 'T1) = 
+        x.HasValue && x.Value = y
+
+    [<ReflectedDefinition>]
+    let (<>?!) (x : Nullable<'T1>) (y: 'T1) = 
+        not x.HasValue or x.Value <> y
+
+    /// This overloaded operator divides Nullable values by non-Nullable values
+    /// using the overloaded operator "/".  Inlined to allow use over any type,
+    /// as this resolves the overloading on "/".
+    [<ReflectedDefinition>]
+    let inline (/?!) (x : Nullable<'T1>) (y: 'T1) = 
+        if x.HasValue then new Nullable<'T1>(x.Value / y)
+        else x
+
+    /// This overloaded operator adds Nullable values by non-Nullable values
+    /// using the overloaded operator "+".  Inlined to allow use over any type,
+    /// as this resolves the overloading on "+".
+    [<ReflectedDefinition>]
+    let inline (+?!) (x : Nullable<'T1>) (y: 'T1) = 
+        if x.HasValue then new Nullable<'T1>(x.Value + y)
+        else x
+
+    /// This overloaded operator adds Nullable values by non-Nullable values
+    /// using the overloaded operator "-".  Inlined to allow use over any type,
+    /// as this resolves the overloading on "-".
+    [<ReflectedDefinition>]
+    let inline (-?!) (x : Nullable<'T1>) (y: 'T1) = 
+        if x.HasValue then new Nullable<'T1>(x.Value - y)
+        else x
+
+    /// This overloaded operator adds Nullable values by non-Nullable values
+    /// using the overloaded operator "*".  Inlined to allow use over any type,
+    /// as this resolves the overloading on "*".
+    [<ReflectedDefinition>]
+    let inline ( *?!) (x : Nullable<'T1>) (y: 'T1) = 
+        if x.HasValue then new Nullable<'T1>(x.Value * y)
+        else x
+
+    /// This overloaded operator adds Nullable values by non-Nullable values
+    /// using the overloaded operator "%".  Inlined to allow use over any type,
+    /// as this resolves the overloading on "%".
+    [<ReflectedDefinition>]
+    let inline ( %?!) (x : Nullable<'T1>) (y: 'T1) = 
+        if x.HasValue then new Nullable<'T1>(x.Value % y)
+        else x
+
+*)
+    
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Linq/LinqQueries.fsi b/src/FSharp.PowerPack.Linq/LinqQueries.fsi
new file mode 100755
index 0000000..3f07d90
--- /dev/null
+++ b/src/FSharp.PowerPack.Linq/LinqQueries.fsi
@@ -0,0 +1,62 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Linq
+
+    open System
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Query =
+
+        /// Evaluate the quotation expression by first converting to a LINQ expression tree
+        /// making use of IQueryable operators and then executing expression tree
+        ///
+        /// Exceptions: <c>InvalidArgumentException</c> will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        val query : Quotations.Expr<'T> -> 'T
+
+
+        /// When used in queries, this operator corresponds to the LINQ Contains operator and the <c>query</c> convertor recognises it as such
+        val contains : 
+            key:'T -> 
+            source:seq<'T> -> 
+               bool
+
+        /// When used in queries, this operator corresponds to the LINQ Min operator and the <c>query</c> convertor recognises it as such
+        /// It differs in return type from <c>Seq.minBy</c>
+        val minBy : 
+            keySelector:('T -> 'Key) -> 
+            source:seq<'T> -> 
+               'Key
+
+        /// When used in queries, this operator corresponds to the LINQ Max operator and the <c>query</c> convertor recognises it as such
+        /// It differs in return type from <c>Seq.maxBy</c>
+        val maxBy : 
+            keySelector:('T -> 'Key) -> 
+            source:seq<'T> -> 
+               'Key
+
+        /// When used in queries, this operator corresponds to the LINQ Join operator and the <c>query</c> convertor recognises it as such
+        val groupBy : 
+            keySelector:('T -> 'Key) -> 
+            source:seq<'T> -> 
+               seq<System.Linq.IGrouping<'Key,'T>>
+
+        /// This join operator corresponds to the LINQ Join operator and the <c>query</c> convertor recognises it as such
+        val join : 
+            outerSource:seq<'Outer> -> 
+            innerSource:seq<'Inner> -> 
+            outerKeySelector:('Outer -> 'Key) -> 
+            innerKeySelector:('Inner -> 'Key) -> 
+            resultSelector:('Outer -> 'Inner -> 'Result) ->
+               seq<'Result>
+
+
+        /// This join operator implements the LINQ GroupJoin operator and the <c>query</c> convertor recognises it as such
+        val groupJoin : 
+            outerSource:seq<'Outer> -> 
+            innerSource:seq<'Inner> -> 
+            outerKeySelector:('Outer -> 'Key) -> 
+            innerKeySelector:('Inner -> 'Key) -> 
+            resultSelector:('Outer -> seq<'Inner> -> 'Result) ->
+               seq<'Result>
+
diff --git a/src/FSharp.PowerPack.Linq/assemblyinfo.FSharp.PowerPack.Linq.dll.fs b/src/FSharp.PowerPack.Linq/assemblyinfo.FSharp.PowerPack.Linq.dll.fs
new file mode 100755
index 0000000..2f0f65c
--- /dev/null
+++ b/src/FSharp.PowerPack.Linq/assemblyinfo.FSharp.PowerPack.Linq.dll.fs
@@ -0,0 +1,7 @@
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("FSharp.PowerPack.Linq.dll")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("FSharp.PowerPack.Linq.dll")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
diff --git a/src/FSharp.PowerPack.Metadata/FSComp.fs b/src/FSharp.PowerPack.Metadata/FSComp.fs
new file mode 100755
index 0000000..a3c7084
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/FSComp.fs
@@ -0,0 +1,4243 @@
+// This is a generated file; the original input is 'C:\fsharp\staging\src\fsharp\FSComp.txt'
+namespace FSComp
+            
+open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
+open Microsoft.FSharp.Reflection
+open System.Reflection
+// (namespaces below for specific case of using the tool to compile FSharp.Core itself)
+open Microsoft.FSharp.Core
+open Microsoft.FSharp.Core.Operators
+open Microsoft.FSharp.Text
+open Microsoft.FSharp.Collections
+open Printf
+
+type internal SR private() =
+            
+    // BEGIN BOILERPLATE        
+    static let resources = lazy (new System.Resources.ResourceManager("FSComp", System.Reflection.Assembly.GetExecutingAssembly()))
+
+    static let GetString(name:string) =        
+        let s = resources.Value.GetString(name, System.Globalization.CultureInfo.CurrentUICulture)
+#if DEBUG
+        if null = s then
+            System.Diagnostics.Debug.Assert(false, sprintf "**RESOURCE ERROR**: Resource token %s does not exist!" name)
+#endif
+        s
+
+    static let mkFunctionValue (tys: System.Type[]) (impl:obj->obj) = 
+        FSharpValue.MakeFunction(FSharpType.MakeFunctionType(tys.[0],tys.[1]), impl)
+        
+    static let funTyC = typeof<(obj -> obj)>.GetGenericTypeDefinition()  
+
+    static let isNamedType(ty:System.Type) = not (ty.IsArray ||  ty.IsByRef ||  ty.IsPointer)
+    static let isFunctionType (ty1:System.Type)  = 
+        isNamedType(ty1) && ty1.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(funTyC)
+
+    static let rec destFunTy (ty:System.Type) =
+        if isFunctionType ty then 
+            ty, ty.GetGenericArguments() 
+        else
+            match ty.BaseType with 
+            | null -> failwith "destFunTy: not a function type" 
+            | b -> destFunTy b 
+
+    static let buildFunctionForOneArgPat (ty: System.Type) impl = 
+        let _,tys = destFunTy ty 
+        let rty = tys.[1]
+        // PERF: this technique is a bit slow (e.g. in simple cases, like 'sprintf "%x"') 
+        mkFunctionValue tys (fun inp -> impl rty inp)
+                
+    static let capture1 (fmt:string) i args ty (go : obj list -> System.Type -> int -> obj) : obj = 
+        match fmt.[i] with
+        | '%' -> go args ty (i+1) 
+        | 'd'
+        | 'f'
+        | 's' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
+        | _ -> failwith "bad format specifier"
+        
+    // newlines and tabs get converted to strings when read from a resource file
+    // this will preserve their original intention    
+    static let postProcessString (s : string) =
+        s.Replace("\\n","\n").Replace("\\t","\t").Replace("\\r","\r").Replace("\\\"", "\"")
+        
+    static let createMessageString (messageString : string) (fmt : Printf.StringFormat<'T>) : 'T = 
+        let fmt = fmt.Value // here, we use the actual error string, as opposed to the one stored as fmt
+        let len = fmt.Length 
+
+        /// Function to capture the arguments and then run.
+        let rec capture args ty i = 
+            if i >= len ||  (fmt.[i] = '%' && i+1 >= len) then 
+                let b = new System.Text.StringBuilder()    
+                b.AppendFormat(messageString, [| for x in List.rev args -> x |]) |> ignore
+                box(b.ToString())
+            elif System.Char.IsSurrogatePair(fmt,i) then 
+               capture args ty (i+2)
+            else
+                match fmt.[i] with
+                | '%' ->
+                    let i = i+1 
+                    capture1 fmt i args ty capture
+                | _ ->
+                    capture args ty (i+1) 
+
+        (unbox (capture [] (typeof<'T>) 0) : 'T)
+
+    static let mutable swallowResourceText = false
+    
+    static let GetStringFunc((messageID : string),(fmt : Printf.StringFormat<'T>)) : 'T =
+        if swallowResourceText then
+            sprintf fmt
+        else
+            let mutable messageString = GetString(messageID)
+            messageString <- postProcessString messageString                            
+            createMessageString messageString fmt
+        
+    /// If set to true, then all error messages will just return the filled 'holes' delimited by ',,,'s - this is for language-neutral testing (e.g. localization-invariant baselines).
+    static member SwallowResourceText with get () = swallowResourceText
+                                      and set (b) = swallowResourceText <- b
+    // END BOILERPLATE        
+    
+    /// The namespace '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:2)
+    static member undefinedNameNamespace(a0 : System.String) = (GetStringFunc("undefinedNameNamespace",",,,%s,,,") a0)
+    /// The namespace or module '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:3)
+    static member undefinedNameNamespaceOrModule(a0 : System.String) = (GetStringFunc("undefinedNameNamespaceOrModule",",,,%s,,,") a0)
+    /// The field, constructor or member '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:4)
+    static member undefinedNameFieldConstructorOrMember(a0 : System.String) = (GetStringFunc("undefinedNameFieldConstructorOrMember",",,,%s,,,") a0)
+    /// The value, constructor, namespace or type '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:5)
+    static member undefinedNameValueConstructorNamespaceOrType(a0 : System.String) = (GetStringFunc("undefinedNameValueConstructorNamespaceOrType",",,,%s,,,") a0)
+    /// The value or constructor '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:6)
+    static member undefinedNameValueOfConstructor(a0 : System.String) = (GetStringFunc("undefinedNameValueOfConstructor",",,,%s,,,") a0)
+    /// The value, namespace, type or module '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:7)
+    static member undefinedNameValueNamespaceTypeOrModule(a0 : System.String) = (GetStringFunc("undefinedNameValueNamespaceTypeOrModule",",,,%s,,,") a0)
+    /// The constructor, module or namespace '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:8)
+    static member undefinedNameConstructorModuleOrNamespace(a0 : System.String) = (GetStringFunc("undefinedNameConstructorModuleOrNamespace",",,,%s,,,") a0)
+    /// The type '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:9)
+    static member undefinedNameType(a0 : System.String) = (GetStringFunc("undefinedNameType",",,,%s,,,") a0)
+    /// The record label or namespace '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:10)
+    static member undefinedNameRecordLabelOrNamespace(a0 : System.String) = (GetStringFunc("undefinedNameRecordLabelOrNamespace",",,,%s,,,") a0)
+    /// The record label '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:11)
+    static member undefinedNameRecordLabel(a0 : System.String) = (GetStringFunc("undefinedNameRecordLabel",",,,%s,,,") a0)
+    /// The type parameter '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:12)
+    static member undefinedNameTypeParameter(a0 : System.String) = (GetStringFunc("undefinedNameTypeParameter",",,,%s,,,") a0)
+    /// The pattern discriminator '%s' is not defined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:13)
+    static member undefinedNamePatternDiscriminator(a0 : System.String) = (GetStringFunc("undefinedNamePatternDiscriminator",",,,%s,,,") a0)
+    /// The non-generic type '%s' does not expect any type arguments, but here is given %d type argument(s)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:17)
+    static member buildUnexpectedTypeArgs(a0 : System.String, a1 : System.Int32) = (GetStringFunc("buildUnexpectedTypeArgs",",,,%s,,,%d,,,") a0 a1)
+    /// Invalid warning number '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:18)
+    static member buildInvalidWarningNumber(a0 : System.String) = (203, GetStringFunc("buildInvalidWarningNumber",",,,%s,,,") a0)
+    /// Invalid version string '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:19)
+    static member buildInvalidVersionString(a0 : System.String) = (204, GetStringFunc("buildInvalidVersionString",",,,%s,,,") a0)
+    /// Invalid version file '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:20)
+    static member buildInvalidVersionFile(a0 : System.String) = (205, GetStringFunc("buildInvalidVersionFile",",,,%s,,,") a0)
+    /// Microsoft (R) F# 2.0 Compiler build %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:21)
+    static member buildProductName(a0 : System.String) = (GetStringFunc("buildProductName",",,,%s,,,") a0)
+    /// Problem with filename '%s': %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:22)
+    static member buildProblemWithFilename(a0 : System.String, a1 : System.String) = (206, GetStringFunc("buildProblemWithFilename",",,,%s,,,%s,,,") a0 a1)
+    /// No inputs specified
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:23)
+    static member buildNoInputsSpecified() = (207, GetStringFunc("buildNoInputsSpecified",",,,") )
+    /// The output name extension doesn't match the options used. If '-a' or '--target:library' is used the output file name must end with '.dll', if '--target:module' is used the output extension must be '.netmodule', otherwise '.exe'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:24)
+    static member buildMismatchOutputExtension() = (208, GetStringFunc("buildMismatchOutputExtension",",,,") )
+    /// The '--pdb' option requires the '--debug' option to be used
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:25)
+    static member buildPdbRequiresDebug() = (209, GetStringFunc("buildPdbRequiresDebug",",,,") )
+    /// The search directory '%s' is invalid
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:26)
+    static member buildInvalidSearchDirectory(a0 : System.String) = (210, GetStringFunc("buildInvalidSearchDirectory",",,,%s,,,") a0)
+    /// The search directory '%s' could not be found
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:27)
+    static member buildSearchDirectoryNotFound(a0 : System.String) = (211, GetStringFunc("buildSearchDirectoryNotFound",",,,%s,,,") a0)
+    /// '%s' is not a valid filename
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:28)
+    static member buildInvalidFilename(a0 : System.String) = (212, GetStringFunc("buildInvalidFilename",",,,%s,,,") a0)
+    /// '%s' is not a valid assembly name
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:29)
+    static member buildInvalidAssemblyName(a0 : System.String) = (213, GetStringFunc("buildInvalidAssemblyName",",,,%s,,,") a0)
+    /// Unrecognized privacy setting '%s' for managed resource, valid options are 'public' and 'private'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:30)
+    static member buildInvalidPrivacy(a0 : System.String) = (214, GetStringFunc("buildInvalidPrivacy",",,,%s,,,") a0)
+    /// Multiple references to '%s.dll' are not permitted
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:31)
+    static member buildMultipleReferencesNotAllowed(a0 : System.String) = (215, GetStringFunc("buildMultipleReferencesNotAllowed",",,,%s,,,") a0)
+    /// The file '%s' is a CLI 1.x version of mscorlib. F# requires CLI version 2.0 or greater.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:32)
+    static member buildRequiresCLI2(a0 : System.String) = (216, GetStringFunc("buildRequiresCLI2",",,,%s,,,") a0)
+    /// Could not read version from mscorlib.dll
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:33)
+    static member buildCouldNotReadVersionInfoFromMscorlib() = (GetStringFunc("buildCouldNotReadVersionInfoFromMscorlib",",,,") )
+    /// The referenced or default base CLI library 'mscorlib' is binary-incompatible with the referenced library '%s'. Consider recompiling the library or making an explicit reference to a version of this library that matches the CLI version you are using.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:34)
+    static member buildMscorlibAndReferencedAssemblyMismatch(a0 : System.String) = (217, GetStringFunc("buildMscorlibAndReferencedAssemblyMismatch",",,,%s,,,") a0)
+    /// Unable to read assembly '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:35)
+    static member buildCannotReadAssembly(a0 : System.String) = (218, GetStringFunc("buildCannotReadAssembly",",,,%s,,,") a0)
+    /// The referenced or default base CLI library 'mscorlib' is binary-incompatible with the referenced F# core library '%s'. Consider recompiling the library or making an explicit reference to a version of this library that matches the CLI version you are using.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:36)
+    static member buildMscorLibAndFSharpCoreMismatch(a0 : System.String) = (219, GetStringFunc("buildMscorLibAndFSharpCoreMismatch",",,,%s,,,") a0)
+    /// Assembly resolution failure at or near this location
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:37)
+    static member buildAssemblyResolutionFailed() = (220, GetStringFunc("buildAssemblyResolutionFailed",",,,") )
+    /// The declarations in this file will be placed in an implicit module '%s' based on the file name '%s'. However this is not a valid F# identifier, so the contents will not be accessible from other files. Consider renaming the file or adding a 'module' or 'namespace' declaration at the top of the file.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:38)
+    static member buildImplicitModuleIsNotLegalIdentifier(a0 : System.String, a1 : System.String) = (221, GetStringFunc("buildImplicitModuleIsNotLegalIdentifier",",,,%s,,,%s,,,") a0 a1)
+    /// Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:39)
+    static member buildMultiFileRequiresNamespaceOrModule() = (222, GetStringFunc("buildMultiFileRequiresNamespaceOrModule",",,,") )
+    /// This file contains multiple declarations of the form 'module SomeNamespace.SomeModule'. Only one declaration of this form is permitted in a file. Change your file to use an initial namespace declaration and/or use 'module ModuleName = ...' to define your modules.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:40)
+    static member buildMultipleToplevelModules() = (223, GetStringFunc("buildMultipleToplevelModules",",,,") )
+    /// ParseInput: unknown file suffix for '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:41)
+    static member buildUnknownFileSuffix(a0 : System.String) = (GetStringFunc("buildUnknownFileSuffix",",,,%s,,,") a0)
+    /// Option requires parameter: %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:42)
+    static member buildOptionRequiresParameter(a0 : System.String) = (224, GetStringFunc("buildOptionRequiresParameter",",,,%s,,,") a0)
+    /// Source file '%s' could not be found
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:43)
+    static member buildCouldNotFindSourceFile(a0 : System.String) = (225, GetStringFunc("buildCouldNotFindSourceFile",",,,%s,,,") a0)
+    /// The file extension of '%s' is not recognized. Source files must have extension .fs, .fsi, .fsx, .fsscript, .ml or .mli.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:44)
+    static member buildInvalidSourceFileExtension(a0 : System.String) = (226, GetStringFunc("buildInvalidSourceFileExtension",",,,%s,,,") a0)
+    /// Could not resolve assembly '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:45)
+    static member buildCouldNotResolveAssembly(a0 : System.String) = (227, GetStringFunc("buildCouldNotResolveAssembly",",,,%s,,,") a0)
+    /// Could not resolve assembly '%s' required by '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:46)
+    static member buildCouldNotResolveAssemblyRequiredByFile(a0 : System.String, a1 : System.String) = (228, GetStringFunc("buildCouldNotResolveAssemblyRequiredByFile",",,,%s,,,%s,,,") a0 a1)
+    /// Error opening binary file '%s': %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:47)
+    static member buildErrorOpeningBinaryFile(a0 : System.String, a1 : System.String) = (229, GetStringFunc("buildErrorOpeningBinaryFile",",,,%s,,,%s,,,") a0 a1)
+    /// The F#-compiled DLL '%s' needs to be recompiled to be used with this version of F#
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:48)
+    static member buildDifferentVersionMustRecompile(a0 : System.String) = (231, GetStringFunc("buildDifferentVersionMustRecompile",",,,%s,,,") a0)
+    /// Invalid directive. Expected '#I \"<path>\"'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:49)
+    static member buildInvalidHashIDirective() = (232, GetStringFunc("buildInvalidHashIDirective",",,,") )
+    /// Invalid directive. Expected '#r \"<file-or-assembly>\"'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:50)
+    static member buildInvalidHashrDirective() = (233, GetStringFunc("buildInvalidHashrDirective",",,,") )
+    /// Invalid directive. Expected '#load \"<file>\" ... \"<file>\"'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:51)
+    static member buildInvalidHashloadDirective() = (234, GetStringFunc("buildInvalidHashloadDirective",",,,") )
+    /// Invalid directive. Expected '#time', '#time \"on\"' or '#time \"off\"'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:52)
+    static member buildInvalidHashtimeDirective() = (235, GetStringFunc("buildInvalidHashtimeDirective",",,,") )
+    /// Directives inside modules are ignored
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:53)
+    static member buildDirectivesInModulesAreIgnored() = (236, GetStringFunc("buildDirectivesInModulesAreIgnored",",,,") )
+    /// A signature for the file or module '%s' has already been specified
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:54)
+    static member buildSignatureAlreadySpecified(a0 : System.String) = (237, GetStringFunc("buildSignatureAlreadySpecified",",,,%s,,,") a0)
+    /// An implementation of file or module '%s' has already been given. Compilation order is significant in F# because of type inference. You may need to adjust the order of your files to place the signature file before the implementation. In Visual Studio files are type-checked in the order they appear in the project file, which can be edited manually or adjusted using the solution explorer.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:55)
+    static member buildImplementationAlreadyGivenDetail(a0 : System.String) = (238, GetStringFunc("buildImplementationAlreadyGivenDetail",",,,%s,,,") a0)
+    /// An implementation of the file or module '%s' has already been given
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:56)
+    static member buildImplementationAlreadyGiven(a0 : System.String) = (239, GetStringFunc("buildImplementationAlreadyGiven",",,,%s,,,") a0)
+    /// The signature file '%s' does not have a corresponding implementation file. If an implementation file exists then check the 'module' and 'namespace' declarations in the signature and implementation files match.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:57)
+    static member buildSignatureWithoutImplementation(a0 : System.String) = (240, GetStringFunc("buildSignatureWithoutImplementation",",,,%s,,,") a0)
+    /// '%s' is not a valid integer argument
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:58)
+    static member buildArgInvalidInt(a0 : System.String) = (241, GetStringFunc("buildArgInvalidInt",",,,%s,,,") a0)
+    /// '%s' is not a valid floating point argument
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:59)
+    static member buildArgInvalidFloat(a0 : System.String) = (242, GetStringFunc("buildArgInvalidFloat",",,,%s,,,") a0)
+    /// Unrecognized option: '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:60)
+    static member buildUnrecognizedOption(a0 : System.String) = (243, GetStringFunc("buildUnrecognizedOption",",,,%s,,,") a0)
+    /// Invalid module or namespace name
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:61)
+    static member buildInvalidModuleOrNamespaceName() = (244, GetStringFunc("buildInvalidModuleOrNamespaceName",",,,") )
+    /// When mscorlib.dll or FSharp.Core.dll is explicitly referenced the %s option must also be passed
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:62)
+    static member buildExplicitCoreLibRequiresNoFramework(a0 : System.String) = (1203, GetStringFunc("buildExplicitCoreLibRequiresNoFramework",",,,%s,,,") a0)
+    /// Did not expect to find sigdata resource in FSharp.Core.dll
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:63)
+    static member buildDidNotExpectSigdataResource() = (1220, GetStringFunc("buildDidNotExpectSigdataResource",",,,") )
+    /// FSharp.Core.sigdata not found alongside FSharp.Core
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:64)
+    static member buildExpectedSigdataFile() = (1221, GetStringFunc("buildExpectedSigdataFile",",,,") )
+    /// Did not expect to find optdata resource in FSharp.Core.dll
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:65)
+    static member buildDidNotExpectOptDataResource() = (1222, GetStringFunc("buildDidNotExpectOptDataResource",",,,") )
+    /// File '%s' not found alongside FSharp.Core
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:66)
+    static member buildExpectedFileAlongSideFSharpCore(a0 : System.String) = (1223, GetStringFunc("buildExpectedFileAlongSideFSharpCore",",,,%s,,,") a0)
+    /// Error reading/writing metadata for the F# compiled DLL '%s'. Was the DLL compiled with an earlier version of the F# compiler? (error: '%s').
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:70)
+    static member pickleErrorReadingWritingMetadata(a0 : System.String, a1 : System.String) = (GetStringFunc("pickleErrorReadingWritingMetadata",",,,%s,,,%s,,,") a0 a1)
+    /// The type/module '%s' is not a concrete module or type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:74)
+    static member tastTypeOrModuleNotConcrete(a0 : System.String) = (245, GetStringFunc("tastTypeOrModuleNotConcrete",",,,%s,,,") a0)
+    /// The type '%s' has an inline assembly code representation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:75)
+    static member tastTypeHasAssemblyCodeRepresentation(a0 : System.String) = (GetStringFunc("tastTypeHasAssemblyCodeRepresentation",",,,%s,,,") a0)
+    /// A namespace and a module named '%s' both occur in two parts of this assembly
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:76)
+    static member tastNamespaceAndModuleWithSameNameInAssembly(a0 : System.String) = (247, GetStringFunc("tastNamespaceAndModuleWithSameNameInAssembly",",,,%s,,,") a0)
+    /// Two modules named '%s' occur in two parts of this assembly
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:77)
+    static member tastTwoModulesWithSameNameInAssembly(a0 : System.String) = (248, GetStringFunc("tastTwoModulesWithSameNameInAssembly",",,,%s,,,") a0)
+    /// Two type definitions named '%s' occur in namespace '%s' in two parts of this assembly
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:78)
+    static member tastDuplicateTypeDefinitionInAssembly(a0 : System.String, a1 : System.String) = (249, GetStringFunc("tastDuplicateTypeDefinitionInAssembly",",,,%s,,,%s,,,") a0 a1)
+    /// A module and a type definition named '%s' occur in namespace '%s' in two parts of this assembly
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:79)
+    static member tastConflictingModuleAndTypeDefinitionInAssembly(a0 : System.String, a1 : System.String) = (250, GetStringFunc("tastConflictingModuleAndTypeDefinitionInAssembly",",,,%s,,,%s,,,") a0 a1)
+    /// Invalid member signature encountered because of an earlier error
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:83)
+    static member tastInvalidMemberSignature() = (251, GetStringFunc("tastInvalidMemberSignature",",,,") )
+    /// This value does not have a valid property setter type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:84)
+    static member tastValueDoesNotHaveSetterType() = (252, GetStringFunc("tastValueDoesNotHaveSetterType",",,,") )
+    /// Invalid form for a property getter. At least one '()' argument is required when using the explicit syntax.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:85)
+    static member tastInvalidFormForPropertyGetter() = (253, GetStringFunc("tastInvalidFormForPropertyGetter",",,,") )
+    /// Invalid form for a property setter. At least one argument is required.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:86)
+    static member tastInvalidFormForPropertySetter() = (254, GetStringFunc("tastInvalidFormForPropertySetter",",,,") )
+    /// Unexpected use of a byref-typed variable
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:87)
+    static member tastUnexpectedByRef() = (255, GetStringFunc("tastUnexpectedByRef",",,,") )
+    /// A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:88)
+    static member tastValueMustBeLocalAndMutable() = (256, GetStringFunc("tastValueMustBeLocalAndMutable",",,,") )
+    /// Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:89)
+    static member tastInvalidMutationOfConstant() = (257, GetStringFunc("tastInvalidMutationOfConstant",",,,") )
+    /// The value has been copied to ensure the original is not mutated by this operation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:90)
+    static member tastValueHasBeenCopied() = (GetStringFunc("tastValueHasBeenCopied",",,,") )
+    /// Recursively defined values cannot appear directly as part of the construction of a tuple value within a recursive binding
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:91)
+    static member tastRecursiveValuesMayNotBeInConstructionOfTuple() = (259, GetStringFunc("tastRecursiveValuesMayNotBeInConstructionOfTuple",",,,") )
+    /// Recursive values cannot appear directly as a construction of the type '%s' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:92)
+    static member tastRecursiveValuesMayNotAppearInConstructionOfType(a0 : System.String) = (260, GetStringFunc("tastRecursiveValuesMayNotAppearInConstructionOfType",",,,%s,,,") a0)
+    /// Recursive values cannot be directly assigned to the non-mutable field '%s' of the type '%s' within a recursive binding. Consider using a mutable field instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:93)
+    static member tastRecursiveValuesMayNotBeAssignedToNonMutableField(a0 : System.String, a1 : System.String) = (261, GetStringFunc("tastRecursiveValuesMayNotBeAssignedToNonMutableField",",,,%s,,,%s,,,") a0 a1)
+    /// Unexpected decode of AutoOpenAttribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:94)
+    static member tastUnexpectedDecodeOfAutoOpenAttribute() = (GetStringFunc("tastUnexpectedDecodeOfAutoOpenAttribute",",,,") )
+    /// Unexpected decode of InternalsVisibleToAttribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:95)
+    static member tastUnexpectedDecodeOfInternalsVisibleToAttribute() = (GetStringFunc("tastUnexpectedDecodeOfInternalsVisibleToAttribute",",,,") )
+    /// Unexpected decode of InterfaceDataVersionAttribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:96)
+    static member tastUnexpectedDecodeOfInterfaceDataVersionAttribute() = (GetStringFunc("tastUnexpectedDecodeOfInterfaceDataVersionAttribute",",,,") )
+    /// Active patterns cannot return more than 7 possibilities
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:97)
+    static member tastActivePatternsLimitedToSeven() = (265, GetStringFunc("tastActivePatternsLimitedToSeven",",,,") )
+    /// This constant cannot be used as a custom attribute value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:98)
+    static member tastConstantCannotBeCustomAttribute() = (266, GetStringFunc("tastConstantCannotBeCustomAttribute",",,,") )
+    /// This is not a constant expression or valid custom attribute value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:99)
+    static member tastNotAConstantExpression() = (267, GetStringFunc("tastNotAConstantExpression",",,,") )
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe mutability attributes differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:103)
+    static member ValueNotContainedMutabilityAttributesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityAttributesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe names differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:104)
+    static member ValueNotContainedMutabilityNamesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityNamesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe compiled names differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:105)
+    static member ValueNotContainedMutabilityCompiledNamesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityCompiledNamesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe display names differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:106)
+    static member ValueNotContainedMutabilityDisplayNamesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityDisplayNamesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe accessibility specified in the signature is more than that specified in the implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:107)
+    static member ValueNotContainedMutabilityAccessibilityMore(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityAccessibilityMore",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe inline flags differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:108)
+    static member ValueNotContainedMutabilityInlineFlagsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityInlineFlagsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe literal constant values and/or attributes differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:109)
+    static member ValueNotContainedMutabilityLiteralConstantValuesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityLiteralConstantValuesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nOne is a type function and the other is not. The signature requires explicit type parameters if they are present in the implementation.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:110)
+    static member ValueNotContainedMutabilityOneIsTypeFunction(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityOneIsTypeFunction",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe respective type parameter counts differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:111)
+    static member ValueNotContainedMutabilityParameterCountsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityParameterCountsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe types differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:112)
+    static member ValueNotContainedMutabilityTypesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityTypesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nOne is an extension member and the other is not
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:113)
+    static member ValueNotContainedMutabilityExtensionsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityExtensionsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nAn arity was not inferred for this value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:114)
+    static member ValueNotContainedMutabilityArityNotInferred(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityArityNotInferred",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe number of generic parameters in the signature and implementation differ (the signature declares %s but the implementation declares %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:115)
+    static member ValueNotContainedMutabilityGenericParametersDiffer(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String, a4 : System.String) = (GetStringFunc("ValueNotContainedMutabilityGenericParametersDiffer",",,,%s,,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3 a4)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe generic parameters in the signature and implementation have different kinds. Perhaps there is a missing [<Measure>] attribute.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:116)
+    static member ValueNotContainedMutabilityGenericParametersAreDifferentKinds(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityGenericParametersAreDifferentKinds",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe arities in the signature and implementation differ. The signature specifies that '%s' is function definition or lambda expression accepting at least %s argument(s), but the implementation is a computed function value. To declare that a computed function value is a permitted implementation simply parenthesize its type in the signature, e.g.\n\tval %s: int -> (int -> int)\ninstead of\n\tval %s: int -> in [...]
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:117)
+    static member ValueNotContainedMutabilityAritiesDiffer(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String, a4 : System.String, a5 : System.String, a6 : System.String) = (GetStringFunc("ValueNotContainedMutabilityAritiesDiffer",",,,%s,,,%s,,,%s,,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3 a4 a5 a6)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe CLI member names differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:118)
+    static member ValueNotContainedMutabilityDotNetNamesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityDotNetNamesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nOne is static and the other isn't
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:119)
+    static member ValueNotContainedMutabilityStaticsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityStaticsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nOne is virtual and the other isn't
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:120)
+    static member ValueNotContainedMutabilityVirtualsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityVirtualsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nOne is abstract and the other isn't
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:121)
+    static member ValueNotContainedMutabilityAbstractsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityAbstractsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nOne is final and the other isn't
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:122)
+    static member ValueNotContainedMutabilityFinalsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityFinalsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nOne is marked as an override and the other isn't
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:123)
+    static member ValueNotContainedMutabilityOverridesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityOverridesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nOne is a constructor/property and the other is not
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:124)
+    static member ValueNotContainedMutabilityOneIsConstructor(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityOneIsConstructor",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe compiled representation of this method is as a static member but the signature indicates its compiled representation is as an instance member
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:125)
+    static member ValueNotContainedMutabilityStaticButInstance(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityStaticButInstance",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Module '%s' contains\n    %s    \nbut its signature specifies\n    %s    \nThe compiled representation of this method is as an instance member, but the signature indicates its compiled representation is as a static member
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:126)
+    static member ValueNotContainedMutabilityInstanceButStatic(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityInstanceButStatic",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The %s definitions in the signature and implementation are not compatible because the names differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:127)
+    static member DefinitionsInSigAndImplNotCompatibleNamesDiffer(a0 : System.String) = (290, GetStringFunc("DefinitionsInSigAndImplNotCompatibleNamesDiffer",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the respective type parameter counts differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:128)
+    static member DefinitionsInSigAndImplNotCompatibleParameterCountsDiffer(a0 : System.String) = (291, GetStringFunc("DefinitionsInSigAndImplNotCompatibleParameterCountsDiffer",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the accessibility specified in the signature is more than that specified in the implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:129)
+    static member DefinitionsInSigAndImplNotCompatibleAccessibilityDiffer(a0 : System.String) = (292, GetStringFunc("DefinitionsInSigAndImplNotCompatibleAccessibilityDiffer",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the signature requires that the type supports the interface %s but the interface has not been implemented
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:130)
+    static member DefinitionsInSigAndImplNotCompatibleMissingInterface(a0 : System.String, a1 : System.String) = (293, GetStringFunc("DefinitionsInSigAndImplNotCompatibleMissingInterface",",,,%s,,,%s,,,") a0 a1)
+    /// The %s definitions in the signature and implementation are not compatible because the implementation says this type may use nulls as a representation but the signature does not
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:131)
+    static member DefinitionsInSigAndImplNotCompatibleImplementationSaysNull(a0 : System.String) = (294, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplementationSaysNull",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the implementation says this type may use nulls as an extra value but the signature does not
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:132)
+    static member DefinitionsInSigAndImplNotCompatibleImplementationSaysNull2(a0 : System.String) = (294, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplementationSaysNull2",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the signature says this type may use nulls as a representation but the implementation does not
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:133)
+    static member DefinitionsInSigAndImplNotCompatibleSignatureSaysNull(a0 : System.String) = (295, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSignatureSaysNull",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the signature says this type may use nulls as an extra value but the implementation does not
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:134)
+    static member DefinitionsInSigAndImplNotCompatibleSignatureSaysNull2(a0 : System.String) = (295, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSignatureSaysNull2",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the implementation type is sealed but the signature implies it is not. Consider adding the [<Sealed>] attribute to the signature.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:135)
+    static member DefinitionsInSigAndImplNotCompatibleImplementationSealed(a0 : System.String) = (296, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplementationSealed",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the implementation type is not sealed but signature implies it is. Consider adding the [<Sealed>] attribute to the implementation.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:136)
+    static member DefinitionsInSigAndImplNotCompatibleImplementationIsNotSealed(a0 : System.String) = (297, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplementationIsNotSealed",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the implementation is an abstract class but the signature is not. Consider adding the [<AbstractClass>] attribute to the signature.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:137)
+    static member DefinitionsInSigAndImplNotCompatibleImplementationIsAbstract(a0 : System.String) = (298, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplementationIsAbstract",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the signature is an abstract class but the implementation is not. Consider adding the [<AbstractClass>] attribute to the implementation.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:138)
+    static member DefinitionsInSigAndImplNotCompatibleSignatureIsAbstract(a0 : System.String) = (299, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSignatureIsAbstract",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the types have different base types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:139)
+    static member DefinitionsInSigAndImplNotCompatibleTypesHaveDifferentBaseTypes(a0 : System.String) = (300, GetStringFunc("DefinitionsInSigAndImplNotCompatibleTypesHaveDifferentBaseTypes",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the number of %ss differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:140)
+    static member DefinitionsInSigAndImplNotCompatibleNumbersDiffer(a0 : System.String, a1 : System.String) = (301, GetStringFunc("DefinitionsInSigAndImplNotCompatibleNumbersDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The %s definitions in the signature and implementation are not compatible because the signature defines the %s '%s' but the implementation does not (or does, but not in the same order)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:141)
+    static member DefinitionsInSigAndImplNotCompatibleSignatureDefinesButImplDoesNot(a0 : System.String, a1 : System.String, a2 : System.String) = (302, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSignatureDefinesButImplDoesNot",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The %s definitions in the signature and implementation are not compatible because the implementation defines the %s '%s' but the signature does not (or does, but not in the same order)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:142)
+    static member DefinitionsInSigAndImplNotCompatibleImplDefinesButSignatureDoesNot(a0 : System.String, a1 : System.String, a2 : System.String) = (303, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplDefinesButSignatureDoesNot",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The %s definitions in the signature and implementation are not compatible because the implementation defines a struct but the signature defines a type with a hidden representation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:143)
+    static member DefinitionsInSigAndImplNotCompatibleImplDefinesStruct(a0 : System.String) = (304, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplDefinesStruct",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because a CLI type representation is being hidden by a signature
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:144)
+    static member DefinitionsInSigAndImplNotCompatibleDotNetTypeRepresentationIsHidden(a0 : System.String) = (305, GetStringFunc("DefinitionsInSigAndImplNotCompatibleDotNetTypeRepresentationIsHidden",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because a type representation is being hidden by a signature
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:145)
+    static member DefinitionsInSigAndImplNotCompatibleTypeIsHidden(a0 : System.String) = (306, GetStringFunc("DefinitionsInSigAndImplNotCompatibleTypeIsHidden",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the types are of different kinds
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:146)
+    static member DefinitionsInSigAndImplNotCompatibleTypeIsDifferentKind(a0 : System.String) = (307, GetStringFunc("DefinitionsInSigAndImplNotCompatibleTypeIsDifferentKind",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the IL representations differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:147)
+    static member DefinitionsInSigAndImplNotCompatibleILDiffer(a0 : System.String) = (308, GetStringFunc("DefinitionsInSigAndImplNotCompatibleILDiffer",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the representations differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:148)
+    static member DefinitionsInSigAndImplNotCompatibleRepresentationsDiffer(a0 : System.String) = (309, GetStringFunc("DefinitionsInSigAndImplNotCompatibleRepresentationsDiffer",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the field %s was present in the implementation but not in the signature
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:149)
+    static member DefinitionsInSigAndImplNotCompatibleFieldWasPresent(a0 : System.String, a1 : System.String) = (311, GetStringFunc("DefinitionsInSigAndImplNotCompatibleFieldWasPresent",",,,%s,,,%s,,,") a0 a1)
+    /// The %s definitions in the signature and implementation are not compatible because the order of the fields is different in the signature and implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:150)
+    static member DefinitionsInSigAndImplNotCompatibleFieldOrderDiffer(a0 : System.String) = (312, GetStringFunc("DefinitionsInSigAndImplNotCompatibleFieldOrderDiffer",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the field %s was required by the signature but was not specified by the implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:151)
+    static member DefinitionsInSigAndImplNotCompatibleFieldRequiredButNotSpecified(a0 : System.String, a1 : System.String) = (313, GetStringFunc("DefinitionsInSigAndImplNotCompatibleFieldRequiredButNotSpecified",",,,%s,,,%s,,,") a0 a1)
+    /// The %s definitions in the signature and implementation are not compatible because the field %s was present in the implementation but not in the signature. Struct types must now reveal their fields in the signature for the type, though the fields may still be labelled 'private' or 'internal'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:152)
+    static member DefinitionsInSigAndImplNotCompatibleFieldIsInImplButNotSig(a0 : System.String, a1 : System.String) = (314, GetStringFunc("DefinitionsInSigAndImplNotCompatibleFieldIsInImplButNotSig",",,,%s,,,%s,,,") a0 a1)
+    /// The %s definitions in the signature and implementation are not compatible because the abstract member '%s' was required by the signature but was not specified by the implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:153)
+    static member DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInImpl(a0 : System.String, a1 : System.String) = (315, GetStringFunc("DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInImpl",",,,%s,,,%s,,,") a0 a1)
+    /// The %s definitions in the signature and implementation are not compatible because the abstract member '%s' was present in the implementation but not in the signature
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:154)
+    static member DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInSig(a0 : System.String, a1 : System.String) = (316, GetStringFunc("DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInSig",",,,%s,,,%s,,,") a0 a1)
+    /// The %s definitions in the signature and implementation are not compatible because the signature declares a %s while the implementation declares a %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:155)
+    static member DefinitionsInSigAndImplNotCompatibleSignatureDeclaresDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (317, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSignatureDeclaresDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The %s definitions in the signature and implementation are not compatible because the abbreviations differ: %s versus %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:156)
+    static member DefinitionsInSigAndImplNotCompatibleAbbreviationsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (318, GetStringFunc("DefinitionsInSigAndImplNotCompatibleAbbreviationsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The %s definitions in the signature and implementation are not compatible because an abbreviation is being hidden by a signature. The abbreviation must be visible to other CLI languages. Consider making the abbreviation visible in the signature.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:157)
+    static member DefinitionsInSigAndImplNotCompatibleAbbreviationHiddenBySig(a0 : System.String) = (319, GetStringFunc("DefinitionsInSigAndImplNotCompatibleAbbreviationHiddenBySig",",,,%s,,,") a0)
+    /// The %s definitions in the signature and implementation are not compatible because the signature has an abbreviation while the implementation does not
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:158)
+    static member DefinitionsInSigAndImplNotCompatibleSigHasAbbreviation(a0 : System.String) = (320, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSigHasAbbreviation",",,,%s,,,") a0)
+    /// The module contains the constructor\n    %s    \nbut its signature specifies\n    %s    \nThe names differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:159)
+    static member ModuleContainsConstructorButNamesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ModuleContainsConstructorButNamesDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The module contains the constructor\n    %s    \nbut its signature specifies\n    %s    \nThe respective number of data fields differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:160)
+    static member ModuleContainsConstructorButDataFieldsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ModuleContainsConstructorButDataFieldsDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The module contains the constructor\n    %s    \nbut its signature specifies\n    %s    \nThe types of the fields differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:161)
+    static member ModuleContainsConstructorButTypesOfFieldsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ModuleContainsConstructorButTypesOfFieldsDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The module contains the constructor\n    %s    \nbut its signature specifies\n    %s    \nthe accessibility specified in the signature is more than that specified in the implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:162)
+    static member ModuleContainsConstructorButAccessibilityDiffers(a0 : System.String, a1 : System.String) = (GetStringFunc("ModuleContainsConstructorButAccessibilityDiffers",",,,%s,,,%s,,,") a0 a1)
+    /// The module contains the field\n    %s    \nbut its signature specifies\n    %s    \nThe names differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:163)
+    static member FieldNotContainedNamesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedNamesDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The module contains the field\n    %s    \nbut its signature specifies\n    %s    \nthe accessibility specified in the signature is more than that specified in the implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:164)
+    static member FieldNotContainedAccessibilitiesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedAccessibilitiesDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The module contains the field\n    %s    \nbut its signature specifies\n    %s    \nThe 'static' modifiers differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:165)
+    static member FieldNotContainedStaticsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedStaticsDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The module contains the field\n    %s    \nbut its signature specifies\n    %s    \nThe 'mutable' modifiers differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:166)
+    static member FieldNotContainedMutablesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedMutablesDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The module contains the field\n    %s    \nbut its signature specifies\n    %s    \nThe 'literal' modifiers differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:167)
+    static member FieldNotContainedLiteralsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedLiteralsDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The module contains the field\n    %s    \nbut its signature specifies\n    %s    \nThe types differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:168)
+    static member FieldNotContainedTypesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedTypesDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The implicit instantiation of a generic construct at or near this point could not be resolved because it could resolve to multiple unrelated types, e.g. '%s' and '%s'. Consider using type annotations to resolve the ambiguity
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:169)
+    static member typrelCannotResolveImplicitGenericInstantiation(a0 : System.String, a1 : System.String) = (331, GetStringFunc("typrelCannotResolveImplicitGenericInstantiation",",,,%s,,,%s,,,") a0 a1)
+    /// Could not resolve the ambiguity inherent in the use of the operator '%s' at or near this program point. Consider using type annotations to resolve the ambiguity.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:170)
+    static member typrelCannotResolveAmbiguityInOverloadedOperator(a0 : System.String) = (332, GetStringFunc("typrelCannotResolveAmbiguityInOverloadedOperator",",,,%s,,,") a0)
+    /// Could not resolve the ambiguity inherent in the use of a 'printf'-style format string
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:171)
+    static member typrelCannotResolveAmbiguityInPrintf() = (333, GetStringFunc("typrelCannotResolveAmbiguityInPrintf",",,,") )
+    /// Could not resolve the ambiguity in the use of a generic construct with an 'enum' constraint at or near this position
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:172)
+    static member typrelCannotResolveAmbiguityInEnum() = (334, GetStringFunc("typrelCannotResolveAmbiguityInEnum",",,,") )
+    /// Could not resolve the ambiguity in the use of a generic construct with a 'delegate' constraint at or near this position
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:173)
+    static member typrelCannotResolveAmbiguityInDelegate() = (335, GetStringFunc("typrelCannotResolveAmbiguityInDelegate",",,,") )
+    /// Invalid value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:174)
+    static member typrelInvalidValue() = (337, GetStringFunc("typrelInvalidValue",",,,") )
+    /// The signature and implementation are not compatible because the respective type parameter counts differ
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:175)
+    static member typrelSigImplNotCompatibleParamCountsDiffer() = (338, GetStringFunc("typrelSigImplNotCompatibleParamCountsDiffer",",,,") )
+    /// The signature and implementation are not compatible because the type parameter in the class/signature has a different compile-time requirement to the one in the member/implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:176)
+    static member typrelSigImplNotCompatibleCompileTimeRequirementsDiffer() = (339, GetStringFunc("typrelSigImplNotCompatibleCompileTimeRequirementsDiffer",",,,") )
+    /// The signature and implementation are not compatible because the declaration of the type parameter '%s' requires a constraint of the form %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:177)
+    static member typrelSigImplNotCompatibleConstraintsDiffer(a0 : System.String, a1 : System.String) = (340, GetStringFunc("typrelSigImplNotCompatibleConstraintsDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The signature and implementation are not compatible because the type parameter '%s' has a constraint of the form %s but the implementation does not. Either remove this constraint from the signature or add it to the implementation.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:178)
+    static member typrelSigImplNotCompatibleConstraintsDifferRemove(a0 : System.String, a1 : System.String) = (341, GetStringFunc("typrelSigImplNotCompatibleConstraintsDifferRemove",",,,%s,,,%s,,,") a0 a1)
+    /// The type '%s' implements 'System.IComparable'. Consider also adding an explicit override for 'Object.Equals'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:179)
+    static member typrelTypeImplementsIComparableShouldOverrideObjectEquals(a0 : System.String) = (342, GetStringFunc("typrelTypeImplementsIComparableShouldOverrideObjectEquals",",,,%s,,,") a0)
+    /// The type '%s' implements 'System.IComparable' explicitly but provides no corresponding override for 'Object.Equals'. An implementation of 'Object.Equals' has been automatically provided, implemented via 'System.IComparable'. Consider implementing the override 'Object.Equals' explicitly
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:180)
+    static member typrelTypeImplementsIComparableDefaultObjectEqualsProvided(a0 : System.String) = (343, GetStringFunc("typrelTypeImplementsIComparableDefaultObjectEqualsProvided",",,,%s,,,") a0)
+    /// The struct, record or union type '%s' has an explicit implementation of 'Object.GetHashCode' or 'Object.Equals'. You must apply the 'CustomEquality' attribute to the type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:181)
+    static member typrelExplicitImplementationOfGetHashCodeOrEquals(a0 : System.String) = (344, GetStringFunc("typrelExplicitImplementationOfGetHashCodeOrEquals",",,,%s,,,") a0)
+    /// The struct, record or union type '%s' has an explicit implementation of 'Object.GetHashCode'. Consider implementing a matching override for 'Object.Equals(obj)'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:182)
+    static member typrelExplicitImplementationOfGetHashCode(a0 : System.String) = (345, GetStringFunc("typrelExplicitImplementationOfGetHashCode",",,,%s,,,") a0)
+    /// The struct, record or union type '%s' has an explicit implementation of 'Object.Equals'. Consider implementing a matching override for 'Object.GetHashCode()'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:183)
+    static member typrelExplicitImplementationOfEquals(a0 : System.String) = (346, GetStringFunc("typrelExplicitImplementationOfEquals",",,,%s,,,") a0)
+    /// The exception definitions are not compatible because a CLI exception mapping is being hidden by a signature. The exception mapping must be visible to other modules. The module contains the exception definition\n    %s    \nbut its signature specifies\n\t%s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:184)
+    static member ExceptionDefsNotCompatibleHiddenBySignature(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleHiddenBySignature",",,,%s,,,%s,,,") a0 a1)
+    /// The exception definitions are not compatible because the CLI representations differ. The module contains the exception definition\n    %s    \nbut its signature specifies\n\t%s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:185)
+    static member ExceptionDefsNotCompatibleDotNetRepresentationsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleDotNetRepresentationsDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The exception definitions are not compatible because the exception abbreviation is being hidden by the signature. The abbreviation must be visible to other CLI languages. Consider making the abbreviation visible in the signature. The module contains the exception definition\n    %s    \nbut its signature specifies\n\t%s.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:186)
+    static member ExceptionDefsNotCompatibleAbbreviationHiddenBySignature(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleAbbreviationHiddenBySignature",",,,%s,,,%s,,,") a0 a1)
+    /// The exception definitions are not compatible because the exception abbreviations in the signature and implementation differ. The module contains the exception definition\n    %s    \nbut its signature specifies\n\t%s.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:187)
+    static member ExceptionDefsNotCompatibleSignaturesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleSignaturesDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The exception definitions are not compatible because the exception declarations differ. The module contains the exception definition\n    %s    \nbut its signature specifies\n\t%s.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:188)
+    static member ExceptionDefsNotCompatibleExceptionDeclarationsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleExceptionDeclarationsDiffer",",,,%s,,,%s,,,") a0 a1)
+    /// The exception definitions are not compatible because the field '%s' was required by the signature but was not specified by the implementation. The module contains the exception definition\n    %s    \nbut its signature specifies\n\t%s.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:189)
+    static member ExceptionDefsNotCompatibleFieldInSigButNotImpl(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleFieldInSigButNotImpl",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The exception definitions are not compatible because the field '%s' was present in the implementation but not in the signature. The module contains the exception definition\n    %s    \nbut its signature specifies\n\t%s.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:190)
+    static member ExceptionDefsNotCompatibleFieldInImplButNotSig(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleFieldInImplButNotSig",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The exception definitions are not compatible because the order of the fields is different in the signature and implementation. The module contains the exception definition\n    %s    \nbut its signature specifies\n\t%s.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:191)
+    static member ExceptionDefsNotCompatibleFieldOrderDiffers(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleFieldOrderDiffers",",,,%s,,,%s,,,") a0 a1)
+    /// The namespace or module attributes differ between signature and implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:192)
+    static member typrelModuleNamespaceAttributesDifferInSigAndImpl() = (355, GetStringFunc("typrelModuleNamespaceAttributesDifferInSigAndImpl",",,,") )
+    /// This method is over-constrained in its type parameters
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:193)
+    static member typrelMethodIsOverconstrained() = (356, GetStringFunc("typrelMethodIsOverconstrained",",,,") )
+    /// No implementations of '%s' had the correct number of arguments and type parameters. The required signature is '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:194)
+    static member typrelOverloadNotFound(a0 : System.String, a1 : System.String) = (357, GetStringFunc("typrelOverloadNotFound",",,,%s,,,%s,,,") a0 a1)
+    /// The override for '%s' was ambiguous
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:195)
+    static member typrelOverrideWasAmbiguous(a0 : System.String) = (358, GetStringFunc("typrelOverrideWasAmbiguous",",,,%s,,,") a0)
+    /// More than one override implements '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:196)
+    static member typrelMoreThenOneOverride(a0 : System.String) = (359, GetStringFunc("typrelMoreThenOneOverride",",,,%s,,,") a0)
+    /// The method '%s' is sealed and cannot be overridden
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:197)
+    static member typrelMethodIsSealed(a0 : System.String) = (360, GetStringFunc("typrelMethodIsSealed",",,,%s,,,") a0)
+    /// The override '%s' implements more than one abstract slot, e.g. '%s' and '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:198)
+    static member typrelOverrideImplementsMoreThenOneSlot(a0 : System.String, a1 : System.String, a2 : System.String) = (361, GetStringFunc("typrelOverrideImplementsMoreThenOneSlot",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Duplicate or redundant interface
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:199)
+    static member typrelDuplicateInterface() = (362, GetStringFunc("typrelDuplicateInterface",",,,") )
+    /// The interface '%s' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:200)
+    static member typrelNeedExplicitImplementation(a0 : System.String) = (363, GetStringFunc("typrelNeedExplicitImplementation",",,,%s,,,") a0)
+    /// A named argument has been assigned more than one value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:201)
+    static member typrelNamedArgumentHasBeenAssignedMoreThenOnce() = (364, GetStringFunc("typrelNamedArgumentHasBeenAssignedMoreThenOnce",",,,") )
+    /// No implementation was given for '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:202)
+    static member typrelNoImplementationGiven(a0 : System.String) = (365, GetStringFunc("typrelNoImplementationGiven",",,,%s,,,") a0)
+    /// No implementation was given for '%s'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:203)
+    static member typrelNoImplementationGivenWithSuggestion(a0 : System.String) = (366, GetStringFunc("typrelNoImplementationGivenWithSuggestion",",,,%s,,,") a0)
+    /// The member '%s' does not have the correct number of arguments. The required signature is '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:204)
+    static member typrelMemberDoesNotHaveCorrectNumberOfArguments(a0 : System.String, a1 : System.String) = (367, GetStringFunc("typrelMemberDoesNotHaveCorrectNumberOfArguments",",,,%s,,,%s,,,") a0 a1)
+    /// The member '%s' does not have the correct number of method type parameters. The required signature is '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:205)
+    static member typrelMemberDoesNotHaveCorrectNumberOfTypeParameters(a0 : System.String, a1 : System.String) = (368, GetStringFunc("typrelMemberDoesNotHaveCorrectNumberOfTypeParameters",",,,%s,,,%s,,,") a0 a1)
+    /// The member '%s' does not have the correct kinds of generic parameters. The required signature is '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:206)
+    static member typrelMemberDoesNotHaveCorrectKindsOfGenericParameters(a0 : System.String, a1 : System.String) = (369, GetStringFunc("typrelMemberDoesNotHaveCorrectKindsOfGenericParameters",",,,%s,,,%s,,,") a0 a1)
+    /// The member '%s' cannot be used to implement '%s'. The required signature is '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:207)
+    static member typrelMemberCannotImplement(a0 : System.String, a1 : System.String, a2 : System.String) = (370, GetStringFunc("typrelMemberCannotImplement",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Error while parsing embedded IL
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:211)
+    static member astParseEmbeddedILError() = (371, GetStringFunc("astParseEmbeddedILError",",,,") )
+    /// Error while parsing embedded IL type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:212)
+    static member astParseEmbeddedILTypeError() = (372, GetStringFunc("astParseEmbeddedILTypeError",",,,") )
+    /// This indexer notation has been removed from the F# language
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:213)
+    static member astDeprecatedIndexerNotation() = (GetStringFunc("astDeprecatedIndexerNotation",",,,") )
+    /// Invalid expression on left of assignment
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:214)
+    static member astInvalidExprLeftHandOfAssignment() = (374, GetStringFunc("astInvalidExprLeftHandOfAssignment",",,,") )
+    /// The 'ReferenceEquality' attribute cannot be used on structs. Consider using the 'StructuralEquality' attribute instead, or implement an override for 'System.Object.Equals(obj)'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:218)
+    static member augNoRefEqualsOnStruct() = (376, GetStringFunc("augNoRefEqualsOnStruct",",,,") )
+    /// This type uses an invalid mix of the attributes 'NoEquality', 'ReferenceEquality', 'StructuralEquality', 'NoComparison' and 'StructuralComparison' attributes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:219)
+    static member augInvalidAttrs() = (377, GetStringFunc("augInvalidAttrs",",,,") )
+    /// The 'NoEquality' attribute must be used in conjunction with the 'NoComparison' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:220)
+    static member augNoEqualityNeedsNoComparison() = (378, GetStringFunc("augNoEqualityNeedsNoComparison",",,,") )
+    /// The 'StructuralComparison' attribute must be used in conjunction with the 'StructuralEquality' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:221)
+    static member augStructCompNeedsStructEquality() = (379, GetStringFunc("augStructCompNeedsStructEquality",",,,") )
+    /// The 'StructuralEquality' attribute must be used in conjunction with the 'NoComparison' or 'StructuralComparison' attributes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:222)
+    static member augStructEqNeedsNoCompOrStructComp() = (380, GetStringFunc("augStructEqNeedsNoCompOrStructComp",",,,") )
+    /// A type cannot have both the 'ReferenceEquality' and 'StructuralEquality' or 'StructuralComparison' attributes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:223)
+    static member augTypeCantHaveRefEqAndStructAttrs() = (381, GetStringFunc("augTypeCantHaveRefEqAndStructAttrs",",,,") )
+    /// Only record, union, exception and struct types may be augmented with the 'ReferenceEquality', 'StructuralEquality' and 'StructuralComparison' attributes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:224)
+    static member augOnlyCertainTypesCanHaveAttrs() = (382, GetStringFunc("augOnlyCertainTypesCanHaveAttrs",",,,") )
+    /// A type with attribute 'ReferenceEquality' cannot have an explicit implementation of 'Object.Equals(obj)', 'System.IEquatable<_>' or 'System.Collections.IStructuralEquatable'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:225)
+    static member augRefEqCantHaveObjEquals() = (383, GetStringFunc("augRefEqCantHaveObjEquals",",,,") )
+    /// A type with attribute 'CustomEquality' must have an explicit implementation of at least one of 'Object.Equals(obj)', 'System.IEquatable<_>' or 'System.Collections.IStructuralEquatable'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:226)
+    static member augCustomEqNeedsObjEquals() = (384, GetStringFunc("augCustomEqNeedsObjEquals",",,,") )
+    /// A type with attribute 'CustomComparison' must have an explicit implementation of at least one of 'System.IComparable' or 'System.Collections.IStructuralComparable'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:227)
+    static member augCustomCompareNeedsIComp() = (385, GetStringFunc("augCustomCompareNeedsIComp",",,,") )
+    /// A type with attribute 'NoEquality' should not usually have an explicit implementation of 'Object.Equals(obj)'. Disable this warning if this is intentional for interoperability purposes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:228)
+    static member augNoEqNeedsNoObjEquals() = (386, GetStringFunc("augNoEqNeedsNoObjEquals",",,,") )
+    /// A type with attribute 'NoComparison' should not usually have an explicit implementation of 'System.IComparable', 'System.IComparable<_>' or 'System.Collections.IStructuralComparable'. Disable this warning if this is intentional for interoperability purposes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:229)
+    static member augNoCompCantImpIComp() = (386, GetStringFunc("augNoCompCantImpIComp",",,,") )
+    /// The 'CustomEquality' attribute must be used in conjunction with the 'NoComparison' or 'CustomComparison' attributes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:230)
+    static member augCustomEqNeedsNoCompOrCustomComp() = (387, GetStringFunc("augCustomEqNeedsNoCompOrCustomComp",",,,") )
+    /// Positional specifiers are not permitted in format strings
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:234)
+    static member forPositionalSpecifiersNotPermitted() = (GetStringFunc("forPositionalSpecifiersNotPermitted",",,,") )
+    /// Missing format specifier
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:235)
+    static member forMissingFormatSpecifier() = (GetStringFunc("forMissingFormatSpecifier",",,,") )
+    /// '%s' flag set twice
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:236)
+    static member forFlagSetTwice(a0 : System.String) = (GetStringFunc("forFlagSetTwice",",,,%s,,,") a0)
+    /// Prefix flag (' ' or '+') set twice
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:237)
+    static member forPrefixFlagSpacePlusSetTwice() = (GetStringFunc("forPrefixFlagSpacePlusSetTwice",",,,") )
+    /// The # formatting modifier is invalid in F#
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:238)
+    static member forHashSpecifierIsInvalid() = (GetStringFunc("forHashSpecifierIsInvalid",",,,") )
+    /// Bad precision in format specifier
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:239)
+    static member forBadPrecision() = (GetStringFunc("forBadPrecision",",,,") )
+    /// Bad width in format specifier
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:240)
+    static member forBadWidth() = (GetStringFunc("forBadWidth",",,,") )
+    /// '%s' format does not support '0' flag
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:241)
+    static member forDoesNotSupportZeroFlag(a0 : System.String) = (GetStringFunc("forDoesNotSupportZeroFlag",",,,%s,,,") a0)
+    /// Precision missing after the '.'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:242)
+    static member forPrecisionMissingAfterDot() = (GetStringFunc("forPrecisionMissingAfterDot",",,,") )
+    /// '%s' format does not support precision
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:243)
+    static member forFormatDoesntSupportPrecision(a0 : System.String) = (GetStringFunc("forFormatDoesntSupportPrecision",",,,%s,,,") a0)
+    /// Bad format specifier (after l or L): Expected ld,li,lo,lu,lx or lX. These format specifiers support ML compatibility. In F# code you can use %%d, %%x, %%o or %%u instead, which are overloaded to work with all basic integer types.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:244)
+    static member forBadFormatSpecifier() = (GetStringFunc("forBadFormatSpecifier",",,,") )
+    /// The 'l' or 'L' in this format specifier is unnecessary except for ML compatibility. In F# code you can use %%d, %%x, %%o or %%u instead, which are overloaded to work with all basic integer types.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:245)
+    static member forLIsUnnecessary() = (GetStringFunc("forLIsUnnecessary",",,,") )
+    /// The 'h' or 'H' in this format specifier is unnecessary. You can use %%d, %%x, %%o or %%u instead, which are overloaded to work with all basic integer types..
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:246)
+    static member forHIsUnnecessary() = (GetStringFunc("forHIsUnnecessary",",,,") )
+    /// '%s' does not support prefix '%s' flag
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:247)
+    static member forDoesNotSupportPrefixFlag(a0 : System.String, a1 : System.String) = (GetStringFunc("forDoesNotSupportPrefixFlag",",,,%s,,,%s,,,") a0 a1)
+    /// Bad format specifier: '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:248)
+    static member forBadFormatSpecifierGeneral(a0 : System.String) = (GetStringFunc("forBadFormatSpecifierGeneral",",,,%s,,,") a0)
+    /// System.Environment.Exit did not exit
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:252)
+    static member elSysEnvExitDidntExit() = (GetStringFunc("elSysEnvExitDidntExit",",,,") )
+    /// The treatment of this operator is now handled directly by the F# compiler and its meaning cannot be redefined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:253)
+    static member elDeprecatedOperator() = (GetStringFunc("elDeprecatedOperator",",,,") )
+    /// A protected member is called or 'base' is being used. This is only allowed in the direct implementation of members since they could escape their object scope.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:257)
+    static member chkProtectedOrBaseCalled() = (405, GetStringFunc("chkProtectedOrBaseCalled",",,,") )
+    /// The byref-typed variable '%s' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:258)
+    static member chkByrefUsedInInvalidWay(a0 : System.String) = (406, GetStringFunc("chkByrefUsedInInvalidWay",",,,%s,,,") a0)
+    /// The mutable variable '%s' is used in an invalid way. Mutable variables cannot be captured by closures. Consider eliminating this use of mutation or using a heap-allocated mutable reference cell via 'ref' and '!'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:259)
+    static member chkMutableUsedInInvalidWay(a0 : System.String) = (407, GetStringFunc("chkMutableUsedInInvalidWay",",,,%s,,,") a0)
+    /// The 'base' keyword is used in an invalid way. Base calls cannot be used in closures. Consider using a private member to make base calls.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:260)
+    static member chkBaseUsedInInvalidWay() = (408, GetStringFunc("chkBaseUsedInInvalidWay",",,,") )
+    /// The variable '%s' is used in an invalid way
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:261)
+    static member chkVariableUsedInInvalidWay(a0 : System.String) = (GetStringFunc("chkVariableUsedInInvalidWay",",,,%s,,,") a0)
+    /// The type '%s' is less accessible than the value, member or type '%s' it is used in
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:262)
+    static member chkTypeLessAccessibleThanType(a0 : System.String, a1 : System.String) = (410, GetStringFunc("chkTypeLessAccessibleThanType",",,,%s,,,%s,,,") a0 a1)
+    /// 'System.Void' can only be used as 'typeof<System.Void>' in F#
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:263)
+    static member chkSystemVoidOnlyInTypeof() = (411, GetStringFunc("chkSystemVoidOnlyInTypeof",",,,") )
+    /// A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:264)
+    static member chkErrorUseOfByref() = (412, GetStringFunc("chkErrorUseOfByref",",,,") )
+    /// Calls to 'reraise' may only occur directly in a handler of a try-with
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:265)
+    static member chkErrorContainsCallToRethrow() = (413, GetStringFunc("chkErrorContainsCallToRethrow",",,,") )
+    /// Expression-splicing operators may only be used within quotations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:266)
+    static member chkSplicingOnlyInQuotations() = (414, GetStringFunc("chkSplicingOnlyInQuotations",",,,") )
+    /// First-class uses of the expression-splicing operator are not permitted
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:267)
+    static member chkNoFirstClassSplicing() = (415, GetStringFunc("chkNoFirstClassSplicing",",,,") )
+    /// First-class uses of the address-of operators are not permitted
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:268)
+    static member chkNoFirstClassAddressOf() = (416, GetStringFunc("chkNoFirstClassAddressOf",",,,") )
+    /// First-class uses of the 'reraise' function is not permitted
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:269)
+    static member chkNoFirstClassRethrow() = (417, GetStringFunc("chkNoFirstClassRethrow",",,,") )
+    /// The byref typed value '%s' cannot be used at this point
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:270)
+    static member chkNoByrefAtThisPoint(a0 : System.String) = (418, GetStringFunc("chkNoByrefAtThisPoint",",,,%s,,,") a0)
+    /// 'base' values may only be used to make direct calls to the base implementations of overridden members
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:271)
+    static member chkLimitationsOfBaseKeyword() = (419, GetStringFunc("chkLimitationsOfBaseKeyword",",,,") )
+    /// Object constructors cannot directly use try/with and try/finally prior to the initialization of the object. This includes constructs such as 'for x in ...' that may elaborate to uses of these constructs. This is a limitation imposed by Common IL.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:272)
+    static member chkObjCtorsCantUseExceptionHandling() = (420, GetStringFunc("chkObjCtorsCantUseExceptionHandling",",,,") )
+    /// The address of the variable '%s' cannot be used at this point
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:273)
+    static member chkNoAddressOfAtThisPoint(a0 : System.String) = (421, GetStringFunc("chkNoAddressOfAtThisPoint",",,,%s,,,") a0)
+    /// The address of the static field '%s' cannot be used at this point
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:274)
+    static member chkNoAddressStaticFieldAtThisPoint(a0 : System.String) = (422, GetStringFunc("chkNoAddressStaticFieldAtThisPoint",",,,%s,,,") a0)
+    /// The address of the field '%s' cannot be used at this point
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:275)
+    static member chkNoAddressFieldAtThisPoint(a0 : System.String) = (423, GetStringFunc("chkNoAddressFieldAtThisPoint",",,,%s,,,") a0)
+    /// The address of an array element cannot be used at this point
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:276)
+    static member chkNoAddressOfArrayElementAtThisPoint() = (424, GetStringFunc("chkNoAddressOfArrayElementAtThisPoint",",,,") )
+    /// The type of a first-class function cannot contain byrefs
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:277)
+    static member chkFirstClassFuncNoByref() = (425, GetStringFunc("chkFirstClassFuncNoByref",",,,") )
+    /// A method return type would contain byrefs which is not permitted
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:278)
+    static member chkReturnTypeNoByref() = (426, GetStringFunc("chkReturnTypeNoByref",",,,") )
+    /// Invalid custom attribute value (not a constant or literal)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:279)
+    static member chkInvalidCustAttrVal() = (428, GetStringFunc("chkInvalidCustAttrVal",",,,") )
+    /// The attribute type '%s' has 'AllowMultiple=false'. Multiple instances of this attribute cannot be attached to a single language element.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:280)
+    static member chkAttrHasAllowMultiFalse(a0 : System.String) = (429, GetStringFunc("chkAttrHasAllowMultiFalse",",,,%s,,,") a0)
+    /// The member '%s' is used in an invalid way. A use of '%s' has been inferred prior to its definition at or near '%s'. This is an invalid forward reference.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:281)
+    static member chkMemberUsedInInvalidWay(a0 : System.String, a1 : System.String, a2 : System.String) = (430, GetStringFunc("chkMemberUsedInInvalidWay",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// A byref typed value would be stored here. Top-level let-bound byref values are not permitted.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:282)
+    static member chkNoByrefAsTopValue() = (431, GetStringFunc("chkNoByrefAsTopValue",",,,") )
+    /// [<ReflectedDefinition>] terms cannot contain uses of the prefix splice operator '%%'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:283)
+    static member chkReflectedDefCantSplice() = (432, GetStringFunc("chkReflectedDefCantSplice",",,,") )
+    /// A function labeled with the 'EntryPointAttribute' attribute must be the last declaration in the last file in the compilation sequence, and can only be used when compiling to a .exe
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:284)
+    static member chkEntryPointUsage() = (433, GetStringFunc("chkEntryPointUsage",",,,") )
+    /// compiled form of the union case
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:285)
+    static member chkUnionCaseCompiledForm() = (GetStringFunc("chkUnionCaseCompiledForm",",,,") )
+    /// default augmentation of the union case
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:286)
+    static member chkUnionCaseDefaultAugmentation() = (GetStringFunc("chkUnionCaseDefaultAugmentation",",,,") )
+    /// Name clash. The property '%s' has the same name as a method in this type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:287)
+    static member chkPropertySameNameMethod(a0 : System.String) = (434, GetStringFunc("chkPropertySameNameMethod",",,,%s,,,") a0)
+    /// The property '%s' has a getter and a setter that do not match. If one is abstract then the other must be as well.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:288)
+    static member chkGetterSetterDoNotMatchAbstract(a0 : System.String) = (435, GetStringFunc("chkGetterSetterDoNotMatchAbstract",",,,%s,,,") a0)
+    /// The property '%s' has the same name as another property in this type, but one takes indexer arguments and the other does not. You may be missing an indexer argument to one of your properties.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:289)
+    static member chkPropertySameNameIndexer(a0 : System.String) = (436, GetStringFunc("chkPropertySameNameIndexer",",,,%s,,,") a0)
+    /// A type would store a byref typed value. This is not permitted by Common IL.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:290)
+    static member chkCantStoreByrefValue() = (437, GetStringFunc("chkCantStoreByrefValue",",,,") )
+    /// Duplicate method. The method '%s' has the same name and signature as another method in this type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:292)
+    static member chkDuplicateMethod(a0 : System.String) = (438, GetStringFunc("chkDuplicateMethod",",,,%s,,,") a0)
+    /// Duplicate method. The method '%s' has the same name and signature as another method in this type once tuples, functions and/or units of measure are erased.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:293)
+    static member chkDuplicateMethodWithSuffix(a0 : System.String) = (438, GetStringFunc("chkDuplicateMethodWithSuffix",",,,%s,,,") a0)
+    /// The method '%s' has curried arguments but has the same name as another method in this type. Methods with curried arguments cannot be overloaded. Consider using a method taking tupled arguments.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:294)
+    static member chkDuplicateMethodCurried(a0 : System.String) = (439, GetStringFunc("chkDuplicateMethodCurried",",,,%s,,,") a0)
+    /// Methods with curried arguments cannot declare 'out', 'ParamArray', 'optional' or 'byref' arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:295)
+    static member chkCurriedMethodsCantHaveOutParams() = (440, GetStringFunc("chkCurriedMethodsCantHaveOutParams",",,,") )
+    /// Duplicate property. The property '%s' has the same name and signature as another property in this type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:296)
+    static member chkDuplicateProperty(a0 : System.String) = (441, GetStringFunc("chkDuplicateProperty",",,,%s,,,") a0)
+    /// Duplicate property. The property '%s' has the same name and signature as another property in this type once tuples, functions and/or units of measure are erased.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:297)
+    static member chkDuplicatePropertyWithSuffix(a0 : System.String) = (441, GetStringFunc("chkDuplicatePropertyWithSuffix",",,,%s,,,") a0)
+    /// Duplicate method. The abstract method '%s' has the same name and signature as an abstract method in an inherited type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:298)
+    static member chkDuplicateMethodInheritedType(a0 : System.String) = (442, GetStringFunc("chkDuplicateMethodInheritedType",",,,%s,,,") a0)
+    /// Duplicate method. The abstract method '%s' has the same name and signature as an abstract method in an inherited type once tuples, functions and/or units of measure are erased.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:299)
+    static member chkDuplicateMethodInheritedTypeWithSuffix(a0 : System.String) = (442, GetStringFunc("chkDuplicateMethodInheritedTypeWithSuffix",",,,%s,,,") a0)
+    /// This type implements or inherits the same interface at different generic instantiations '%s' and '%s'. This is not permitted in this version of F#.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:300)
+    static member chkMultipleGenericInterfaceInstantiations(a0 : System.String, a1 : System.String) = (443, GetStringFunc("chkMultipleGenericInterfaceInstantiations",",,,%s,,,%s,,,") a0 a1)
+    /// The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:301)
+    static member chkValueWithDefaultValueMustHaveDefaultValue() = (444, GetStringFunc("chkValueWithDefaultValueMustHaveDefaultValue",",,,") )
+    /// The type abbreviation contains byrefs. This is not permitted by F#.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:302)
+    static member chkNoByrefInTypeAbbrev() = (445, GetStringFunc("chkNoByrefInTypeAbbrev",",,,") )
+    /// The variable '%s' is bound in a quotation but is used as part of a spliced expression. This is not permitted since it may escape its scope.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:306)
+    static member crefBoundVarUsedInSplice(a0 : System.String) = (446, GetStringFunc("crefBoundVarUsedInSplice",",,,%s,,,") a0)
+    /// Quotations cannot contain uses of generic expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:307)
+    static member crefQuotationsCantContainGenericExprs() = (447, GetStringFunc("crefQuotationsCantContainGenericExprs",",,,") )
+    /// Quotations cannot contain function declarations that are inferred or declared to be generic. Consider adding some type constraints to make this a valid quoted expression.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:308)
+    static member crefQuotationsCantContainGenericFunctions() = (448, GetStringFunc("crefQuotationsCantContainGenericFunctions",",,,") )
+    /// Quotations cannot contain object expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:309)
+    static member crefQuotationsCantContainObjExprs() = (449, GetStringFunc("crefQuotationsCantContainObjExprs",",,,") )
+    /// Quotations cannot contain expressions that take the address of a field
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:310)
+    static member crefQuotationsCantContainAddressOf() = (450, GetStringFunc("crefQuotationsCantContainAddressOf",",,,") )
+    /// Quotations cannot contain expressions that fetch static fields
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:311)
+    static member crefQuotationsCantContainStaticFieldRef() = (451, GetStringFunc("crefQuotationsCantContainStaticFieldRef",",,,") )
+    /// Quotations cannot contain inline assembly code or pattern matching on arrays
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:312)
+    static member crefQuotationsCantContainInlineIL() = (452, GetStringFunc("crefQuotationsCantContainInlineIL",",,,") )
+    /// Quotations cannot contain descending for loops
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:313)
+    static member crefQuotationsCantContainDescendingForLoops() = (453, GetStringFunc("crefQuotationsCantContainDescendingForLoops",",,,") )
+    /// Quotations cannot contain expressions that fetch union case indexes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:314)
+    static member crefQuotationsCantFetchUnionIndexes() = (454, GetStringFunc("crefQuotationsCantFetchUnionIndexes",",,,") )
+    /// Quotations cannot contain expressions that set union case fields
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:315)
+    static member crefQuotationsCantSetUnionFields() = (455, GetStringFunc("crefQuotationsCantSetUnionFields",",,,") )
+    /// Quotations cannot contain expressions that set fields in exception values
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:316)
+    static member crefQuotationsCantSetExceptionFields() = (456, GetStringFunc("crefQuotationsCantSetExceptionFields",",,,") )
+    /// Quotations cannot contain expressions that require byref pointers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:317)
+    static member crefQuotationsCantRequireByref() = (457, GetStringFunc("crefQuotationsCantRequireByref",",,,") )
+    /// Quotations cannot contain expressions that make member constraint calls, or uses of operators that implicitly resolve to a member constraint call
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:318)
+    static member crefQuotationsCantCallTraitMembers() = (458, GetStringFunc("crefQuotationsCantCallTraitMembers",",,,") )
+    /// Quotations cannot contain this kind of constant
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:319)
+    static member crefQuotationsCantContainThisConstant() = (459, GetStringFunc("crefQuotationsCantContainThisConstant",",,,") )
+    /// Quotations cannot contain this kind of pattern match
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:320)
+    static member crefQuotationsCantContainThisPatternMatch() = (460, GetStringFunc("crefQuotationsCantContainThisPatternMatch",",,,") )
+    /// Quotations cannot contain array pattern matching
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:321)
+    static member crefQuotationsCantContainArrayPatternMatching() = (461, GetStringFunc("crefQuotationsCantContainArrayPatternMatching",",,,") )
+    /// Quotations cannot contain this kind of type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:322)
+    static member crefQuotationsCantContainThisType() = (462, GetStringFunc("crefQuotationsCantContainThisType",",,,") )
+    /// Quotations cannot contain literal byte arrays
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:323)
+    static member crefQuotationsCantContainLiteralByteArrays() = (3002, GetStringFunc("crefQuotationsCantContainLiteralByteArrays",",,,") )
+    /// Inner generic functions are not permitted in quoted expressions. Consider adding some type constraints until this function is no longer generic.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:324)
+    static member crefNoInnerGenericsInQuotations() = (3003, GetStringFunc("crefNoInnerGenericsInQuotations",",,,") )
+    /// The declared type parameter '%s' cannot be used here since the type parameter cannot be resolved at compile time
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:328)
+    static member csTypeCannotBeResolvedAtCompileTime(a0 : System.String) = (GetStringFunc("csTypeCannotBeResolvedAtCompileTime",",,,%s,,,") a0)
+    /// This code is less generic than indicated by its annotations. A unit-of-measure specified using '_' has been determined to be '1', i.e. dimensionless. Consider making the code generic, or removing the use of '_'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:329)
+    static member csCodeLessGeneric() = (464, GetStringFunc("csCodeLessGeneric",",,,") )
+    /// Type inference problem too complicated (maximum iteration depth reached). Consider adding further type annotations.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:330)
+    static member csTypeInferenceMaxDepth() = (465, GetStringFunc("csTypeInferenceMaxDepth",",,,") )
+    /// Expected arguments to an instance member
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:331)
+    static member csExpectedArguments() = (GetStringFunc("csExpectedArguments",",,,") )
+    /// This indexer expects %d arguments but is here given %d
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:332)
+    static member csIndexArgumentMismatch(a0 : System.Int32, a1 : System.Int32) = (GetStringFunc("csIndexArgumentMismatch",",,,%d,,,%d,,,") a0 a1)
+    /// Expecting a type supporting the operator '%s' but given a function type. You may be missing an argument to a function.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:333)
+    static member csExpectTypeWithOperatorButGivenFunction(a0 : System.String) = (GetStringFunc("csExpectTypeWithOperatorButGivenFunction",",,,%s,,,") a0)
+    /// The type '%s' does not support any operators named '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:334)
+    static member csTypeDoesNotSupportOperator(a0 : System.String, a1 : System.String) = (GetStringFunc("csTypeDoesNotSupportOperator",",,,%s,,,%s,,,") a0 a1)
+    /// The type '%s' does not support a conversion to the type '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:335)
+    static member csTypeDoesNotSupportConversion(a0 : System.String, a1 : System.String) = (GetStringFunc("csTypeDoesNotSupportConversion",",,,%s,,,%s,,,") a0 a1)
+    /// The type '%s' has a method '%s' (full name '%s'), but the method is static
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:336)
+    static member csMethodFoundButIsStatic(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("csMethodFoundButIsStatic",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The type '%s' has a method '%s' (full name '%s'), but the method is not static
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:337)
+    static member csMethodFoundButIsNotStatic(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("csMethodFoundButIsNotStatic",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The constraints 'struct' and 'not struct' are inconsistent
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:338)
+    static member csStructConstraintInconsistent() = (472, GetStringFunc("csStructConstraintInconsistent",",,,") )
+    /// The type '%s' does not have 'null' as a proper value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:339)
+    static member csTypeDoesNotHaveNull(a0 : System.String) = (GetStringFunc("csTypeDoesNotHaveNull",",,,%s,,,") a0)
+    /// The type '%s' does not support the 'comparison' constraint because it has the 'NoComparison' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:340)
+    static member csTypeDoesNotSupportComparison1(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportComparison1",",,,%s,,,") a0)
+    /// The type '%s' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:341)
+    static member csTypeDoesNotSupportComparison2(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportComparison2",",,,%s,,,") a0)
+    /// The type '%s' does not support the 'comparison' constraint because it is a record, union or struct with one or more structural element types which do not support the 'comparison' constraint. Either avoid the use of comparison with this type, or add the 'StructuralComparison' attribute to the type to determine which field type does not support comparison
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:342)
+    static member csTypeDoesNotSupportComparison3(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportComparison3",",,,%s,,,") a0)
+    /// The type '%s' does not support the 'equality' constraint because it has the 'NoEquality' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:343)
+    static member csTypeDoesNotSupportEquality1(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportEquality1",",,,%s,,,") a0)
+    /// The type '%s' does not support the 'equality' constraint because it is a function type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:344)
+    static member csTypeDoesNotSupportEquality2(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportEquality2",",,,%s,,,") a0)
+    /// The type '%s' does not support the 'equality' constraint because it is a record, union or struct with one or more structural element types which do not support the 'equality' constraint. Either avoid the use of equality with this type, or add the 'StructuralEquality' attribute to the type to determine which field type does not support equality
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:345)
+    static member csTypeDoesNotSupportEquality3(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportEquality3",",,,%s,,,") a0)
+    /// The type '%s' is not a CLI enum type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:346)
+    static member csTypeIsNotEnumType(a0 : System.String) = (GetStringFunc("csTypeIsNotEnumType",",,,%s,,,") a0)
+    /// The type '%s' has a non-standard delegate type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:347)
+    static member csTypeHasNonStandardDelegateType(a0 : System.String) = (GetStringFunc("csTypeHasNonStandardDelegateType",",,,%s,,,") a0)
+    /// The type '%s' is not a CLI delegate type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:348)
+    static member csTypeIsNotDelegateType(a0 : System.String) = (GetStringFunc("csTypeIsNotDelegateType",",,,%s,,,") a0)
+    /// This type parameter cannot be instantiated to 'Nullable'. This is a restriction imposed in order to ensure the meaning of 'null' in some CLI languages is not confusing when used in conjunction with 'Nullable' values.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:349)
+    static member csTypeParameterCannotBeNullable() = (GetStringFunc("csTypeParameterCannotBeNullable",",,,") )
+    /// A generic construct requires that the type '%s' is a CLI or F# struct type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:350)
+    static member csGenericConstructRequiresStructType(a0 : System.String) = (GetStringFunc("csGenericConstructRequiresStructType",",,,%s,,,") a0)
+    /// A generic construct requires that the type '%s' is an unmanaged type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:351)
+    static member csGenericConstructRequiresUnmanagedType(a0 : System.String) = (GetStringFunc("csGenericConstructRequiresUnmanagedType",",,,%s,,,") a0)
+    /// The type '%s' is not compatible with any of the types %s, arising from the use of a printf-style format string
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:352)
+    static member csTypeNotCompatibleBecauseOfPrintf(a0 : System.String, a1 : System.String) = (GetStringFunc("csTypeNotCompatibleBecauseOfPrintf",",,,%s,,,%s,,,") a0 a1)
+    /// A generic construct requires that the type '%s' have reference semantics, but it does not, i.e. it is a struct
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:353)
+    static member csGenericConstructRequiresReferenceSemantics(a0 : System.String) = (GetStringFunc("csGenericConstructRequiresReferenceSemantics",",,,%s,,,") a0)
+    /// A generic construct requires that the type '%s' be non-abstract
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:354)
+    static member csGenericConstructRequiresNonAbstract(a0 : System.String) = (GetStringFunc("csGenericConstructRequiresNonAbstract",",,,%s,,,") a0)
+    /// A generic construct requires that the type '%s' have a public default constructor
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:355)
+    static member csGenericConstructRequiresPublicDefaultConstructor(a0 : System.String) = (GetStringFunc("csGenericConstructRequiresPublicDefaultConstructor",",,,%s,,,") a0)
+    /// Type instantiation length mismatch
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:356)
+    static member csTypeInstantiationLengthMismatch() = (483, GetStringFunc("csTypeInstantiationLengthMismatch",",,,") )
+    /// Optional arguments not permitted here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:357)
+    static member csOptionalArgumentNotPermittedHere() = (484, GetStringFunc("csOptionalArgumentNotPermittedHere",",,,") )
+    /// %s is not a static member
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:358)
+    static member csMemberIsNotStatic(a0 : System.String) = (485, GetStringFunc("csMemberIsNotStatic",",,,%s,,,") a0)
+    /// %s is not an instance member
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:359)
+    static member csMemberIsNotInstance(a0 : System.String) = (486, GetStringFunc("csMemberIsNotInstance",",,,%s,,,") a0)
+    /// Argument length mismatch
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:360)
+    static member csArgumentLengthMismatch() = (487, GetStringFunc("csArgumentLengthMismatch",",,,") )
+    /// The argument types don't match
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:361)
+    static member csArgumentTypesDoNotMatch() = (488, GetStringFunc("csArgumentTypesDoNotMatch",",,,") )
+    /// This method expects a CLI 'params' parameter in this position. 'params' is a way of passing a variable number of arguments to a method in languages such as C#. Consider passing an array for this argument
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:362)
+    static member csMethodExpectsParams() = (489, GetStringFunc("csMethodExpectsParams",",,,") )
+    /// The member or object constructor '%s' is not %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:363)
+    static member csMemberIsNotAccessible(a0 : System.String, a1 : System.String) = (490, GetStringFunc("csMemberIsNotAccessible",",,,%s,,,%s,,,") a0 a1)
+    /// The member or object constructor '%s' is not %s. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:364)
+    static member csMemberIsNotAccessible2(a0 : System.String, a1 : System.String) = (491, GetStringFunc("csMemberIsNotAccessible2",",,,%s,,,%s,,,") a0 a1)
+    /// %s is not a static method
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:365)
+    static member csMethodIsNotAStaticMethod(a0 : System.String) = (492, GetStringFunc("csMethodIsNotAStaticMethod",",,,%s,,,") a0)
+    /// %s is not an instance method
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:366)
+    static member csMethodIsNotAnInstanceMethod(a0 : System.String) = (493, GetStringFunc("csMethodIsNotAnInstanceMethod",",,,%s,,,") a0)
+    /// The member or object constructor '%s' has no argument or settable return property '%s'. %s.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:367)
+    static member csMemberHasNoArgumentOrReturnProperty(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("csMemberHasNoArgumentOrReturnProperty",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The required signature is %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:368)
+    static member csRequiredSignatureIs(a0 : System.String) = (495, GetStringFunc("csRequiredSignatureIs",",,,%s,,,") a0)
+    /// The member or object constructor '%s' requires %d argument(s). The required signature is '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:369)
+    static member csMemberSignatureMismatch(a0 : System.String, a1 : System.Int32, a2 : System.String) = (496, GetStringFunc("csMemberSignatureMismatch",",,,%s,,,%d,,,%s,,,") a0 a1 a2)
+    /// The member or object constructor '%s' requires %d additional argument(s). The required signature is '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:370)
+    static member csMemberSignatureMismatch2(a0 : System.String, a1 : System.Int32, a2 : System.String) = (497, GetStringFunc("csMemberSignatureMismatch2",",,,%s,,,%d,,,%s,,,") a0 a1 a2)
+    /// The member or object constructor '%s' requires %d argument(s). The required signature is '%s'. Some names for missing arguments are %s.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:371)
+    static member csMemberSignatureMismatch3(a0 : System.String, a1 : System.Int32, a2 : System.String, a3 : System.String) = (498, GetStringFunc("csMemberSignatureMismatch3",",,,%s,,,%d,,,%s,,,%s,,,") a0 a1 a2 a3)
+    /// The member or object constructor '%s' requires %d additional argument(s). The required signature is '%s'. Some names for missing arguments are %s.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:372)
+    static member csMemberSignatureMismatch4(a0 : System.String, a1 : System.Int32, a2 : System.String, a3 : System.String) = (499, GetStringFunc("csMemberSignatureMismatch4",",,,%s,,,%d,,,%s,,,%s,,,") a0 a1 a2 a3)
+    /// The member or object constructor '%s' requires %d argument(s) but is here given %d unnamed and %d named argument(s). The required signature is '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:373)
+    static member csMemberSignatureMismatchArityNamed(a0 : System.String, a1 : System.Int32, a2 : System.Int32, a3 : System.Int32, a4 : System.String) = (500, GetStringFunc("csMemberSignatureMismatchArityNamed",",,,%s,,,%d,,,%d,,,%d,,,%s,,,") a0 a1 a2 a3 a4)
+    /// The member or object constructor '%s' takes %d argument(s) but is here given %d. The required signature is '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:374)
+    static member csMemberSignatureMismatchArity(a0 : System.String, a1 : System.Int32, a2 : System.Int32, a3 : System.String) = (501, GetStringFunc("csMemberSignatureMismatchArity",",,,%s,,,%d,,,%d,,,%s,,,") a0 a1 a2 a3)
+    /// The member or object constructor '%s' takes %d type argument(s) but is here given %d. The required signature is '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:375)
+    static member csMemberSignatureMismatchArityType(a0 : System.String, a1 : System.Int32, a2 : System.Int32, a3 : System.String) = (502, GetStringFunc("csMemberSignatureMismatchArityType",",,,%s,,,%d,,,%d,,,%s,,,") a0 a1 a2 a3)
+    /// The member or object constructor '%s' taking %d arguments are not accessible from this code location. All accessible versions of method '%s' take %d arguments.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:376)
+    static member csMemberNotAccessible(a0 : System.String, a1 : System.Int32, a2 : System.String, a3 : System.Int32) = (503, GetStringFunc("csMemberNotAccessible",",,,%s,,,%d,,,%s,,,%d,,,") a0 a1 a2 a3)
+    /// Incorrect generic instantiation. No %s member named '%s' takes %d generic arguments.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:377)
+    static member csIncorrectGenericInstantiation(a0 : System.String, a1 : System.String, a2 : System.Int32) = (504, GetStringFunc("csIncorrectGenericInstantiation",",,,%s,,,%s,,,%d,,,") a0 a1 a2)
+    /// The member or object constructor '%s' does not take %d argument(s). An overload was found taking %d arguments.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:378)
+    static member csMemberOverloadArityMismatch(a0 : System.String, a1 : System.Int32, a2 : System.Int32) = (505, GetStringFunc("csMemberOverloadArityMismatch",",,,%s,,,%d,,,%d,,,") a0 a1 a2)
+    /// No %s member or object constructor named '%s' takes %d arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:379)
+    static member csNoMemberTakesTheseArguments(a0 : System.String, a1 : System.String, a2 : System.Int32) = (506, GetStringFunc("csNoMemberTakesTheseArguments",",,,%s,,,%s,,,%d,,,") a0 a1 a2)
+    /// No %s member or object constructor named '%s' takes %d arguments. Note the call to this member also provides %d named arguments.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:380)
+    static member csNoMemberTakesTheseArguments2(a0 : System.String, a1 : System.String, a2 : System.Int32, a3 : System.Int32) = (507, GetStringFunc("csNoMemberTakesTheseArguments2",",,,%s,,,%s,,,%d,,,%d,,,") a0 a1 a2 a3)
+    /// No %s member or object constructor named '%s' takes %d arguments. The named argument '%s' doesn't correspond to any argument or settable return property for any overload.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:381)
+    static member csNoMemberTakesTheseArguments3(a0 : System.String, a1 : System.String, a2 : System.Int32, a3 : System.String) = (508, GetStringFunc("csNoMemberTakesTheseArguments3",",,,%s,,,%s,,,%d,,,%s,,,") a0 a1 a2 a3)
+    /// Method or object constructor '%s' not found
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:382)
+    static member csMethodNotFound(a0 : System.String) = (509, GetStringFunc("csMethodNotFound",",,,%s,,,") a0)
+    /// No overloads match for method '%s'. The available overloads are shown below (or in the Error List window).
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:383)
+    static member csNoOverloadsFound(a0 : System.String) = (GetStringFunc("csNoOverloadsFound",",,,%s,,,") a0)
+    /// A unique overload for method '%s' could not be determined based on type information prior to this program point. The available overloads are shown below (or in the Error List window). A type annotation may be needed.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:384)
+    static member csMethodIsOverloaded(a0 : System.String) = (GetStringFunc("csMethodIsOverloaded",",,,%s,,,") a0)
+    /// Accessibility modifiers are not permitted on 'do' bindings
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:388)
+    static member parsDoCannotHaveVisibilityDeclarations() = (512, GetStringFunc("parsDoCannotHaveVisibilityDeclarations",",,,") )
+    /// End of file in #if section begun at or after here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:389)
+    static member parsEofInHashIf() = (513, GetStringFunc("parsEofInHashIf",",,,") )
+    /// End of file in string begun at or before here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:390)
+    static member parsEofInString() = (514, GetStringFunc("parsEofInString",",,,") )
+    /// End of file in verbatim string begun at or before here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:391)
+    static member parsEofInVerbatimString() = (515, GetStringFunc("parsEofInVerbatimString",",,,") )
+    /// End of file in comment begun at or before here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:392)
+    static member parsEofInComment() = (516, GetStringFunc("parsEofInComment",",,,") )
+    /// End of file in string embedded in comment begun at or before here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:393)
+    static member parsEofInStringInComment() = (517, GetStringFunc("parsEofInStringInComment",",,,") )
+    /// End of file in verbatim string embedded in comment begun at or before here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:394)
+    static member parsEofInVerbatimStringInComment() = (518, GetStringFunc("parsEofInVerbatimStringInComment",",,,") )
+    /// End of file in IF-OCAML section begun at or before here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:395)
+    static member parsEofInIfOcaml() = (519, GetStringFunc("parsEofInIfOcaml",",,,") )
+    /// End of file in directive begun at or before here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:396)
+    static member parsEofInDirective() = (520, GetStringFunc("parsEofInDirective",",,,") )
+    /// No #endif found for #if or #else
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:397)
+    static member parsNoHashEndIfFound() = (521, GetStringFunc("parsNoHashEndIfFound",",,,") )
+    /// Attributes have been ignored in this construct
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:398)
+    static member parsAttributesIgnored() = (522, GetStringFunc("parsAttributesIgnored",",,,") )
+    /// 'use' bindings are not permitted in implicit class constructors
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:399)
+    static member parsUseBindingsIllegalInImplicitClassConstructors() = (523, GetStringFunc("parsUseBindingsIllegalInImplicitClassConstructors",",,,") )
+    /// 'use' bindings are not permitted in modules and are treated as 'let' bindings
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:400)
+    static member parsUseBindingsIllegalInModules() = (524, GetStringFunc("parsUseBindingsIllegalInModules",",,,") )
+    /// An integer for loop must use a simple identifier
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:401)
+    static member parsIntegerForLoopRequiresSimpleIdentifier() = (525, GetStringFunc("parsIntegerForLoopRequiresSimpleIdentifier",",,,") )
+    /// At most one 'with' augmentation is permitted
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:402)
+    static member parsOnlyOneWithAugmentationAllowed() = (526, GetStringFunc("parsOnlyOneWithAugmentationAllowed",",,,") )
+    /// A semicolon is not expected at this point
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:403)
+    static member parsUnexpectedSemicolon() = (527, GetStringFunc("parsUnexpectedSemicolon",",,,") )
+    /// Unexpected end of input
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:404)
+    static member parsUnexpectedEndOfFile() = (528, GetStringFunc("parsUnexpectedEndOfFile",",,,") )
+    /// Accessibility modifiers are not permitted here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:405)
+    static member parsUnexpectedVisibilityDeclaration() = (529, GetStringFunc("parsUnexpectedVisibilityDeclaration",",,,") )
+    /// Only '#' compiler directives may occur prior to the first 'namespace' declaration
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:406)
+    static member parsOnlyHashDirectivesAllowed() = (530, GetStringFunc("parsOnlyHashDirectivesAllowed",",,,") )
+    /// Accessibility modifiers should come immediately prior to the identifier naming a construct
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:407)
+    static member parsVisibilityDeclarationsShouldComePriorToIdentifier() = (531, GetStringFunc("parsVisibilityDeclarationsShouldComePriorToIdentifier",",,,") )
+    /// Files should begin with either a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule', but not both. To define a module within a namespace use 'module SomeModule = ...'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:408)
+    static member parsNamespaceOrModuleNotBoth() = (532, GetStringFunc("parsNamespaceOrModuleNotBoth",",,,") )
+    /// A module abbreviation must be a simple name, not a path
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:409)
+    static member parsModuleAbbreviationMustBeSimpleName() = (534, GetStringFunc("parsModuleAbbreviationMustBeSimpleName",",,,") )
+    /// Ignoring attributes on module abbreviation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:410)
+    static member parsIgnoreAttributesOnModuleAbbreviation() = (535, GetStringFunc("parsIgnoreAttributesOnModuleAbbreviation",",,,") )
+    /// Ignoring accessibility attribute on module abbreviation. Module abbreviations are always private.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:411)
+    static member parsIgnoreAttributesOnModuleAbbreviationAlwaysPrivate() = (536, GetStringFunc("parsIgnoreAttributesOnModuleAbbreviationAlwaysPrivate",",,,") )
+    /// Ignoring visibility attribute on module abbreviation. Module abbreviations are always private.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:412)
+    static member parsIgnoreVisibilityOnModuleAbbreviationAlwaysPrivate() = (537, GetStringFunc("parsIgnoreVisibilityOnModuleAbbreviationAlwaysPrivate",",,,") )
+    /// Unclosed block
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:413)
+    static member parsUnClosedBlockInHashLight() = (538, GetStringFunc("parsUnClosedBlockInHashLight",",,,") )
+    /// Unmatched 'begin' or 'struct'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:414)
+    static member parsUnmatchedBeginOrStruct() = (539, GetStringFunc("parsUnmatchedBeginOrStruct",",,,") )
+    /// A module name must be a simple name, not a path
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:415)
+    static member parsModuleDefnMustBeSimpleName() = (541, GetStringFunc("parsModuleDefnMustBeSimpleName",",,,") )
+    /// Unexpected empty type moduleDefn list
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:416)
+    static member parsUnexpectedEmptyModuleDefn() = (542, GetStringFunc("parsUnexpectedEmptyModuleDefn",",,,") )
+    /// Attributes should be placed before 'val'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:417)
+    static member parsAttributesMustComeBeforeVal() = (GetStringFunc("parsAttributesMustComeBeforeVal",",,,") )
+    /// Attributes are not permitted on interface implementations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:418)
+    static member parsAttributesAreNotPermittedOnInterfaceImplementations() = (543, GetStringFunc("parsAttributesAreNotPermittedOnInterfaceImplementations",",,,") )
+    /// Syntax error
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:419)
+    static member parsSyntaxError() = (544, GetStringFunc("parsSyntaxError",",,,") )
+    /// Augmentations are not permitted on delegate type moduleDefns
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:420)
+    static member parsAugmentationsIllegalOnDelegateType() = (545, GetStringFunc("parsAugmentationsIllegalOnDelegateType",",,,") )
+    /// Unmatched 'class', 'interface' or 'struct'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:421)
+    static member parsUnmatchedClassInterfaceOrStruct() = (546, GetStringFunc("parsUnmatchedClassInterfaceOrStruct",",,,") )
+    /// A type definition requires one or more members or other declarations. If you intend to define an empty class, struct or interface, then use 'type ... = class end', 'interface end' or 'struct end'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:422)
+    static member parsEmptyTypeDefinition() = (547, GetStringFunc("parsEmptyTypeDefinition",",,,") )
+    /// Unmatched 'with' or badly formatted 'with' block
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:423)
+    static member parsUnmatchedWith() = (550, GetStringFunc("parsUnmatchedWith",",,,") )
+    /// 'get', 'set' or 'get,set' required
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:424)
+    static member parsGetOrSetRequired() = (551, GetStringFunc("parsGetOrSetRequired",",,,") )
+    /// Only class types may take value arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:425)
+    static member parsOnlyClassCanTakeValueArguments() = (552, GetStringFunc("parsOnlyClassCanTakeValueArguments",",,,") )
+    /// Unmatched 'begin'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:426)
+    static member parsUnmatchedBegin() = (553, GetStringFunc("parsUnmatchedBegin",",,,") )
+    /// Invalid declaration syntax
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:427)
+    static member parsInvalidDeclarationSyntax() = (554, GetStringFunc("parsInvalidDeclarationSyntax",",,,") )
+    /// 'get' and/or 'set' required
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:428)
+    static member parsGetAndOrSetRequired() = (555, GetStringFunc("parsGetAndOrSetRequired",",,,") )
+    /// Type annotations on property getters and setters must be given after the 'get()' or 'set(v)', e.g. 'with get() : string = ...'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:429)
+    static member parsTypeAnnotationsOnGetSet() = (556, GetStringFunc("parsTypeAnnotationsOnGetSet",",,,") )
+    /// A getter property is expected to be a function, e.g. 'get() = ...' or 'get(index) = ...'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:430)
+    static member parsGetterMustHaveAtLeastOneArgument() = (557, GetStringFunc("parsGetterMustHaveAtLeastOneArgument",",,,") )
+    /// Multiple accessibilities given for property getter or setter
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:431)
+    static member parsMultipleAccessibilitiesForGetSet() = (558, GetStringFunc("parsMultipleAccessibilitiesForGetSet",",,,") )
+    /// Property setters must be defined using 'set value = ', 'set idx value = ' or 'set (idx1,...,idxN) value = ... '
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:432)
+    static member parsSetSyntax() = (559, GetStringFunc("parsSetSyntax",",,,") )
+    /// Interfaces always have the same visibility as the enclosing type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:433)
+    static member parsInterfacesHaveSameVisibilityAsEnclosingType() = (560, GetStringFunc("parsInterfacesHaveSameVisibilityAsEnclosingType",",,,") )
+    /// Accessibility modifiers are not allowed on this member. Abstract slots always have the same visibility as the enclosing type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:434)
+    static member parsAccessibilityModsIllegalForAbstract() = (561, GetStringFunc("parsAccessibilityModsIllegalForAbstract",",,,") )
+    /// Attributes are not permitted on 'inherit' declarations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:435)
+    static member parsAttributesIllegalOnInherit() = (562, GetStringFunc("parsAttributesIllegalOnInherit",",,,") )
+    /// Accessibility modifiers are not permitted on an 'inherits' declaration
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:436)
+    static member parsVisibilityIllegalOnInherit() = (563, GetStringFunc("parsVisibilityIllegalOnInherit",",,,") )
+    /// 'inherit' declarations cannot have 'as' bindings. To access members of the base class when overriding a method, the syntax 'base.SomeMember' may be used; 'base' is a keyword. Remove this 'as' binding.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:437)
+    static member parsInheritDeclarationsCannotHaveAsBindings() = (564, GetStringFunc("parsInheritDeclarationsCannotHaveAsBindings",",,,") )
+    /// Attributes are not allowed here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:438)
+    static member parsAttributesIllegalHere() = (565, GetStringFunc("parsAttributesIllegalHere",",,,") )
+    /// Accessibility modifiers are not permitted in this position for type abbreviations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:439)
+    static member parsTypeAbbreviationsCannotHaveVisibilityDeclarations() = (566, GetStringFunc("parsTypeAbbreviationsCannotHaveVisibilityDeclarations",",,,") )
+    /// Accessibility modifiers are not permitted in this position for enum types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:440)
+    static member parsEnumTypesCannotHaveVisibilityDeclarations() = (567, GetStringFunc("parsEnumTypesCannotHaveVisibilityDeclarations",",,,") )
+    /// All enum fields must be given values
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:441)
+    static member parsAllEnumFieldsRequireValues() = (568, GetStringFunc("parsAllEnumFieldsRequireValues",",,,") )
+    /// Accessibility modifiers are not permitted on inline assembly code types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:442)
+    static member parsInlineAssemblyCannotHaveVisibilityDeclarations() = (569, GetStringFunc("parsInlineAssemblyCannotHaveVisibilityDeclarations",",,,") )
+    /// Unexpected identifier: '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:443)
+    static member parsUnexpectedIdentifier(a0 : System.String) = (571, GetStringFunc("parsUnexpectedIdentifier",",,,%s,,,") a0)
+    /// Accessibility modifiers are not permitted on union cases. Use 'type U = internal ...' or 'type U = private ...' to give an accessibility to the whole representation.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:444)
+    static member parsUnionCasesCannotHaveVisibilityDeclarations() = (572, GetStringFunc("parsUnionCasesCannotHaveVisibilityDeclarations",",,,") )
+    /// Accessibility modifiers are not permitted on enumeration fields
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:445)
+    static member parsEnumFieldsCannotHaveVisibilityDeclarations() = (573, GetStringFunc("parsEnumFieldsCannotHaveVisibilityDeclarations",",,,") )
+    /// Consider using a separate record type instead
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:446)
+    static member parsConsiderUsingSeparateRecordType() = (GetStringFunc("parsConsiderUsingSeparateRecordType",",,,") )
+    /// Accessibility modifiers are not permitted on record fields. Use 'type R = internal ...' or 'type R = private ...' to give an accessibility to the whole representation.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:447)
+    static member parsRecordFieldsCannotHaveVisibilityDeclarations() = (575, GetStringFunc("parsRecordFieldsCannotHaveVisibilityDeclarations",",,,") )
+    /// The declaration form 'let ... and ...' for non-recursive bindings is not used in F# code. Consider using a sequence of 'let' bindings
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:448)
+    static member parsLetAndForNonRecBindings() = (576, GetStringFunc("parsLetAndForNonRecBindings",",,,") )
+    /// No body found for this 'let' or 'do'. The body must be indented to the same column as this line.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:449)
+    static member parsUnmatchedLetOrDo() = (577, GetStringFunc("parsUnmatchedLetOrDo",",,,") )
+    /// Unmatched '('
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:450)
+    static member parsUnmatchedParen() = (583, GetStringFunc("parsUnmatchedParen",",,,") )
+    /// Successive patterns should be separated by spaces or tupled
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:451)
+    static member parsSuccessivePatternsShouldBeSpacedOrTupled() = (584, GetStringFunc("parsSuccessivePatternsShouldBeSpacedOrTupled",",,,") )
+    /// No matching 'in' found for this 'let'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:452)
+    static member parsNoMatchingInForLet() = (586, GetStringFunc("parsNoMatchingInForLet",",,,") )
+    /// Error in the return expression for this 'let'. Possible incorrect indentation.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:453)
+    static member parsErrorInReturnForLetIncorrectIndentation() = (587, GetStringFunc("parsErrorInReturnForLetIncorrectIndentation",",,,") )
+    /// Block following this '%s' is unfinished. Expect an expression.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:454)
+    static member parsExpectedStatementAfterLet(a0 : System.String) = (588, GetStringFunc("parsExpectedStatementAfterLet",",,,%s,,,") a0)
+    /// Unmatched 'if'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:455)
+    static member parsUnmatchedIf() = (589, GetStringFunc("parsUnmatchedIf",",,,") )
+    /// 'assert' may no longer be used as a first class value. Use 'assert <expr>' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:456)
+    static member parsAssertIsNotFirstClassValue() = (590, GetStringFunc("parsAssertIsNotFirstClassValue",",,,") )
+    /// 'done' expected after this expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:457)
+    static member parsDoneExpected() = (591, GetStringFunc("parsDoneExpected",",,,") )
+    /// 'do' expected after this expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:458)
+    static member parsDoExpected() = (592, GetStringFunc("parsDoExpected",",,,") )
+    /// Unclosed 'for', e.g. no 'done' found to match this 'for'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:459)
+    static member parsUnclosedFor() = (593, GetStringFunc("parsUnclosedFor",",,,") )
+    /// Identifier expected
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:460)
+    static member parsIdentifierExpected() = (594, GetStringFunc("parsIdentifierExpected",",,,") )
+    /// '=' expected
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:461)
+    static member parsEqualExpected() = (595, GetStringFunc("parsEqualExpected",",,,") )
+    /// The use of '->' in sequence and computation expressions is limited to the form 'for pat in expr -> expr'. Use the syntax 'for ... in ... do ... yield...' to generate elements in more complex sequence expressions.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:462)
+    static member parsArrowUseIsLimited() = (596, GetStringFunc("parsArrowUseIsLimited",",,,") )
+    /// Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:463)
+    static member parsSuccessiveArgsShouldBeSpacedOrTupled() = (597, GetStringFunc("parsSuccessiveArgsShouldBeSpacedOrTupled",",,,") )
+    /// Unmatched '['
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:464)
+    static member parsUnmatchedBracket() = (598, GetStringFunc("parsUnmatchedBracket",",,,") )
+    /// Missing qualification after '.'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:465)
+    static member parsMissingQualificationAfterDot() = (599, GetStringFunc("parsMissingQualificationAfterDot",",,,") )
+    /// In F# code you may use 'expr.[expr]'. A type annotation may be required to indicate the first expression is an array
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:466)
+    static member parsParenFormIsForML() = (GetStringFunc("parsParenFormIsForML",",,,") )
+    /// Mismatched quotation, beginning with '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:467)
+    static member parsMismatchedQuote(a0 : System.String) = (601, GetStringFunc("parsMismatchedQuote",",,,%s,,,") a0)
+    /// Unmatched '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:468)
+    static member parsUnmatched(a0 : System.String) = (602, GetStringFunc("parsUnmatched",",,,%s,,,") a0)
+    /// Unmatched '[|'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:469)
+    static member parsUnmatchedBracketBar() = (603, GetStringFunc("parsUnmatchedBracketBar",",,,") )
+    /// Unmatched '{'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:470)
+    static member parsUnmatchedBrace() = (604, GetStringFunc("parsUnmatchedBrace",",,,") )
+    /// Field bindings must have the form 'id = expr;'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:471)
+    static member parsFieldBinding() = (609, GetStringFunc("parsFieldBinding",",,,") )
+    /// This member is not permitted in an object implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:472)
+    static member parsMemberIllegalInObjectImplementation() = (610, GetStringFunc("parsMemberIllegalInObjectImplementation",",,,") )
+    /// Missing function body
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:473)
+    static member parsMissingFunctionBody() = (611, GetStringFunc("parsMissingFunctionBody",",,,") )
+    /// Error in 'function' block
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:474)
+    static member parsErrorInFunctionBlock() = (612, GetStringFunc("parsErrorInFunctionBlock",",,,") )
+    /// Syntax error in labelled type argument
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:475)
+    static member parsSyntaxErrorInLabeledType() = (613, GetStringFunc("parsSyntaxErrorInLabeledType",",,,") )
+    /// Unexpected infix operator in type expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:476)
+    static member parsUnexpectedInfixOperator() = (615, GetStringFunc("parsUnexpectedInfixOperator",",,,") )
+    /// The syntax '(typ,...,typ) ident' is not used in F# code. Consider using 'ident<typ,...,typ>' instead
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:477)
+    static member parsMultiArgumentGenericTypeFormDeprecated() = (GetStringFunc("parsMultiArgumentGenericTypeFormDeprecated",",,,") )
+    /// Unexpected integer literal in type expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:478)
+    static member parsUnexpectedIntegerLiteral() = (618, GetStringFunc("parsUnexpectedIntegerLiteral",",,,") )
+    /// Unexpected infix operator in unit-of-measure expression. Legal operators are '*', '/' and '^'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:479)
+    static member parsUnexpectedOperatorForUnitOfMeasure() = (619, GetStringFunc("parsUnexpectedOperatorForUnitOfMeasure",",,,") )
+    /// Unexpected integer literal in unit-of-measure expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:480)
+    static member parsUnexpectedIntegerLiteralForUnitOfMeasure() = (620, GetStringFunc("parsUnexpectedIntegerLiteralForUnitOfMeasure",",,,") )
+    /// Syntax error: unexpected type parameter specification
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:481)
+    static member parsUnexpectedTypeParameter() = (621, GetStringFunc("parsUnexpectedTypeParameter",",,,") )
+    /// Mismatched quotation operator name, beginning with '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:482)
+    static member parsMismatchedQuotationName(a0 : System.String) = (622, GetStringFunc("parsMismatchedQuotationName",",,,%s,,,") a0)
+    /// Active pattern case identifiers must begin with an uppercase letter
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:483)
+    static member parsActivePatternCaseMustBeginWithUpperCase() = (623, GetStringFunc("parsActivePatternCaseMustBeginWithUpperCase",",,,") )
+    /// No '=' symbol should follow a 'namespace' declaration
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:484)
+    static member parsNoEqualShouldFollowNamespace() = (GetStringFunc("parsNoEqualShouldFollowNamespace",",,,") )
+    /// The syntax 'module ... = struct .. end' is not used in F# code. Consider using 'module ... = begin .. end'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:485)
+    static member parsSyntaxModuleStructEndDeprecated() = (GetStringFunc("parsSyntaxModuleStructEndDeprecated",",,,") )
+    /// The syntax 'module ... : sig .. end' is not used in F# code. Consider using 'module ... = begin .. end'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:486)
+    static member parsSyntaxModuleSigEndDeprecated() = (GetStringFunc("parsSyntaxModuleSigEndDeprecated",",,,") )
+    /// A static field was used where an instance field is expected
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:490)
+    static member tcStaticFieldUsedWhenInstanceFieldExpected() = (627, GetStringFunc("tcStaticFieldUsedWhenInstanceFieldExpected",",,,") )
+    /// Method '%s' is not accessible from this code location
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:491)
+    static member tcMethodNotAccessible(a0 : System.String) = (629, GetStringFunc("tcMethodNotAccessible",",,,%s,,,") a0)
+    /// Fields which are type functions cannot be mutated
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:492)
+    static member tcTypeFunctionFieldsCannotBeMutated() = (630, GetStringFunc("tcTypeFunctionFieldsCannotBeMutated",",,,") )
+    /// Implicit product of measures following /
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:493)
+    static member tcImplicitMeasureFollowingSlash() = (632, GetStringFunc("tcImplicitMeasureFollowingSlash",",,,") )
+    /// Unexpected Measure_Anon
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:494)
+    static member tcUnexpectedMeasureAnon() = (633, GetStringFunc("tcUnexpectedMeasureAnon",",,,") )
+    /// Non-zero constants cannot have generic units. For generic zero, write 0.0<_>.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:495)
+    static member tcNonZeroConstantCannotHaveGenericUnit() = (634, GetStringFunc("tcNonZeroConstantCannotHaveGenericUnit",",,,") )
+    /// In sequence expressions, results are generated using 'yield'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:496)
+    static member tcSeqResultsUseYield() = (635, GetStringFunc("tcSeqResultsUseYield",",,,") )
+    /// Unexpected big rational constant
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:497)
+    static member tcUnexpectedBigRationalConstant() = (GetStringFunc("tcUnexpectedBigRationalConstant",",,,") )
+    /// Units-of-measure supported only on float, float32, decimal and signed integer types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:498)
+    static member tcInvalidTypeForUnitsOfMeasure() = (636, GetStringFunc("tcInvalidTypeForUnitsOfMeasure",",,,") )
+    /// Unexpected Const_uint16array
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:499)
+    static member tcUnexpectedConstUint16Array() = (GetStringFunc("tcUnexpectedConstUint16Array",",,,") )
+    /// Unexpected Const_bytearray
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:500)
+    static member tcUnexpectedConstByteArray() = (GetStringFunc("tcUnexpectedConstByteArray",",,,") )
+    /// A parameter with attributes must also be given a name, e.g. '[<Attribute>] paramName : paramType'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:501)
+    static member tcParameterRequiresName() = (640, GetStringFunc("tcParameterRequiresName",",,,") )
+    /// Return values cannot have names
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:502)
+    static member tcReturnValuesCannotHaveNames() = (641, GetStringFunc("tcReturnValuesCannotHaveNames",",,,") )
+    /// MemberKindPropertyGetSet only expected in parse trees
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:503)
+    static member tcMemberKindPropertyGetSetNotExpected() = (GetStringFunc("tcMemberKindPropertyGetSetNotExpected",",,,") )
+    /// Namespaces cannot contain values. Consider using a module to hold your value declarations.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:504)
+    static member tcNamespaceCannotContainValues() = (201, GetStringFunc("tcNamespaceCannotContainValues",",,,") )
+    /// Namespaces cannot contain extension members except in the same file and namespace where the type is defined. Consider using a module to hold declarations of extension members.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:505)
+    static member tcNamespaceCannotContainExtensionMembers() = (644, GetStringFunc("tcNamespaceCannotContainExtensionMembers",",,,") )
+    /// Multiple visibility attributes have been specified for this identifier
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:506)
+    static member tcMultipleVisibilityAttributes() = (645, GetStringFunc("tcMultipleVisibilityAttributes",",,,") )
+    /// Multiple visibility attributes have been specified for this identifier. 'let' bindings in classes are always private, as are any 'let' bindings inside expressions.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:507)
+    static member tcMultipleVisibilityAttributesWithLet() = (646, GetStringFunc("tcMultipleVisibilityAttributesWithLet",",,,") )
+    /// Unrecognized accessibility specification
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:508)
+    static member tcUnrecognizedAccessibilitySpec() = (GetStringFunc("tcUnrecognizedAccessibilitySpec",",,,") )
+    /// The name '(%s)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name '%s' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:509)
+    static member tcInvalidMethodNameForRelationalOperator(a0 : System.String, a1 : System.String) = (GetStringFunc("tcInvalidMethodNameForRelationalOperator",",,,%s,,,%s,,,") a0 a1)
+    /// The name '(%s)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name '%s' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:510)
+    static member tcInvalidMethodNameForEquality(a0 : System.String, a1 : System.String) = (GetStringFunc("tcInvalidMethodNameForEquality",",,,%s,,,%s,,,") a0 a1)
+    /// The name '(%s)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name '%s' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:511)
+    static member tcInvalidMemberName(a0 : System.String, a1 : System.String) = (GetStringFunc("tcInvalidMemberName",",,,%s,,,%s,,,") a0 a1)
+    /// The name '(%s)' should not be used as a member name because it is given a standard definition in the F# library over fixed types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:512)
+    static member tcInvalidMemberNameFixedTypes(a0 : System.String) = (GetStringFunc("tcInvalidMemberNameFixedTypes",",,,%s,,,") a0)
+    /// The '%s' operator should not normally be redefined. To define overloaded comparison semantics for a particular type, implement the 'System.IComparable' interface in the definition of that type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:513)
+    static member tcInvalidOperatorDefinitionRelational(a0 : System.String) = (GetStringFunc("tcInvalidOperatorDefinitionRelational",",,,%s,,,") a0)
+    /// The '%s' operator should not normally be redefined. To define equality semantics for a type, override the 'Object.Equals' member in the definition of that type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:514)
+    static member tcInvalidOperatorDefinitionEquality(a0 : System.String) = (GetStringFunc("tcInvalidOperatorDefinitionEquality",",,,%s,,,") a0)
+    /// The '%s' operator should not normally be redefined. Consider using a different operator name
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:515)
+    static member tcInvalidOperatorDefinition(a0 : System.String) = (GetStringFunc("tcInvalidOperatorDefinition",",,,%s,,,") a0)
+    /// The '%s' operator cannot be redefined. Consider using a different operator name
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:516)
+    static member tcInvalidIndexOperatorDefinition(a0 : System.String) = (GetStringFunc("tcInvalidIndexOperatorDefinition",",,,%s,,,") a0)
+    /// Expected module or namespace parent %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:517)
+    static member tcExpectModuleOrNamespaceParent(a0 : System.String) = (GetStringFunc("tcExpectModuleOrNamespaceParent",",,,%s,,,") a0)
+    /// The struct, record or union type '%s' implements the interface 'System.IComparable' explicitly. You must apply the 'CustomComparison' attribute to the type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:518)
+    static member tcImplementsIComparableExplicitly(a0 : System.String) = (647, GetStringFunc("tcImplementsIComparableExplicitly",",,,%s,,,") a0)
+    /// The struct, record or union type '%s' implements the interface 'System.IComparable<_>' explicitly. You must apply the 'CustomComparison' attribute to the type, and should also provide a consistent implementation of the non-generic interface System.IComparable.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:519)
+    static member tcImplementsGenericIComparableExplicitly(a0 : System.String) = (648, GetStringFunc("tcImplementsGenericIComparableExplicitly",",,,%s,,,") a0)
+    /// The struct, record or union type '%s' implements the interface 'System.IStructuralComparable' explicitly. Apply the 'CustomComparison' attribute to the type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:520)
+    static member tcImplementsIStructuralComparableExplicitly(a0 : System.String) = (649, GetStringFunc("tcImplementsIStructuralComparableExplicitly",",,,%s,,,") a0)
+    /// This record contains fields from inconsistent types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:521)
+    static member tcRecordFieldInconsistentTypes() = (656, GetStringFunc("tcRecordFieldInconsistentTypes",",,,") )
+    /// DLLImport stubs cannot be inlined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:522)
+    static member tcDllImportStubsCannotBeInlined() = (657, GetStringFunc("tcDllImportStubsCannotBeInlined",",,,") )
+    /// Structs may only bind a 'this' parameter at member declarations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:523)
+    static member tcStructsCanOnlyBindThisAtMemberDeclaration() = (658, GetStringFunc("tcStructsCanOnlyBindThisAtMemberDeclaration",",,,") )
+    /// Unexpected expression at recursive inference point
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:524)
+    static member tcUnexpectedExprAtRecInfPoint() = (659, GetStringFunc("tcUnexpectedExprAtRecInfPoint",",,,") )
+    /// This code is less generic than required by its annotations because the explicit type variable '%s' could not be generalized. It was constrained to be '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:525)
+    static member tcLessGenericBecauseOfAnnotation(a0 : System.String, a1 : System.String) = (660, GetStringFunc("tcLessGenericBecauseOfAnnotation",",,,%s,,,%s,,,") a0 a1)
+    /// One or more of the explicit class or function type variables for this binding could not be generalized, because they were constrained to other types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:526)
+    static member tcConstrainedTypeVariableCannotBeGeneralized() = (661, GetStringFunc("tcConstrainedTypeVariableCannotBeGeneralized",",,,") )
+    /// A generic type parameter has been used in a way that constrains it to always be '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:527)
+    static member tcGenericParameterHasBeenConstrained(a0 : System.String) = (662, GetStringFunc("tcGenericParameterHasBeenConstrained",",,,%s,,,") a0)
+    /// This type parameter has been used in a way that constrains it to always be '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:528)
+    static member tcTypeParameterHasBeenConstrained(a0 : System.String) = (663, GetStringFunc("tcTypeParameterHasBeenConstrained",",,,%s,,,") a0)
+    /// The type parameters inferred for this value are not stable under the erasure of type abbreviations. This is due to the use of type abbreviations which drop or reorder type parameters, e.g. \n\ttype taggedInt<'a> = int or\n\ttype swap<'a,'b> = 'b * 'a.\nConsider declaring the type parameters for this value explicitly, e.g.\n\tlet f<'a,'b> ((x,y) : swap<'b,'a>) : swap<'a,'b> = (y,x).
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:529)
+    static member tcTypeParametersInferredAreNotStable() = (664, GetStringFunc("tcTypeParametersInferredAreNotStable",",,,") )
+    /// Explicit type parameters may only be used on module or member bindings
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:530)
+    static member tcExplicitTypeParameterInvalid() = (665, GetStringFunc("tcExplicitTypeParameterInvalid",",,,") )
+    /// You must explicitly declare either all or no type parameters when overriding a generic abstract method
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:531)
+    static member tcOverridingMethodRequiresAllOrNoTypeParameters() = (666, GetStringFunc("tcOverridingMethodRequiresAllOrNoTypeParameters",",,,") )
+    /// The field labels and expected type of this record expression or pattern do not uniquely determine a corresponding record type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:532)
+    static member tcFieldsDoNotDetermineUniqueRecordType() = (667, GetStringFunc("tcFieldsDoNotDetermineUniqueRecordType",",,,") )
+    /// The field '%s' appears twice in this record expression or pattern
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:533)
+    static member tcFieldAppearsTwiceInRecord(a0 : System.String) = (668, GetStringFunc("tcFieldAppearsTwiceInRecord",",,,%s,,,") a0)
+    /// Unknown union case
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:534)
+    static member tcUnknownUnion() = (669, GetStringFunc("tcUnknownUnion",",,,") )
+    /// This code is not sufficiently generic. The type variable %s could not be generalized because it would escape its scope.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:535)
+    static member tcNotSufficientlyGenericBecauseOfScope(a0 : System.String) = (670, GetStringFunc("tcNotSufficientlyGenericBecauseOfScope",",,,%s,,,") a0)
+    /// A property cannot have explicit type parameters. Consider using a method instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:536)
+    static member tcPropertyRequiresExplicitTypeParameters() = (671, GetStringFunc("tcPropertyRequiresExplicitTypeParameters",",,,") )
+    /// A constructor cannot have explicit type parameters. Consider using a static construction method instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:537)
+    static member tcConstructorCannotHaveTypeParameters() = (672, GetStringFunc("tcConstructorCannotHaveTypeParameters",",,,") )
+    /// This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args) = ...'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:538)
+    static member tcInstanceMemberRequiresTarget() = (673, GetStringFunc("tcInstanceMemberRequiresTarget",",,,") )
+    /// Unexpected source-level property specification in syntax tree
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:539)
+    static member tcUnexpectedPropertyInSyntaxTree() = (674, GetStringFunc("tcUnexpectedPropertyInSyntaxTree",",,,") )
+    /// A static initializer requires an argument
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:540)
+    static member tcStaticInitializerRequiresArgument() = (675, GetStringFunc("tcStaticInitializerRequiresArgument",",,,") )
+    /// An object constructor requires an argument
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:541)
+    static member tcObjectConstructorRequiresArgument() = (676, GetStringFunc("tcObjectConstructorRequiresArgument",",,,") )
+    /// This static member should not have a 'this' parameter. Consider using the notation 'member Member(args) = ...'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:542)
+    static member tcStaticMemberShouldNotHaveThis() = (677, GetStringFunc("tcStaticMemberShouldNotHaveThis",",,,") )
+    /// An explicit static initializer should use the syntax 'static new(args) = expr'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:543)
+    static member tcExplicitStaticInitializerSyntax() = (678, GetStringFunc("tcExplicitStaticInitializerSyntax",",,,") )
+    /// An explicit object constructor should use the syntax 'new(args) = expr'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:544)
+    static member tcExplicitObjectConstructorSyntax() = (679, GetStringFunc("tcExplicitObjectConstructorSyntax",",,,") )
+    /// Unexpected source-level property specification
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:545)
+    static member tcUnexpectedPropertySpec() = (680, GetStringFunc("tcUnexpectedPropertySpec",",,,") )
+    /// This form of object expression is not used in F#. Use 'member this.MemberName ... = ...' to define member implementations in object expressions.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:546)
+    static member tcObjectExpressionFormDeprecated() = (GetStringFunc("tcObjectExpressionFormDeprecated",",,,") )
+    /// Invalid declaration
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:547)
+    static member tcInvalidDeclaration() = (682, GetStringFunc("tcInvalidDeclaration",",,,") )
+    /// Attributes are not allowed within patterns
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:548)
+    static member tcAttributesInvalidInPatterns() = (683, GetStringFunc("tcAttributesInvalidInPatterns",",,,") )
+    /// The generic function '%s' must be given explicit type argument(s)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:549)
+    static member tcFunctionRequiresExplicitTypeArguments(a0 : System.String) = (685, GetStringFunc("tcFunctionRequiresExplicitTypeArguments",",,,%s,,,") a0)
+    /// The method or function '%s' should not be given explicit type argument(s) because it does not declare its type parameters explicitly
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:550)
+    static member tcDoesNotAllowExplicitTypeArguments(a0 : System.String) = (686, GetStringFunc("tcDoesNotAllowExplicitTypeArguments",",,,%s,,,") a0)
+    /// This value, type or method expects %d type parameter(s) but was given %d
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:551)
+    static member tcTypeParameterArityMismatch(a0 : System.Int32, a1 : System.Int32) = (687, GetStringFunc("tcTypeParameterArityMismatch",",,,%d,,,%d,,,") a0 a1)
+    /// The default, zero-initializing constructor of a struct type may only be used if all the fields of the struct type admit default initialization
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:552)
+    static member tcDefaultStructConstructorCall() = (688, GetStringFunc("tcDefaultStructConstructorCall",",,,") )
+    /// Couldn't find Dispose on IDisposable, or it was overloaded
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:553)
+    static member tcCouldNotFindIDisposable() = (GetStringFunc("tcCouldNotFindIDisposable",",,,") )
+    /// This value is not a literal and cannot be used in a pattern
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:554)
+    static member tcNonLiteralCannotBeUsedInPattern() = (689, GetStringFunc("tcNonLiteralCannotBeUsedInPattern",",,,") )
+    /// This field is readonly
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:555)
+    static member tcFieldIsReadonly() = (690, GetStringFunc("tcFieldIsReadonly",",,,") )
+    /// Named arguments must appear after all other arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:556)
+    static member tcNameArgumentsMustAppearLast() = (691, GetStringFunc("tcNameArgumentsMustAppearLast",",,,") )
+    /// This function value is being used to construct a delegate type whose signature includes a byref argument. You must use an explicit lambda expression taking %d arguments.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:557)
+    static member tcFunctionRequiresExplicitLambda(a0 : System.Int32) = (692, GetStringFunc("tcFunctionRequiresExplicitLambda",",,,%d,,,") a0)
+    /// The type '%s' is not a type whose values can be enumerated with this syntax, i.e. is not compatible with either seq<_>, IEnumerable<_> or IEnumerable and does not have a GetEnumerator method
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:558)
+    static member tcTypeCannotBeEnumerated(a0 : System.String) = (693, GetStringFunc("tcTypeCannotBeEnumerated",",,,%s,,,") a0)
+    /// This expression has a method called GetEnumerator, but its return type is a value type. Methods returning struct enumerators cannot be used in this expression form.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:559)
+    static member tcBadReturnTypeForGetEnumerator() = (694, GetStringFunc("tcBadReturnTypeForGetEnumerator",",,,") )
+    /// This recursive binding uses an invalid mixture of recursive forms
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:560)
+    static member tcInvalidMixtureOfRecursiveForms() = (695, GetStringFunc("tcInvalidMixtureOfRecursiveForms",",,,") )
+    /// This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:561)
+    static member tcInvalidObjectConstructionExpression() = (696, GetStringFunc("tcInvalidObjectConstructionExpression",",,,") )
+    /// Invalid constraint
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:562)
+    static member tcInvalidConstraint() = (697, GetStringFunc("tcInvalidConstraint",",,,") )
+    /// Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:563)
+    static member tcInvalidConstraintTypeSealed() = (698, GetStringFunc("tcInvalidConstraintTypeSealed",",,,") )
+    /// An 'enum' constraint must be of the form 'enum<type>'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:564)
+    static member tcInvalidEnumConstraint() = (699, GetStringFunc("tcInvalidEnumConstraint",",,,") )
+    /// 'new' constraints must take one argument of type 'unit' and return the constructed type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:565)
+    static member tcInvalidNewConstraint() = (700, GetStringFunc("tcInvalidNewConstraint",",,,") )
+    /// This property has an invalid type. Properties taking multiple indexer arguments should have types of the form 'ty1 * ty2 -> ty3'. Properties returning functions should have types of the form '(ty1 -> ty2)'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:566)
+    static member tcInvalidPropertyType() = (701, GetStringFunc("tcInvalidPropertyType",",,,") )
+    /// Expected unit-of-measure parameter, not type parameter. Explicit unit-of-measure parameters must be marked with the [<Measure>] attribute.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:567)
+    static member tcExpectedUnitOfMeasureMarkWithAttribute() = (702, GetStringFunc("tcExpectedUnitOfMeasureMarkWithAttribute",",,,") )
+    /// Expected type parameter, not unit-of-measure parameter
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:568)
+    static member tcExpectedTypeParameter() = (703, GetStringFunc("tcExpectedTypeParameter",",,,") )
+    /// Expected type, not unit-of-measure
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:569)
+    static member tcExpectedTypeNotUnitOfMeasure() = (704, GetStringFunc("tcExpectedTypeNotUnitOfMeasure",",,,") )
+    /// Expected unit-of-measure, not type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:570)
+    static member tcExpectedUnitOfMeasureNotType() = (705, GetStringFunc("tcExpectedUnitOfMeasureNotType",",,,") )
+    /// Units-of-measure cannot be used as prefix arguments to a type. Rewrite as postfix arguments in angle brackets.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:571)
+    static member tcInvalidUnitsOfMeasurePrefix() = (706, GetStringFunc("tcInvalidUnitsOfMeasurePrefix",",,,") )
+    /// Unit-of-measure cannot be used in type constructor application
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:572)
+    static member tcUnitsOfMeasureInvalidInTypeConstructor() = (707, GetStringFunc("tcUnitsOfMeasureInvalidInTypeConstructor",",,,") )
+    /// This control construct may only be used if the computation expression builder defines a '%s' method
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:573)
+    static member tcRequireBuilderMethod(a0 : System.String) = (708, GetStringFunc("tcRequireBuilderMethod",",,,%s,,,") a0)
+    /// This type has no nested types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:574)
+    static member tcTypeHasNoNestedTypes() = (709, GetStringFunc("tcTypeHasNoNestedTypes",",,,") )
+    /// Unexpected %s in type expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:575)
+    static member tcUnexpectedSymbolInTypeExpression(a0 : System.String) = (711, GetStringFunc("tcUnexpectedSymbolInTypeExpression",",,,%s,,,") a0)
+    /// Type parameter cannot be used as type constructor
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:576)
+    static member tcTypeParameterInvalidAsTypeConstructor() = (712, GetStringFunc("tcTypeParameterInvalidAsTypeConstructor",",,,") )
+    /// Illegal syntax in type expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:577)
+    static member tcIllegalSyntaxInTypeExpression() = (713, GetStringFunc("tcIllegalSyntaxInTypeExpression",",,,") )
+    /// Anonymous unit-of-measure cannot be nested inside another unit-of-measure expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:578)
+    static member tcAnonymousUnitsOfMeasureCannotBeNested() = (714, GetStringFunc("tcAnonymousUnitsOfMeasureCannotBeNested",",,,") )
+    /// Anonymous type variables are not permitted in this declaration
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:579)
+    static member tcAnonymousTypeInvalidInDeclaration() = (715, GetStringFunc("tcAnonymousTypeInvalidInDeclaration",",,,") )
+    /// Unexpected / in type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:580)
+    static member tcUnexpectedSlashInType() = (716, GetStringFunc("tcUnexpectedSlashInType",",,,") )
+    /// Unexpected type arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:581)
+    static member tcUnexpectedTypeArguments() = (717, GetStringFunc("tcUnexpectedTypeArguments",",,,") )
+    /// Optional arguments are only permitted on type members
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:582)
+    static member tcOptionalArgsOnlyOnMembers() = (718, GetStringFunc("tcOptionalArgsOnlyOnMembers",",,,") )
+    /// Name '%s' not bound in pattern context
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:583)
+    static member tcNameNotBoundInPattern(a0 : System.String) = (719, GetStringFunc("tcNameNotBoundInPattern",",,,%s,,,") a0)
+    /// Non-primitive numeric literal constants cannot be used in pattern matches because they can be mapped to multiple different types through the use of a NumericLiteral module. Consider using replacing with a variable, and use 'when <variable> = <constant>' at the end of the match clause.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:584)
+    static member tcInvalidNonPrimitiveLiteralInPatternMatch() = (720, GetStringFunc("tcInvalidNonPrimitiveLiteralInPatternMatch",",,,") )
+    /// Type arguments cannot be specified here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:585)
+    static member tcInvalidTypeArgumentUsage() = (721, GetStringFunc("tcInvalidTypeArgumentUsage",",,,") )
+    /// Only active patterns returning exactly one result may accept arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:586)
+    static member tcRequireActivePatternWithOneResult() = (722, GetStringFunc("tcRequireActivePatternWithOneResult",",,,") )
+    /// Invalid argument to parameterized pattern label
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:587)
+    static member tcInvalidArgForParameterizedPattern() = (723, GetStringFunc("tcInvalidArgForParameterizedPattern",",,,") )
+    /// Internal error. Invalid index into active pattern array
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:588)
+    static member tcInvalidIndexIntoActivePatternArray() = (724, GetStringFunc("tcInvalidIndexIntoActivePatternArray",",,,") )
+    /// This union case does not take arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:589)
+    static member tcUnionCaseDoesNotTakeArguments() = (725, GetStringFunc("tcUnionCaseDoesNotTakeArguments",",,,") )
+    /// This union case takes one argument
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:590)
+    static member tcUnionCaseRequiresOneArgument() = (726, GetStringFunc("tcUnionCaseRequiresOneArgument",",,,") )
+    /// This union case expects %d arguments in tupled form
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:591)
+    static member tcUnionCaseExpectsTupledArguments(a0 : System.Int32) = (727, GetStringFunc("tcUnionCaseExpectsTupledArguments",",,,%d,,,") a0)
+    /// Field '%s' is not static
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:592)
+    static member tcFieldIsNotStatic(a0 : System.String) = (728, GetStringFunc("tcFieldIsNotStatic",",,,%s,,,") a0)
+    /// This field is not a literal and cannot be used in a pattern
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:593)
+    static member tcFieldNotLiteralCannotBeUsedInPattern() = (729, GetStringFunc("tcFieldNotLiteralCannotBeUsedInPattern",",,,") )
+    /// This is not a variable, constant, active recognizer or literal
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:594)
+    static member tcRequireVarConstRecogOrLiteral() = (730, GetStringFunc("tcRequireVarConstRecogOrLiteral",",,,") )
+    /// This is not a valid pattern
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:595)
+    static member tcInvalidPattern() = (731, GetStringFunc("tcInvalidPattern",",,,") )
+    /// Character range matches have been removed in F#. Consider using a 'when' pattern guard instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:596)
+    static member tcUseWhenPatternGuard() = (GetStringFunc("tcUseWhenPatternGuard",",,,") )
+    /// Illegal pattern
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:597)
+    static member tcIllegalPattern() = (733, GetStringFunc("tcIllegalPattern",",,,") )
+    /// Syntax error - unexpected '?' symbol
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:598)
+    static member tcSyntaxErrorUnexpectedQMark() = (734, GetStringFunc("tcSyntaxErrorUnexpectedQMark",",,,") )
+    /// Expected %d expressions, got %d
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:599)
+    static member tcExpressionCountMisMatch(a0 : System.Int32, a1 : System.Int32) = (735, GetStringFunc("tcExpressionCountMisMatch",",,,%d,,,%d,,,") a0 a1)
+    /// TcExprUndelayed: delayed
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:600)
+    static member tcExprUndelayed() = (736, GetStringFunc("tcExprUndelayed",",,,") )
+    /// This expression form may only be used in sequence and computation expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:601)
+    static member tcExpressionRequiresSequence() = (737, GetStringFunc("tcExpressionRequiresSequence",",,,") )
+    /// Invalid object expression. Objects without overrides or interfaces should use the expression form 'new Type(args)' without braces.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:602)
+    static member tcInvalidObjectExpressionSyntaxForm() = (738, GetStringFunc("tcInvalidObjectExpressionSyntaxForm",",,,") )
+    /// Invalid object, sequence or record expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:603)
+    static member tcInvalidObjectSequenceOrRecordExpression() = (739, GetStringFunc("tcInvalidObjectSequenceOrRecordExpression",",,,") )
+    /// Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq { ... }'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:604)
+    static member tcInvalidSequenceExpressionSyntaxForm() = (740, GetStringFunc("tcInvalidSequenceExpressionSyntaxForm",",,,") )
+    /// This list or array expression includes an element of the form 'if ... then ... else'. Parenthesize this expression to indicate it is an individual element of the list or array, to disambiguate this from a list generated using a sequence expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:605)
+    static member tcExpressionWithIfRequiresParenthesis() = (GetStringFunc("tcExpressionWithIfRequiresParenthesis",",,,") )
+    /// Unable to parse format string '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:606)
+    static member tcUnableToParseFormatString(a0 : System.String) = (741, GetStringFunc("tcUnableToParseFormatString",",,,%s,,,") a0)
+    /// This list expression exceeds the maximum size for list literals. Use an array for larger literals and call Array.ToList.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:607)
+    static member tcListLiteralMaxSize() = (742, GetStringFunc("tcListLiteralMaxSize",",,,") )
+    /// The expression form 'expr then expr' may only be used as part of an explicit object constructor
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:608)
+    static member tcExpressionFormRequiresObjectConstructor() = (743, GetStringFunc("tcExpressionFormRequiresObjectConstructor",",,,") )
+    /// Named arguments cannot be given to member trait calls
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:609)
+    static member tcNamedArgumentsCannotBeUsedInMemberTraits() = (744, GetStringFunc("tcNamedArgumentsCannotBeUsedInMemberTraits",",,,") )
+    /// Use 'typeof<_>' instead
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:610)
+    static member tcUseTypeOf() = (GetStringFunc("tcUseTypeOf",",,,") )
+    /// This is not a valid name for an enumeration case
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:611)
+    static member tcNotValidEnumCaseName() = (745, GetStringFunc("tcNotValidEnumCaseName",",,,") )
+    /// This field is not mutable
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:612)
+    static member tcFieldIsNotMutable() = (746, GetStringFunc("tcFieldIsNotMutable",",,,") )
+    /// This construct may only be used within list, array and sequence expressions, e.g. expressions of the form 'seq { ... }', '[ ... ]' or '[| ... |]'. These use the syntax 'for ... in ... do ... yield...' to generate elements
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:613)
+    static member tcConstructRequiresListArrayOrSequence() = (747, GetStringFunc("tcConstructRequiresListArrayOrSequence",",,,") )
+    /// This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:614)
+    static member tcConstructRequiresComputationExpressions() = (748, GetStringFunc("tcConstructRequiresComputationExpressions",",,,") )
+    /// This construct may only be used within sequence or computation expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:615)
+    static member tcConstructRequiresSequenceOrComputations() = (749, GetStringFunc("tcConstructRequiresSequenceOrComputations",",,,") )
+    /// This construct may only be used within computation expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:616)
+    static member tcConstructRequiresComputationExpression() = (750, GetStringFunc("tcConstructRequiresComputationExpression",",,,") )
+    /// Invalid indexer expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:617)
+    static member tcInvalidIndexerExpression() = (751, GetStringFunc("tcInvalidIndexerExpression",",,,") )
+    /// The operator 'expr.[idx]' has been used an object of indeterminate type based on information prior to this program point. Consider adding further type constraints
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:618)
+    static member tcObjectOfIndeterminateTypeUsedRequireTypeConstraint() = (752, GetStringFunc("tcObjectOfIndeterminateTypeUsedRequireTypeConstraint",",,,") )
+    /// Cannot inherit from a variable type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:619)
+    static member tcCannotInheritFromVariableType() = (753, GetStringFunc("tcCannotInheritFromVariableType",",,,") )
+    /// Calls to object constructors on type parameters cannot be given arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:620)
+    static member tcObjectConstructorsOnTypeParametersCannotTakeArguments() = (754, GetStringFunc("tcObjectConstructorsOnTypeParametersCannotTakeArguments",",,,") )
+    /// The 'CompiledName' attribute cannot be used with this language element
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:621)
+    static member tcCompiledNameAttributeMisused() = (755, GetStringFunc("tcCompiledNameAttributeMisused",",,,") )
+    /// '%s' may only be used with named types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:622)
+    static member tcNamedTypeRequired(a0 : System.String) = (756, GetStringFunc("tcNamedTypeRequired",",,,%s,,,") a0)
+    /// 'inherit' cannot be used on interface types. Consider implementing the interface by using 'interface ... with ... end' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:623)
+    static member tcInheritCannotBeUsedOnInterfaceType() = (757, GetStringFunc("tcInheritCannotBeUsedOnInterfaceType",",,,") )
+    /// 'new' cannot be used on interface types. Consider using an object expression '{ new ... with ... }' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:624)
+    static member tcNewCannotBeUsedOnInterfaceType() = (758, GetStringFunc("tcNewCannotBeUsedOnInterfaceType",",,,") )
+    /// Instances of this type cannot be created since it has been marked abstract or not all methods have been given implementations. Consider using an object expression '{ new ... with ... }' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:625)
+    static member tcAbstractTypeCannotBeInstantiated() = (759, GetStringFunc("tcAbstractTypeCannotBeInstantiated",",,,") )
+    /// It is recommended that objects that support the IDisposable interface are created using 'new Type(args)' rather than 'Type(args)' to indicate that resources may be owned by the generated value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:626)
+    static member tcIDisposableTypeShouldUseNew() = (760, GetStringFunc("tcIDisposableTypeShouldUseNew",",,,") )
+    /// '%s' may only be used to construct object types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:627)
+    static member tcSyntaxCanOnlyBeUsedToCreateObjectTypes(a0 : System.String) = (761, GetStringFunc("tcSyntaxCanOnlyBeUsedToCreateObjectTypes",",,,%s,,,") a0)
+    /// Constructors for the type '%s' must directly or indirectly call its implicit object constructor. Use a call to the implicit object constructor instead of a record expression.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:628)
+    static member tcConstructorRequiresCall(a0 : System.String) = (762, GetStringFunc("tcConstructorRequiresCall",",,,%s,,,") a0)
+    /// The field '%s' has been given a value, but is not present in the type '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:629)
+    static member tcUndefinedField(a0 : System.String, a1 : System.String) = (763, GetStringFunc("tcUndefinedField",",,,%s,,,%s,,,") a0 a1)
+    /// No assignment given for field '%s' of type '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:630)
+    static member tcFieldRequiresAssignment(a0 : System.String, a1 : System.String) = (764, GetStringFunc("tcFieldRequiresAssignment",",,,%s,,,%s,,,") a0 a1)
+    /// Extraneous fields have been given values
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:631)
+    static member tcExtraneousFieldsGivenValues() = (765, GetStringFunc("tcExtraneousFieldsGivenValues",",,,") )
+    /// Only overrides of abstract and virtual members may be specified in object expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:632)
+    static member tcObjectExpressionsCanOnlyOverrideAbstractOrVirtual() = (766, GetStringFunc("tcObjectExpressionsCanOnlyOverrideAbstractOrVirtual",",,,") )
+    /// The member '%s' does not correspond to any abstract or virtual method available to override or implement
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:633)
+    static member tcNoAbstractOrVirtualMemberFound(a0 : System.String) = (767, GetStringFunc("tcNoAbstractOrVirtualMemberFound",",,,%s,,,") a0)
+    /// The member '%s' does not accept the correct number of arguments, %d arguments are expected
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:634)
+    static member tcArgumentArityMismatch(a0 : System.String, a1 : System.Int32) = (768, GetStringFunc("tcArgumentArityMismatch",",,,%s,,,%d,,,") a0 a1)
+    /// The member '%s' does not accept the correct number of arguments. One overload accepts %d arguments.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:635)
+    static member tcArgumentArityMismatchOneOverload(a0 : System.String, a1 : System.Int32) = (769, GetStringFunc("tcArgumentArityMismatchOneOverload",",,,%s,,,%d,,,") a0 a1)
+    /// A simple method name is required here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:636)
+    static member tcSimpleMethodNameRequired() = (770, GetStringFunc("tcSimpleMethodNameRequired",",,,") )
+    /// The types System.ValueType, System.Enum, System.Delegate, System.MulticastDelegate and System.Array cannot be used as super types in an object expression or class
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:637)
+    static member tcPredefinedTypeCannotBeUsedAsSuperType() = (771, GetStringFunc("tcPredefinedTypeCannotBeUsedAsSuperType",",,,") )
+    /// 'new' must be used with a named type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:638)
+    static member tcNewMustBeUsedWithNamedType() = (772, GetStringFunc("tcNewMustBeUsedWithNamedType",",,,") )
+    /// Cannot create an extension of a sealed type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:639)
+    static member tcCannotCreateExtensionOfSealedType() = (773, GetStringFunc("tcCannotCreateExtensionOfSealedType",",,,") )
+    /// No arguments may be given when constructing a record value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:640)
+    static member tcNoArgumentsForRecordValue() = (774, GetStringFunc("tcNoArgumentsForRecordValue",",,,") )
+    /// Interface implementations cannot be given on construction expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:641)
+    static member tcNoInterfaceImplementationForConstructionExpression() = (775, GetStringFunc("tcNoInterfaceImplementationForConstructionExpression",",,,") )
+    /// Object construction expressions may only be used to implement constructors in class types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:642)
+    static member tcObjectConstructionCanOnlyBeUsedInClassTypes() = (776, GetStringFunc("tcObjectConstructionCanOnlyBeUsedInClassTypes",",,,") )
+    /// Only simple bindings of the form 'id = expr' can be used in construction expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:643)
+    static member tcOnlySimpleBindingsCanBeUsedInConstructionExpressions() = (777, GetStringFunc("tcOnlySimpleBindingsCanBeUsedInConstructionExpressions",",,,") )
+    /// Objects must be initialized by an object construction expression that calls an inherited object constructor and assigns a value to each field
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:644)
+    static member tcObjectsMustBeInitializedWithObjectExpression() = (778, GetStringFunc("tcObjectsMustBeInitializedWithObjectExpression",",,,") )
+    /// Expected an interface type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:645)
+    static member tcExpectedInterfaceType() = (779, GetStringFunc("tcExpectedInterfaceType",",,,") )
+    /// Constructor expressions for interfaces do not take arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:646)
+    static member tcConstructorForInterfacesDoNotTakeArguments() = (780, GetStringFunc("tcConstructorForInterfacesDoNotTakeArguments",",,,") )
+    /// This object constructor requires arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:647)
+    static member tcConstructorRequiresArguments() = (781, GetStringFunc("tcConstructorRequiresArguments",",,,") )
+    /// 'new' may only be used with object constructors
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:648)
+    static member tcNewRequiresObjectConstructor() = (782, GetStringFunc("tcNewRequiresObjectConstructor",",,,") )
+    /// At least one override did not correctly implement its corresponding abstract member
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:649)
+    static member tcAtLeastOneOverrideIsInvalid() = (783, GetStringFunc("tcAtLeastOneOverrideIsInvalid",",,,") )
+    /// This numeric literal requires that a module '%s' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:650)
+    static member tcNumericLiteralRequiresModule(a0 : System.String) = (784, GetStringFunc("tcNumericLiteralRequiresModule",",,,%s,,,") a0)
+    /// Invalid record construction
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:651)
+    static member tcInvalidRecordConstruction() = (785, GetStringFunc("tcInvalidRecordConstruction",",,,") )
+    /// The expression form { expr with ... } may only be used with record types. To build object types use { new Type(...) with ... }
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:652)
+    static member tcExpressionFormRequiresRecordTypes() = (786, GetStringFunc("tcExpressionFormRequiresRecordTypes",",,,") )
+    /// The inherited type is not an object model type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:653)
+    static member tcInheritedTypeIsNotObjectModelType() = (787, GetStringFunc("tcInheritedTypeIsNotObjectModelType",",,,") )
+    /// Object construction expressions (i.e. record expressions with inheritance specifications) may only be used to implement constructors in object model types. Use 'new ObjectType(args)' to construct instances of object model types outside of constructors
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:654)
+    static member tcObjectConstructionExpressionCanOnlyImplementConstructorsInObjectModelTypes() = (788, GetStringFunc("tcObjectConstructionExpressionCanOnlyImplementConstructorsInObjectModelTypes",",,,") )
+    /// '{ }' is not a valid expression. Records must include at least one field. Empty sequences are specified by using Seq.empty or an empty list '[]'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:655)
+    static member tcEmptyRecordInvalid() = (789, GetStringFunc("tcEmptyRecordInvalid",",,,") )
+    /// This type is not a record type. Values of class and struct types must be created using calls to object constructors.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:656)
+    static member tcTypeIsNotARecordTypeNeedConstructor() = (790, GetStringFunc("tcTypeIsNotARecordTypeNeedConstructor",",,,") )
+    /// This type is not a record type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:657)
+    static member tcTypeIsNotARecordType() = (791, GetStringFunc("tcTypeIsNotARecordType",",,,") )
+    /// This construct is ambiguous as part of a computation expression. Nested expressions may be written using 'let _ = (...)' and nested computations using 'let! res = builder { ... }'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:658)
+    static member tcConstructIsAmbiguousInComputationExpression() = (792, GetStringFunc("tcConstructIsAmbiguousInComputationExpression",",,,") )
+    /// This construct is ambiguous as part of a sequence expression. Nested expressions may be written using 'let _ = (...)' and nested sequences using 'yield! seq {... }'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:659)
+    static member tcConstructIsAmbiguousInSequenceExpression() = (793, GetStringFunc("tcConstructIsAmbiguousInSequenceExpression",",,,") )
+    /// 'do!' cannot be used within sequence expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:660)
+    static member tcDoBangIllegalInSequenceExpression() = (794, GetStringFunc("tcDoBangIllegalInSequenceExpression",",,,") )
+    /// The use of 'let! x = coll' in sequence expressions is no longer permitted. Use 'for x in coll' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:661)
+    static member tcUseForInSequenceExpression() = (795, GetStringFunc("tcUseForInSequenceExpression",",,,") )
+    /// 'try'/'with' cannot be used within sequence expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:662)
+    static member tcTryIllegalInSequenceExpression() = (796, GetStringFunc("tcTryIllegalInSequenceExpression",",,,") )
+    /// In sequence expressions, multiple results are generated using 'yield!'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:663)
+    static member tcUseYieldBangForMultipleResults() = (797, GetStringFunc("tcUseYieldBangForMultipleResults",",,,") )
+    /// Unexpected type application
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:664)
+    static member tcUnexpectedTypeApplication() = (798, GetStringFunc("tcUnexpectedTypeApplication",",,,") )
+    /// Invalid assignment
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:665)
+    static member tcInvalidAssignment() = (799, GetStringFunc("tcInvalidAssignment",",,,") )
+    /// Invalid use of a type name
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:666)
+    static member tcInvalidUseOfTypeName() = (800, GetStringFunc("tcInvalidUseOfTypeName",",,,") )
+    /// This type has no accessible object constructors
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:667)
+    static member tcTypeHasNoAccessibleConstructor() = (801, GetStringFunc("tcTypeHasNoAccessibleConstructor",",,,") )
+    /// Invalid use of a type name and/or object constructor. If necessary use 'new' and apply the constructor to its arguments, e.g. 'new Type(args)'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:668)
+    static member tcInvalidUseOfTypeNameOrConstructor() = (802, GetStringFunc("tcInvalidUseOfTypeNameOrConstructor",",,,") )
+    /// Invalid use of a type name and/or object constructor. If necessary use 'new' and apply the constructor to its arguments, e.g. 'new Type(args)'. Overloads are:\n\t%s.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:669)
+    static member tcInvalidUseOfTypeNameOrConstructorWithOverloads(a0 : System.String) = (803, GetStringFunc("tcInvalidUseOfTypeNameOrConstructorWithOverloads",",,,%s,,,") a0)
+    /// Invalid use of an interface type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:670)
+    static member tcInvalidUseOfInterfaceType() = (804, GetStringFunc("tcInvalidUseOfInterfaceType",",,,") )
+    /// Invalid use of a delegate constructor. Use the syntax 'new Type(args)' or just 'Type(args)'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:671)
+    static member tcInvalidUseOfDelegate() = (805, GetStringFunc("tcInvalidUseOfDelegate",",,,") )
+    /// Property '%s' is not static
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:672)
+    static member tcPropertyIsNotStatic(a0 : System.String) = (806, GetStringFunc("tcPropertyIsNotStatic",",,,%s,,,") a0)
+    /// Property '%s' is not readable
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:673)
+    static member tcPropertyIsNotReadable(a0 : System.String) = (807, GetStringFunc("tcPropertyIsNotReadable",",,,%s,,,") a0)
+    /// This lookup cannot be used here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:674)
+    static member tcLookupMayNotBeUsedHere() = (808, GetStringFunc("tcLookupMayNotBeUsedHere",",,,") )
+    /// Property '%s' is static
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:675)
+    static member tcPropertyIsStatic(a0 : System.String) = (809, GetStringFunc("tcPropertyIsStatic",",,,%s,,,") a0)
+    /// Property '%s' cannot be set
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:676)
+    static member tcPropertyCannotBeSet1(a0 : System.String) = (810, GetStringFunc("tcPropertyCannotBeSet1",",,,%s,,,") a0)
+    /// Constructors must be applied to arguments and cannot be used as first-class values. If necessary use an anonymous function '(fun arg1 ... argN -> new Type(arg1,...,argN))'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:677)
+    static member tcConstructorsCannotBeFirstClassValues() = (811, GetStringFunc("tcConstructorsCannotBeFirstClassValues",",,,") )
+    /// The syntax 'expr.id' may only be used with record labels, properties and fields
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:678)
+    static member tcSyntaxFormUsedOnlyWithRecordLabelsPropertiesAndFields() = (812, GetStringFunc("tcSyntaxFormUsedOnlyWithRecordLabelsPropertiesAndFields",",,,") )
+    /// Event '%s' is static
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:679)
+    static member tcEventIsStatic(a0 : System.String) = (813, GetStringFunc("tcEventIsStatic",",,,%s,,,") a0)
+    /// Event '%s' is not static
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:680)
+    static member tcEventIsNotStatic(a0 : System.String) = (814, GetStringFunc("tcEventIsNotStatic",",,,%s,,,") a0)
+    /// The named argument '%s' did not match any argument or mutable property
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:681)
+    static member tcNamedArgumentDidNotMatch(a0 : System.String) = (815, GetStringFunc("tcNamedArgumentDidNotMatch",",,,%s,,,") a0)
+    /// One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:682)
+    static member tcOverloadsCannotHaveCurriedArguments() = (816, GetStringFunc("tcOverloadsCannotHaveCurriedArguments",",,,") )
+    /// The unnamed arguments do not form a prefix of the arguments of the method called
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:683)
+    static member tcUnnamedArgumentsDoNotFormPrefix() = (GetStringFunc("tcUnnamedArgumentsDoNotFormPrefix",",,,") )
+    /// Static optimization conditionals are only for use within the F# library
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:684)
+    static member tcStaticOptimizationConditionalsOnlyForFSharpLibrary() = (817, GetStringFunc("tcStaticOptimizationConditionalsOnlyForFSharpLibrary",",,,") )
+    /// The corresponding formal argument is not optional
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:685)
+    static member tcFormalArgumentIsNotOptional() = (818, GetStringFunc("tcFormalArgumentIsNotOptional",",,,") )
+    /// Invalid optional assignment to a property or field
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:686)
+    static member tcInvalidOptionalAssignmentToPropertyOrField() = (819, GetStringFunc("tcInvalidOptionalAssignmentToPropertyOrField",",,,") )
+    /// A delegate constructor must be passed a single function value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:687)
+    static member tcDelegateConstructorMustBePassed() = (820, GetStringFunc("tcDelegateConstructorMustBePassed",",,,") )
+    /// A binding cannot be marked both 'use' and 'rec'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:688)
+    static member tcBindingCannotBeUseAndRec() = (821, GetStringFunc("tcBindingCannotBeUseAndRec",",,,") )
+    /// The 'VolatileField' attribute may only be used on 'let' bindings in classes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:689)
+    static member tcVolatileOnlyOnClassLetBindings() = (823, GetStringFunc("tcVolatileOnlyOnClassLetBindings",",,,") )
+    /// Attributes are not permitted on 'let' bindings in expressions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:690)
+    static member tcAttributesAreNotPermittedOnLetBindings() = (824, GetStringFunc("tcAttributesAreNotPermittedOnLetBindings",",,,") )
+    /// The 'DefaultValue' attribute may only be used on 'val' declarations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:691)
+    static member tcDefaultValueAttributeRequiresVal() = (825, GetStringFunc("tcDefaultValueAttributeRequiresVal",",,,") )
+    /// The 'ConditionalAttribute' attribute may only be used on members
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:692)
+    static member tcConditionalAttributeRequiresMembers() = (826, GetStringFunc("tcConditionalAttributeRequiresMembers",",,,") )
+    /// This is not a valid name for an active pattern
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:693)
+    static member tcInvalidActivePatternName() = (827, GetStringFunc("tcInvalidActivePatternName",",,,") )
+    /// The 'EntryPointAttribute' attribute may only be used on function definitions in modules
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:694)
+    static member tcEntryPointAttributeRequiresFunctionInModule() = (828, GetStringFunc("tcEntryPointAttributeRequiresFunctionInModule",",,,") )
+    /// Mutable values cannot be marked 'inline'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:695)
+    static member tcMutableValuesCannotBeInline() = (829, GetStringFunc("tcMutableValuesCannotBeInline",",,,") )
+    /// Mutable values cannot have generic parameters
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:696)
+    static member tcMutableValuesMayNotHaveGenericParameters() = (830, GetStringFunc("tcMutableValuesMayNotHaveGenericParameters",",,,") )
+    /// Mutable function values should be written 'let mutable f = (fun args -> ...)'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:697)
+    static member tcMutableValuesSyntax() = (831, GetStringFunc("tcMutableValuesSyntax",",,,") )
+    /// Only functions may be marked 'inline'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:698)
+    static member tcOnlyFunctionsCanBeInline() = (832, GetStringFunc("tcOnlyFunctionsCanBeInline",",,,") )
+    /// A literal value cannot be given the [<ThreadStatic>] or [<ContextStatic>] attributes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:699)
+    static member tcIllegalAttributesForLiteral() = (833, GetStringFunc("tcIllegalAttributesForLiteral",",,,") )
+    /// A literal value cannot be marked 'mutable'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:700)
+    static member tcLiteralCannotBeMutable() = (834, GetStringFunc("tcLiteralCannotBeMutable",",,,") )
+    /// A literal value cannot be marked 'inline'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:701)
+    static member tcLiteralCannotBeInline() = (835, GetStringFunc("tcLiteralCannotBeInline",",,,") )
+    /// Literal values cannot have generic parameters
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:702)
+    static member tcLiteralCannotHaveGenericParameters() = (836, GetStringFunc("tcLiteralCannotHaveGenericParameters",",,,") )
+    /// This is not a valid constant expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:703)
+    static member tcInvalidConstantExpression() = (837, GetStringFunc("tcInvalidConstantExpression",",,,") )
+    /// This type is not accessible from this code location
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:704)
+    static member tcTypeIsInaccessible() = (838, GetStringFunc("tcTypeIsInaccessible",",,,") )
+    /// Unexpected condition in imported assembly: failed to decode AttributeUsage attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:705)
+    static member tcUnexpectedConditionInImportedAssembly() = (839, GetStringFunc("tcUnexpectedConditionInImportedAssembly",",,,") )
+    /// Unrecognized attribute target. Valid attribute targets are 'assembly', 'module', 'type', 'method', 'property', 'return', 'param', 'field', 'event', 'constructor'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:706)
+    static member tcUnrecognizedAttributeTarget() = (840, GetStringFunc("tcUnrecognizedAttributeTarget",",,,") )
+    /// This attribute is not valid for use on this language element. Assembly attributes should be attached to a 'do ()' declaration, if necessary within an F# module.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:707)
+    static member tcAttributeIsNotValidForLanguageElementUseDo() = (841, GetStringFunc("tcAttributeIsNotValidForLanguageElementUseDo",",,,") )
+    /// This attribute is not valid for use on this language element
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:708)
+    static member tcAttributeIsNotValidForLanguageElement() = (842, GetStringFunc("tcAttributeIsNotValidForLanguageElement",",,,") )
+    /// Optional arguments cannot be used in custom attributes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:709)
+    static member tcOptionalArgumentsCannotBeUsedInCustomAttribute() = (843, GetStringFunc("tcOptionalArgumentsCannotBeUsedInCustomAttribute",",,,") )
+    /// This property cannot be set
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:710)
+    static member tcPropertyCannotBeSet0() = (844, GetStringFunc("tcPropertyCannotBeSet0",",,,") )
+    /// This property or field was not found on this custom attribute type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:711)
+    static member tcPropertyOrFieldNotFoundInAttribute() = (845, GetStringFunc("tcPropertyOrFieldNotFoundInAttribute",",,,") )
+    /// A custom attribute must be a reference type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:712)
+    static member tcCustomAttributeMustBeReferenceType() = (846, GetStringFunc("tcCustomAttributeMustBeReferenceType",",,,") )
+    /// The number of args for a custom attribute does not match the expected number of args for the attribute constructor
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:713)
+    static member tcCustomAttributeArgumentMismatch() = (847, GetStringFunc("tcCustomAttributeArgumentMismatch",",,,") )
+    /// A custom attribute must invoke an object constructor
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:714)
+    static member tcCustomAttributeMustInvokeConstructor() = (848, GetStringFunc("tcCustomAttributeMustInvokeConstructor",",,,") )
+    /// Attribute expressions must be calls to object constructors
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:715)
+    static member tcAttributeExpressionsMustBeConstructorCalls() = (849, GetStringFunc("tcAttributeExpressionsMustBeConstructorCalls",",,,") )
+    /// This attribute cannot be used in this version of F#
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:716)
+    static member tcUnsupportedAttribute() = (850, GetStringFunc("tcUnsupportedAttribute",",,,") )
+    /// Invalid inline specification
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:717)
+    static member tcInvalidInlineSpecification() = (851, GetStringFunc("tcInvalidInlineSpecification",",,,") )
+    /// 'use' bindings must be of the form 'use <var> = <expr>'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:718)
+    static member tcInvalidUseBinding() = (852, GetStringFunc("tcInvalidUseBinding",",,,") )
+    /// Abstract members are not permitted in an augmentation - they must be defined as part of the type itself
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:719)
+    static member tcAbstractMembersIllegalInAugmentation() = (853, GetStringFunc("tcAbstractMembersIllegalInAugmentation",",,,") )
+    /// Method overrides and interface implementations are not permitted here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:720)
+    static member tcMethodOverridesIllegalHere() = (854, GetStringFunc("tcMethodOverridesIllegalHere",",,,") )
+    /// No abstract or interface member was found that corresponds to this override
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:721)
+    static member tcNoMemberFoundForOverride() = (855, GetStringFunc("tcNoMemberFoundForOverride",",,,") )
+    /// This override takes a different number of arguments to the corresponding abstract member
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:722)
+    static member tcOverrideArityMismatch() = (856, GetStringFunc("tcOverrideArityMismatch",",,,") )
+    /// This method already has a default implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:723)
+    static member tcDefaultImplementationAlreadyExists() = (857, GetStringFunc("tcDefaultImplementationAlreadyExists",",,,") )
+    /// The method implemented by this default is ambiguous
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:724)
+    static member tcDefaultAmbiguous() = (858, GetStringFunc("tcDefaultAmbiguous",",,,") )
+    /// No abstract property was found that corresponds to this override
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:725)
+    static member tcNoPropertyFoundForOverride() = (859, GetStringFunc("tcNoPropertyFoundForOverride",",,,") )
+    /// This property overrides or implements an abstract property but the abstract property doesn't have a corresponding %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:726)
+    static member tcAbstractPropertyMissingGetOrSet(a0 : System.String) = (860, GetStringFunc("tcAbstractPropertyMissingGetOrSet",",,,%s,,,") a0)
+    /// Invalid signature for set member
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:727)
+    static member tcInvalidSignatureForSet() = (861, GetStringFunc("tcInvalidSignatureForSet",",,,") )
+    /// This property already has a default implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:728)
+    static member tcPropertyAlreadyHasDefaultImplementation() = (862, GetStringFunc("tcPropertyAlreadyHasDefaultImplementation",",,,") )
+    /// The property implemented by this default is ambiguous
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:729)
+    static member tcPropertyImplementedIsAmbiguous() = (863, GetStringFunc("tcPropertyImplementedIsAmbiguous",",,,") )
+    /// This new member hides the abstract member '%s'. Rename the member or use 'override' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:730)
+    static member tcNewMemberHidesAbstractMember(a0 : System.String) = (864, GetStringFunc("tcNewMemberHidesAbstractMember",",,,%s,,,") a0)
+    /// This new member hides the abstract member '%s' once tuples, functions and/or units of measure are erased. Rename the member or use 'override' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:731)
+    static member tcNewMemberHidesAbstractMemberWithSuffix(a0 : System.String) = (864, GetStringFunc("tcNewMemberHidesAbstractMemberWithSuffix",",,,%s,,,") a0)
+    /// Interfaces cannot contain definitions of static initializers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:732)
+    static member tcStaticInitializersIllegalInInterface() = (865, GetStringFunc("tcStaticInitializersIllegalInInterface",",,,") )
+    /// Interfaces cannot contain definitions of object constructors
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:733)
+    static member tcObjectConstructorsIllegalInInterface() = (866, GetStringFunc("tcObjectConstructorsIllegalInInterface",",,,") )
+    /// Interfaces cannot contain definitions of member overrides
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:734)
+    static member tcMemberOverridesIllegalInInterface() = (867, GetStringFunc("tcMemberOverridesIllegalInInterface",",,,") )
+    /// Interfaces cannot contain definitions of concrete members. You may need to define a constructor on your type, or use implicit class construction, to indicate that the type is a concrete implementation class.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:735)
+    static member tcConcreteMembersIllegalInInterface() = (868, GetStringFunc("tcConcreteMembersIllegalInInterface",",,,") )
+    /// Constructors cannot be specified in exception augmentations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:736)
+    static member tcConstructorsDisallowedInExceptionAugmentation() = (869, GetStringFunc("tcConstructorsDisallowedInExceptionAugmentation",",,,") )
+    /// Structs cannot have an object constructor with no arguments. This is a restriction imposed on all CLI languages as structs automatically support a default constructor.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:737)
+    static member tcStructsCannotHaveConstructorWithNoArguments() = (870, GetStringFunc("tcStructsCannotHaveConstructorWithNoArguments",",,,") )
+    /// Constructors cannot be defined for this type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:738)
+    static member tcConstructorsIllegalForThisType() = (871, GetStringFunc("tcConstructorsIllegalForThisType",",,,") )
+    /// Recursive bindings that include member specifications can only occur as a direct augmentation of a type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:739)
+    static member tcRecursiveBindingsWithMembersMustBeDirectAugmentation() = (872, GetStringFunc("tcRecursiveBindingsWithMembersMustBeDirectAugmentation",",,,") )
+    /// Only simple variable patterns can be bound in 'let rec' constructs
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:740)
+    static member tcOnlySimplePatternsInLetRec() = (873, GetStringFunc("tcOnlySimplePatternsInLetRec",",,,") )
+    /// Only record fields and simple 'let' bindings may be marked mutable
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:741)
+    static member tcOnlyRecordFieldsAndSimpleLetCanBeMutable() = (874, GetStringFunc("tcOnlyRecordFieldsAndSimpleLetCanBeMutable",",,,") )
+    /// This member is not sufficiently generic
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:742)
+    static member tcMemberIsNotSufficientlyGeneric() = (875, GetStringFunc("tcMemberIsNotSufficientlyGeneric",",,,") )
+    /// A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:743)
+    static member tcLiteralAttributeRequiresConstantValue() = (876, GetStringFunc("tcLiteralAttributeRequiresConstantValue",",,,") )
+    /// A declaration may only be given a value in a signature if the declaration has the [<Literal>] attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:744)
+    static member tcValueInSignatureRequiresLiteralAttribute() = (877, GetStringFunc("tcValueInSignatureRequiresLiteralAttribute",",,,") )
+    /// Thread-static and context-static variables must be static and given the [<DefaultValue>] attribute to indicate that the value is initialized to the default value on each new thread
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:745)
+    static member tcThreadStaticAndContextStaticMustBeStatic() = (878, GetStringFunc("tcThreadStaticAndContextStaticMustBeStatic",",,,") )
+    /// Volatile fields must be marked 'mutable' and cannot be thread-static
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:746)
+    static member tcVolatileFieldsMustBeMutable() = (879, GetStringFunc("tcVolatileFieldsMustBeMutable",",,,") )
+    /// Uninitialized 'val' fields in implicit construction types must be mutable and marked with the '[<DefaultValue>]' attribute. Consider using a 'let' binding instead of a 'val' field.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:747)
+    static member tcUninitializedValFieldsMustBeMutable() = (880, GetStringFunc("tcUninitializedValFieldsMustBeMutable",",,,") )
+    /// Static 'val' fields in types must be mutable, private and marked with the '[<DefaultValue>]' attribute. They are initialized to the 'null' or 'zero' value for their type. Consider also using a 'static let mutable' binding in a class type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:748)
+    static member tcStaticValFieldsMustBeMutableAndPrivate() = (881, GetStringFunc("tcStaticValFieldsMustBeMutableAndPrivate",",,,") )
+    /// This field requires a name
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:749)
+    static member tcFieldRequiresName() = (882, GetStringFunc("tcFieldRequiresName",",,,") )
+    /// Invalid namespace, module, type or union case name
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:750)
+    static member tcInvalidNamespaceModuleTypeUnionName() = (883, GetStringFunc("tcInvalidNamespaceModuleTypeUnionName",",,,") )
+    /// Explicit type declarations for constructors must be of the form 'ty1 * ... * tyN -> resTy'. Parentheses may be required around 'resTy'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:751)
+    static member tcIllegalFormForExplicitTypeDeclaration() = (884, GetStringFunc("tcIllegalFormForExplicitTypeDeclaration",",,,") )
+    /// Return types of union cases must be identical to the type being defined, up to abbreviations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:752)
+    static member tcReturnTypesForUnionMustBeSameAsType() = (885, GetStringFunc("tcReturnTypesForUnionMustBeSameAsType",",,,") )
+    /// This is not a valid value for an enumeration literal
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:753)
+    static member tcInvalidEnumerationLiteral() = (886, GetStringFunc("tcInvalidEnumerationLiteral",",,,") )
+    /// The type '%s' is not an interface type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:754)
+    static member tcTypeIsNotInterfaceType1(a0 : System.String) = (887, GetStringFunc("tcTypeIsNotInterfaceType1",",,,%s,,,") a0)
+    /// Duplicate specification of an interface
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:755)
+    static member tcDuplicateSpecOfInterface() = (888, GetStringFunc("tcDuplicateSpecOfInterface",",,,") )
+    /// A field/val declaration is not permitted here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:756)
+    static member tcFieldValIllegalHere() = (889, GetStringFunc("tcFieldValIllegalHere",",,,") )
+    /// A inheritance declaration is not permitted here
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:757)
+    static member tcInheritIllegalHere() = (890, GetStringFunc("tcInheritIllegalHere",",,,") )
+    /// This declaration opens the module '%s', which is marked as 'RequireQualifiedAccess'. Adjust your code to use qualified references to the elements of the module instead, e.g. 'List.map' instead of 'map'. This change will ensure that your code is robust as new constructs are added to libraries.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:758)
+    static member tcModuleRequiresQualifiedAccess(a0 : System.String) = (892, GetStringFunc("tcModuleRequiresQualifiedAccess",",,,%s,,,") a0)
+    /// This declaration opens the namespace or module '%s' through a partially qualified path. Adjust this code to use the full path of the namespace. This change will make your code more robust as new constructs are added to the F# and CLI libraries.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:759)
+    static member tcOpenUsedWithPartiallyQualifiedPath(a0 : System.String) = (893, GetStringFunc("tcOpenUsedWithPartiallyQualifiedPath",",,,%s,,,") a0)
+    /// Local class bindings cannot be marked inline. Consider lifting the definition out of the class or else do not mark it as inline.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:760)
+    static member tcLocalClassBindingsCannotBeInline() = (894, GetStringFunc("tcLocalClassBindingsCannotBeInline",",,,") )
+    /// Type abbreviations cannot have members
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:761)
+    static member tcTypeAbbreviationsMayNotHaveMembers() = (895, GetStringFunc("tcTypeAbbreviationsMayNotHaveMembers",",,,") )
+    /// Enumerations cannot have members
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:762)
+    static member tcEnumerationsMayNotHaveMembers() = (896, GetStringFunc("tcEnumerationsMayNotHaveMembers",",,,") )
+    /// Measure declarations may have only static members
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:763)
+    static member tcMeasureDeclarationsRequireStaticMembers() = (897, GetStringFunc("tcMeasureDeclarationsRequireStaticMembers",",,,") )
+    /// Structs cannot contain 'do' bindings because the default constructor for structs would not execute these bindings
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:764)
+    static member tcStructsMayNotContainDoBindings() = (GetStringFunc("tcStructsMayNotContainDoBindings",",,,") )
+    /// Structs cannot contain 'let' bindings because the default constructor for structs will not execute these bindings. Consider adding additional arguments to the primary constructor for the type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:765)
+    static member tcStructsMayNotContainLetBindings() = (901, GetStringFunc("tcStructsMayNotContainLetBindings",",,,") )
+    /// Static 'let' bindings may only be defined in class types with implicit constructors
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:766)
+    static member tcStaticLetBindingsRequireClassesWithImplicitConstructors() = (902, GetStringFunc("tcStaticLetBindingsRequireClassesWithImplicitConstructors",",,,") )
+    /// Measure declarations may have only static members: constructors are not available
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:767)
+    static member tcMeasureDeclarationsRequireStaticMembersNotConstructors() = (904, GetStringFunc("tcMeasureDeclarationsRequireStaticMembersNotConstructors",",,,") )
+    /// A member and a local class binding both have the name '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:768)
+    static member tcMemberAndLocalClassBindingHaveSameName(a0 : System.String) = (905, GetStringFunc("tcMemberAndLocalClassBindingHaveSameName",",,,%s,,,") a0)
+    /// Type abbreviations cannot have interface declarations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:769)
+    static member tcTypeAbbreviationsCannotHaveInterfaceDeclaration() = (906, GetStringFunc("tcTypeAbbreviationsCannotHaveInterfaceDeclaration",",,,") )
+    /// Enumerations cannot have interface declarations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:770)
+    static member tcEnumerationsCannotHaveInterfaceDeclaration() = (907, GetStringFunc("tcEnumerationsCannotHaveInterfaceDeclaration",",,,") )
+    /// This type is not an interface type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:771)
+    static member tcTypeIsNotInterfaceType0() = (908, GetStringFunc("tcTypeIsNotInterfaceType0",",,,") )
+    /// All implemented interfaces should be declared on the initial declaration of the type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:772)
+    static member tcAllImplementedInterfacesShouldBeDeclared() = (909, GetStringFunc("tcAllImplementedInterfacesShouldBeDeclared",",,,") )
+    /// A default implementation of this interface has already been added because the explicit implementation of the interface was not specified at the definition of the type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:773)
+    static member tcDefaultImplementationForInterfaceHasAlreadyBeenAdded() = (910, GetStringFunc("tcDefaultImplementationForInterfaceHasAlreadyBeenAdded",",,,") )
+    /// This member is not permitted in an interface implementation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:774)
+    static member tcMemberNotPermittedInInterfaceImplementation() = (911, GetStringFunc("tcMemberNotPermittedInInterfaceImplementation",",,,") )
+    /// This declaration element is not permitted in an augmentation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:775)
+    static member tcDeclarationElementNotPermittedInAugmentation() = (912, GetStringFunc("tcDeclarationElementNotPermittedInAugmentation",",,,") )
+    /// Types cannot contain nested type definitions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:776)
+    static member tcTypesCannotContainNestedTypes() = (913, GetStringFunc("tcTypesCannotContainNestedTypes",",,,") )
+    /// type, exception or module
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:777)
+    static member tcTypeExceptionOrModule() = (GetStringFunc("tcTypeExceptionOrModule",",,,") )
+    /// type or module
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:778)
+    static member tcTypeOrModule() = (GetStringFunc("tcTypeOrModule",",,,") )
+    /// The struct, record or union type '%s' implements the interface 'System.IStructuralEquatable' explicitly. Apply the 'CustomEquality' attribute to the type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:779)
+    static member tcImplementsIStructuralEquatableExplicitly(a0 : System.String) = (914, GetStringFunc("tcImplementsIStructuralEquatableExplicitly",",,,%s,,,") a0)
+    /// The struct, record or union type '%s' implements the interface 'System.IEquatable<_>' explicitly. Apply the 'CustomEquality' attribute to the type and provide a consistent implementation of the non-generic override 'System.Object.Equals(obj)'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:780)
+    static member tcImplementsIEquatableExplicitly(a0 : System.String) = (915, GetStringFunc("tcImplementsIEquatableExplicitly",",,,%s,,,") a0)
+    /// Explicit type specifications cannot be used for exception constructors
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:781)
+    static member tcExplicitTypeSpecificationCannotBeUsedForExceptionConstructors() = (916, GetStringFunc("tcExplicitTypeSpecificationCannotBeUsedForExceptionConstructors",",,,") )
+    /// Exception abbreviations should not have argument lists
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:782)
+    static member tcExceptionAbbreviationsShouldNotHaveArgumentList() = (917, GetStringFunc("tcExceptionAbbreviationsShouldNotHaveArgumentList",",,,") )
+    /// Abbreviations for Common IL exceptions cannot take arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:783)
+    static member tcAbbreviationsFordotNetExceptionsCannotTakeArguments() = (918, GetStringFunc("tcAbbreviationsFordotNetExceptionsCannotTakeArguments",",,,") )
+    /// Exception abbreviations must refer to existing exceptions or F# types deriving from System.Exception
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:784)
+    static member tcExceptionAbbreviationsMustReferToValidExceptions() = (919, GetStringFunc("tcExceptionAbbreviationsMustReferToValidExceptions",",,,") )
+    /// Abbreviations for Common IL exception types must have a matching object constructor
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:785)
+    static member tcAbbreviationsFordotNetExceptionsMustHaveMatchingObjectConstructor() = (920, GetStringFunc("tcAbbreviationsFordotNetExceptionsMustHaveMatchingObjectConstructor",",,,") )
+    /// Not an exception
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:786)
+    static member tcNotAnException() = (921, GetStringFunc("tcNotAnException",",,,") )
+    /// Unexpected constraints or parameters on module specification
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:787)
+    static member tcUnexpectedConstraintsOrParametersOnModule() = (922, GetStringFunc("tcUnexpectedConstraintsOrParametersOnModule",",,,") )
+    /// Unexpected constraint or type definition
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:788)
+    static member tcUnexpectedConstraintOrTypeDef() = (923, GetStringFunc("tcUnexpectedConstraintOrTypeDef",",,,") )
+    /// Invalid module name
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:789)
+    static member tcInvalidModuleName() = (924, GetStringFunc("tcInvalidModuleName",",,,") )
+    /// Invalid type extension
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:790)
+    static member tcInvalidTypeExtension() = (925, GetStringFunc("tcInvalidTypeExtension",",,,") )
+    /// The attributes of this type specify multiple kinds for the type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:791)
+    static member tcAttributesOfTypeSpecifyMultipleKindsForType() = (926, GetStringFunc("tcAttributesOfTypeSpecifyMultipleKindsForType",",,,") )
+    /// The kind of the type specified by its attributes does not match the kind implied by its definition
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:792)
+    static member tcKindOfTypeSpecifiedDoesNotMatchDefinition() = (927, GetStringFunc("tcKindOfTypeSpecifiedDoesNotMatchDefinition",",,,") )
+    /// Measure definitions cannot have type parameters
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:793)
+    static member tcMeasureDefinitionsCannotHaveTypeParameters() = (928, GetStringFunc("tcMeasureDefinitionsCannotHaveTypeParameters",",,,") )
+    /// This type requires a definition
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:794)
+    static member tcTypeRequiresDefinition() = (929, GetStringFunc("tcTypeRequiresDefinition",",,,") )
+    /// This type abbreviation has one or more declared type parameters that do not appear in the type being abbreviated. Type abbreviations must use all declared type parameters in the type being abbreviated. Consider removing one or more type parameters, or use a concrete type definition that wraps an underlying type, such as 'type C<'a> = C of ...'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:795)
+    static member tcTypeAbbreviationHasTypeParametersMissingOnType() = (GetStringFunc("tcTypeAbbreviationHasTypeParametersMissingOnType",",,,") )
+    /// Structs, interfaces, enums and delegates cannot inherit from other types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:796)
+    static member tcStructsInterfacesEnumsDelegatesMayNotInheritFromOtherTypes() = (931, GetStringFunc("tcStructsInterfacesEnumsDelegatesMayNotInheritFromOtherTypes",",,,") )
+    /// Types cannot inherit from multiple concrete types
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:797)
+    static member tcTypesCannotInheritFromMultipleConcreteTypes() = (932, GetStringFunc("tcTypesCannotInheritFromMultipleConcreteTypes",",,,") )
+    /// Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:798)
+    static member tcRecordsUnionsAbbreviationsStructsMayNotHaveAllowNullLiteralAttribute() = (934, GetStringFunc("tcRecordsUnionsAbbreviationsStructsMayNotHaveAllowNullLiteralAttribute",",,,") )
+    /// Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:799)
+    static member tcAllowNullTypesMayOnlyInheritFromAllowNullTypes() = (935, GetStringFunc("tcAllowNullTypesMayOnlyInheritFromAllowNullTypes",",,,") )
+    /// Generic types cannot be given the 'StructLayout' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:800)
+    static member tcGenericTypesCannotHaveStructLayout() = (936, GetStringFunc("tcGenericTypesCannotHaveStructLayout",",,,") )
+    /// Only structs and classes without implicit constructors may be given the 'StructLayout' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:801)
+    static member tcOnlyStructsCanHaveStructLayout() = (937, GetStringFunc("tcOnlyStructsCanHaveStructLayout",",,,") )
+    /// The representation of this type is hidden by the signature. It must be given an attribute such as [<Sealed>], [<Class>] or [<Interface>] to indicate the characteristics of the type.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:802)
+    static member tcRepresentationOfTypeHiddenBySignature() = (938, GetStringFunc("tcRepresentationOfTypeHiddenBySignature",",,,") )
+    /// Only classes may be given the 'AbstractClass' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:803)
+    static member tcOnlyClassesCanHaveAbstract() = (939, GetStringFunc("tcOnlyClassesCanHaveAbstract",",,,") )
+    /// Only types representing units-of-measure may be given the 'Measure' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:804)
+    static member tcOnlyTypesRepresentingUnitsOfMeasureCanHaveMeasure() = (940, GetStringFunc("tcOnlyTypesRepresentingUnitsOfMeasureCanHaveMeasure",",,,") )
+    /// Accessibility modifiers are not permitted on overrides or interface implementations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:805)
+    static member tcOverridesCannotHaveVisibilityDeclarations() = (941, GetStringFunc("tcOverridesCannotHaveVisibilityDeclarations",",,,") )
+    /// Discriminated union types are always sealed
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:806)
+    static member tcTypesAreAlwaysSealedDU() = (942, GetStringFunc("tcTypesAreAlwaysSealedDU",",,,") )
+    /// Record types are always sealed
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:807)
+    static member tcTypesAreAlwaysSealedRecord() = (942, GetStringFunc("tcTypesAreAlwaysSealedRecord",",,,") )
+    /// Assembly code types are always sealed
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:808)
+    static member tcTypesAreAlwaysSealedAssemblyCode() = (942, GetStringFunc("tcTypesAreAlwaysSealedAssemblyCode",",,,") )
+    /// Struct types are always sealed
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:809)
+    static member tcTypesAreAlwaysSealedStruct() = (942, GetStringFunc("tcTypesAreAlwaysSealedStruct",",,,") )
+    /// Delegate types are always sealed
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:810)
+    static member tcTypesAreAlwaysSealedDelegate() = (942, GetStringFunc("tcTypesAreAlwaysSealedDelegate",",,,") )
+    /// Enum types are always sealed
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:811)
+    static member tcTypesAreAlwaysSealedEnum() = (942, GetStringFunc("tcTypesAreAlwaysSealedEnum",",,,") )
+    /// Interface types and delegate types cannot contain fields
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:812)
+    static member tcInterfaceTypesAndDelegatesCannotContainFields() = (943, GetStringFunc("tcInterfaceTypesAndDelegatesCannotContainFields",",,,") )
+    /// Abbreviated types cannot be given the 'Sealed' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:813)
+    static member tcAbbreviatedTypesCannotBeSealed() = (944, GetStringFunc("tcAbbreviatedTypesCannotBeSealed",",,,") )
+    /// Cannot inherit a sealed type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:814)
+    static member tcCannotInheritFromSealedType() = (945, GetStringFunc("tcCannotInheritFromSealedType",",,,") )
+    /// Cannot inherit from interface type. Use interface ... with instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:815)
+    static member tcCannotInheritFromInterfaceType() = (946, GetStringFunc("tcCannotInheritFromInterfaceType",",,,") )
+    /// Struct types cannot contain abstract members
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:816)
+    static member tcStructTypesCannotContainAbstractMembers() = (947, GetStringFunc("tcStructTypesCannotContainAbstractMembers",",,,") )
+    /// Interface types cannot be sealed
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:817)
+    static member tcInterfaceTypesCannotBeSealed() = (948, GetStringFunc("tcInterfaceTypesCannotBeSealed",",,,") )
+    /// Delegate specifications must be of the form 'typ -> typ'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:818)
+    static member tcInvalidDelegateSpecification() = (949, GetStringFunc("tcInvalidDelegateSpecification",",,,") )
+    /// Delegate specifications must not be curried types. Use 'typ * ... * typ -> typ' for multi-argument delegates, and 'typ -> (typ -> typ)' for delegates returning function values.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:819)
+    static member tcDelegatesCannotBeCurried() = (950, GetStringFunc("tcDelegatesCannotBeCurried",",,,") )
+    /// Literal enumerations must have type int, uint, int16, uint16, int64, uint64, byte, sbyte or char
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:820)
+    static member tcInvalidTypeForLiteralEnumeration() = (951, GetStringFunc("tcInvalidTypeForLiteralEnumeration",",,,") )
+    /// This type definition involves an immediate cyclic reference through an abbreviation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:822)
+    static member tcTypeDefinitionIsCyclic() = (953, GetStringFunc("tcTypeDefinitionIsCyclic",",,,") )
+    /// This type definition involves an immediate cyclic reference through a struct field or inheritance relation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:823)
+    static member tcTypeDefinitionIsCyclicThroughInheritance() = (954, GetStringFunc("tcTypeDefinitionIsCyclicThroughInheritance",",,,") )
+    /// The syntax 'type X with ...' is reserved for augmentations. Types whose representations are hidden but which have members are now declared in signatures using 'type X = ...'. You may also need to add the '[<Sealed>] attribute to the type declaration in the signature
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:824)
+    static member tcReservedSyntaxForAugmentation() = (GetStringFunc("tcReservedSyntaxForAugmentation",",,,") )
+    /// Members that extend interface, delegate or enum types must be placed in a module separate to the definition of the type. This module must either have the AutoOpen attribute or be opened explicitly by client code to bring the extension members into scope.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:825)
+    static member tcMembersThatExtendInterfaceMustBePlacedInSeparateModule() = (956, GetStringFunc("tcMembersThatExtendInterfaceMustBePlacedInSeparateModule",",,,") )
+    /// The declared type parameters for this type extension do not match the declared type parameters on the original type '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:826)
+    static member tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(a0 : System.String) = (957, GetStringFunc("tcDeclaredTypeParametersForExtensionDoNotMatchOriginal",",,,%s,,,") a0)
+    /// Type definitions using implicit construction may only have one 'inherit' specification and it must be the first declaration
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:827)
+    static member tcTypeDefinitionsWithImplicitConstructionMustHaveOneInherit() = (959, GetStringFunc("tcTypeDefinitionsWithImplicitConstructionMustHaveOneInherit",",,,") )
+    /// Type definitions using implicit construction must have local let/do-bindings preceding member and interface definitions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:828)
+    static member tcTypeDefinitionsWithImplicitConstructionMustHaveLocalBindingsBeforeMembers() = (960, GetStringFunc("tcTypeDefinitionsWithImplicitConstructionMustHaveLocalBindingsBeforeMembers",",,,") )
+    /// This 'inherit' declaration specifies the inherited type but no arguments. Consider supplying arguments, e.g. 'inherit BaseType(args)'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:829)
+    static member tcInheritDeclarationMissingArguments() = (961, GetStringFunc("tcInheritDeclarationMissingArguments",",,,") )
+    /// This 'inherit' construction call is not part of an implicit construction sequence. Only the inherited type should be specified at this point. Calls to the inherited constructor should be placed inside the object initialization expression of your object constructor. Alternatively use an implicit construction sequence by modifying the type declaration to include arguments, e.g. 'type X(args) = ...'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:830)
+    static member tcInheritConstructionCallNotPartOfImplicitSequence() = (962, GetStringFunc("tcInheritConstructionCallNotPartOfImplicitSequence",",,,") )
+    /// 'let' and 'do' bindings are not permitted in class definitions unless an implicit construction sequence is used. You can use an implicit construction sequence by modifying the type declaration to include arguments, e.g. 'type X(args) = ...'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:831)
+    static member tcLetAndDoRequiresImplicitConstructionSequence() = (963, GetStringFunc("tcLetAndDoRequiresImplicitConstructionSequence",",,,") )
+    /// Type abbreviations cannot have augmentations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:832)
+    static member tcTypeAbbreviationsCannotHaveAugmentations() = (964, GetStringFunc("tcTypeAbbreviationsCannotHaveAugmentations",",,,") )
+    /// The path '%s' is a namespace. A module abbreviation may not abbreviate a namespace.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:833)
+    static member tcModuleAbbreviationForNamespace(a0 : System.String) = (965, GetStringFunc("tcModuleAbbreviationForNamespace",",,,%s,,,") a0)
+    /// The type '%s' is used in an invalid way. A value prior to '%s' has an inferred type involving '%s', which is an invalid forward reference.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:834)
+    static member tcTypeUsedInInvalidWay(a0 : System.String, a1 : System.String, a2 : System.String) = (966, GetStringFunc("tcTypeUsedInInvalidWay",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The member '%s' is used in an invalid way. A use of '%s' has been inferred prior to the definition of '%s', which is an invalid forward reference.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:835)
+    static member tcMemberUsedInInvalidWay(a0 : System.String, a1 : System.String, a2 : System.String) = (967, GetStringFunc("tcMemberUsedInInvalidWay",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// Explicit signatures within implementation files may no longer be used
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:836)
+    static member tcExplicitSignaturesInImplementationFileCannotBeUsed() = (968, GetStringFunc("tcExplicitSignaturesInImplementationFileCannotBeUsed",",,,") )
+    /// Modules cannot use named module signature definitions
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:837)
+    static member tcModulesCannotUseNamedModuleSignatures() = (969, GetStringFunc("tcModulesCannotUseNamedModuleSignatures",",,,") )
+    /// The attribute 'AutoOpen(\"%s\")' in the assembly '%s' did not refer to a valid module or namespace in that assembly and has been ignored
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:838)
+    static member tcAttributeAutoOpenWasIgnored(a0 : System.String, a1 : System.String) = (970, GetStringFunc("tcAttributeAutoOpenWasIgnored",",,,%s,,,%s,,,") a0 a1)
+    /// Undefined value '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:842)
+    static member ilUndefinedValue(a0 : System.String) = (971, GetStringFunc("ilUndefinedValue",",,,%s,,,") a0)
+    /// Label %s not found
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:843)
+    static member ilLabelNotFound(a0 : System.String) = (972, GetStringFunc("ilLabelNotFound",",,,%s,,,") a0)
+    /// Incorrect number of type arguments to local call
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:844)
+    static member ilIncorrectNumberOfTypeArguments() = (973, GetStringFunc("ilIncorrectNumberOfTypeArguments",",,,") )
+    /// Dynamic invocation of %s is not supported
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:845)
+    static member ilDynamicInvocationNotSupported(a0 : System.String) = (GetStringFunc("ilDynamicInvocationNotSupported",",,,%s,,,") a0)
+    /// Taking the address of a literal field is invalid
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:846)
+    static member ilAddressOfLiteralFieldIsInvalid() = (975, GetStringFunc("ilAddressOfLiteralFieldIsInvalid",",,,") )
+    /// This operation involves taking the address of a value '%s' represented using a local variable or other special representation. This is invalid.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:847)
+    static member ilAddressOfValueHereIsInvalid(a0 : System.String) = (976, GetStringFunc("ilAddressOfValueHereIsInvalid",",,,%s,,,") a0)
+    /// Values marked with 'LiteralAttribute' cannot be mutable
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:848)
+    static member ilValuesWithLiteralAttributeCannotBeMutable() = (978, GetStringFunc("ilValuesWithLiteralAttributeCannotBeMutable",",,,") )
+    /// Values marked with 'LiteralAttribute' must currently be simple integer, character, Boolean, string or floating point constants
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:849)
+    static member ilValuesWithLiteralAttributeMustBeSimple() = (979, GetStringFunc("ilValuesWithLiteralAttributeMustBeSimple",",,,") )
+    /// Custom marshallers cannot be specified in F# code. Consider using a C# helper function.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:850)
+    static member ilCustomMarshallersCannotBeUsedInFSharp() = (980, GetStringFunc("ilCustomMarshallersCannotBeUsedInFSharp",",,,") )
+    /// The MarshalAs attribute could not be decoded
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:851)
+    static member ilMarshalAsAttributeCannotBeDecoded() = (981, GetStringFunc("ilMarshalAsAttributeCannotBeDecoded",",,,") )
+    /// The signature for this external function contains type parameters. Constrain the argument and return types to indicate the types of the corresponding C function.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:852)
+    static member ilSignatureForExternalFunctionContainsTypeParameters() = (982, GetStringFunc("ilSignatureForExternalFunctionContainsTypeParameters",",,,") )
+    /// The DllImport attribute could not be decoded
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:853)
+    static member ilDllImportAttributeCouldNotBeDecoded() = (983, GetStringFunc("ilDllImportAttributeCouldNotBeDecoded",",,,") )
+    /// Literal fields cannot be set
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:854)
+    static member ilLiteralFieldsCannotBeSet() = (984, GetStringFunc("ilLiteralFieldsCannotBeSet",",,,") )
+    /// GenSetStorage: %s was represented as a static method but was not an appropriate lambda expression
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:855)
+    static member ilStaticMethodIsNotLambda(a0 : System.String) = (985, GetStringFunc("ilStaticMethodIsNotLambda",",,,%s,,,") a0)
+    /// Mutable variables cannot escape their method
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:856)
+    static member ilMutableVariablesCannotEscapeMethod() = (986, GetStringFunc("ilMutableVariablesCannotEscapeMethod",",,,") )
+    /// Compiler error: unexpected unrealized value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:857)
+    static member ilUnexpectedUnrealizedValue() = (987, GetStringFunc("ilUnexpectedUnrealizedValue",",,,") )
+    /// Main module of program is empty: nothing will happen when it is run
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:858)
+    static member ilMainModuleEmpty() = (988, GetStringFunc("ilMainModuleEmpty",",,,") )
+    /// This type cannot be used for a literal field
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:859)
+    static member ilTypeCannotBeUsedForLiteralField() = (989, GetStringFunc("ilTypeCannotBeUsedForLiteralField",",,,") )
+    /// Unexpected GetSet annotation on a property
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:860)
+    static member ilUnexpectedGetSetAnnotation() = (990, GetStringFunc("ilUnexpectedGetSetAnnotation",",,,") )
+    /// The FieldOffset attribute could not be decoded
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:861)
+    static member ilFieldOffsetAttributeCouldNotBeDecoded() = (991, GetStringFunc("ilFieldOffsetAttributeCouldNotBeDecoded",",,,") )
+    /// The StructLayout attribute could not be decoded
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:862)
+    static member ilStructLayoutAttributeCouldNotBeDecoded() = (992, GetStringFunc("ilStructLayoutAttributeCouldNotBeDecoded",",,,") )
+    /// The DefaultAugmentation attribute could not be decoded
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:863)
+    static member ilDefaultAugmentationAttributeCouldNotBeDecoded() = (993, GetStringFunc("ilDefaultAugmentationAttributeCouldNotBeDecoded",",,,") )
+    /// Reflected definitions cannot contain uses of the prefix splice operator '%%'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:864)
+    static member ilReflectedDefinitionsCannotUseSliceOperator() = (994, GetStringFunc("ilReflectedDefinitionsCannotUseSliceOperator",",,,") )
+    /// Problem with codepage '%d': %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:868)
+    static member optsProblemWithCodepage(a0 : System.Int32, a1 : System.String) = (1000, GetStringFunc("optsProblemWithCodepage",",,,%d,,,%s,,,") a0 a1)
+    /// Copyright (c) Microsoft Corporation. All Rights Reserved.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:869)
+    static member optsCopyright() = (GetStringFunc("optsCopyright",",,,") )
+    /// Name of the output file (Short form: -o)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:870)
+    static member optsNameOfOutputFile() = (GetStringFunc("optsNameOfOutputFile",",,,") )
+    /// Build a console executable
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:871)
+    static member optsBuildConsole() = (GetStringFunc("optsBuildConsole",",,,") )
+    /// Build a Windows executable
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:872)
+    static member optsBuildWindows() = (GetStringFunc("optsBuildWindows",",,,") )
+    /// Build a library (Short form: -a)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:873)
+    static member optsBuildLibrary() = (GetStringFunc("optsBuildLibrary",",,,") )
+    /// Build a module that can be added to another assembly
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:874)
+    static member optsBuildModule() = (GetStringFunc("optsBuildModule",",,,") )
+    /// Delay-sign the assembly using only the public portion of the strong name key
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:875)
+    static member optsDelaySign() = (GetStringFunc("optsDelaySign",",,,") )
+    /// Write the xmldoc of the assembly to the given file
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:876)
+    static member optsWriteXml() = (GetStringFunc("optsWriteXml",",,,") )
+    /// Specify a strong name key file
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:877)
+    static member optsStrongKeyFile() = (GetStringFunc("optsStrongKeyFile",",,,") )
+    /// Specify a strong name key container
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:878)
+    static member optsStrongKeyContainer() = (GetStringFunc("optsStrongKeyContainer",",,,") )
+    /// Limit which platforms this code can run on: x86, Itanium, x64 or anycpu. The default is anycpu.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:879)
+    static member optsPlatform() = (GetStringFunc("optsPlatform",",,,") )
+    /// Only include optimization information essential for implementing inlined constructs. Inhibits cross-module inlining but improves binary compatibility.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:880)
+    static member optsNoOpt() = (GetStringFunc("optsNoOpt",",,,") )
+    /// Don't add a resource to the generated assembly containing F#-specific metadata
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:881)
+    static member optsNoInterface() = (GetStringFunc("optsNoInterface",",,,") )
+    /// Print the inferred interface of the assembly to a file
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:882)
+    static member optsSig() = (GetStringFunc("optsSig",",,,") )
+    /// Reference an assembly (Short form: -r)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:883)
+    static member optsReference() = (GetStringFunc("optsReference",",,,") )
+    /// Specify a Win32 resource file (.res)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:884)
+    static member optsWin32res() = (GetStringFunc("optsWin32res",",,,") )
+    /// Specify a Win32 manifest file
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:885)
+    static member optsWin32manifest() = (GetStringFunc("optsWin32manifest",",,,") )
+    /// Do not include the default Win32 manifest
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:886)
+    static member optsNowin32manifest() = (GetStringFunc("optsNowin32manifest",",,,") )
+    /// Embed the specified managed resource
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:887)
+    static member optsResource() = (GetStringFunc("optsResource",",,,") )
+    /// Link the specified resource to this assembly where the resinfo format is <file>[,<string name>[,public|private]]
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:888)
+    static member optsLinkresource() = (GetStringFunc("optsLinkresource",",,,") )
+    /// Emit debug information (Short form: -g)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:889)
+    static member optsDebugPM() = (GetStringFunc("optsDebugPM",",,,") )
+    /// Specify debugging type: full, pdbonly. ('full' is the default and enables attaching a debugger to a running program).
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:890)
+    static member optsDebug() = (GetStringFunc("optsDebug",",,,") )
+    /// Enable optimizations (Short form: -O)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:891)
+    static member optsOptimize() = (GetStringFunc("optsOptimize",",,,") )
+    /// Enable or disable tailcalls
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:892)
+    static member optsTailcalls() = (GetStringFunc("optsTailcalls",",,,") )
+    /// Enable or disable cross-module optimizations
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:893)
+    static member optsCrossoptimize() = (GetStringFunc("optsCrossoptimize",",,,") )
+    /// Report all warnings as errors
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:894)
+    static member optsWarnaserrorPM() = (GetStringFunc("optsWarnaserrorPM",",,,") )
+    /// Report specific warnings as errors
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:895)
+    static member optsWarnaserror() = (GetStringFunc("optsWarnaserror",",,,") )
+    /// Set a warning level (0-4)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:896)
+    static member optsWarn() = (GetStringFunc("optsWarn",",,,") )
+    /// Disable specific warning messages
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:897)
+    static member optsNowarn() = (GetStringFunc("optsNowarn",",,,") )
+    /// Generate overflow checks
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:898)
+    static member optsChecked() = (GetStringFunc("optsChecked",",,,") )
+    /// Define conditional compilation symbols (Short form: -d)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:899)
+    static member optsDefine() = (GetStringFunc("optsDefine",",,,") )
+    /// Ignore ML compatibility warnings
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:900)
+    static member optsMlcompatibility() = (GetStringFunc("optsMlcompatibility",",,,") )
+    /// Suppress compiler copyright message
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:901)
+    static member optsNologo() = (GetStringFunc("optsNologo",",,,") )
+    /// Display this usage message (Short form: -?)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:902)
+    static member optsHelp() = (GetStringFunc("optsHelp",",,,") )
+    /// Specify the codepage used to read source files
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:903)
+    static member optsCodepage() = (GetStringFunc("optsCodepage",",,,") )
+    /// Output messages in UTF-8 encoding
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:904)
+    static member optsUtf8output() = (GetStringFunc("optsUtf8output",",,,") )
+    /// Output messages with fully qualified paths
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:905)
+    static member optsFullpaths() = (GetStringFunc("optsFullpaths",",,,") )
+    /// Specify a directory for the include path which is used to resolve source files and assemblies (Short form: -I)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:906)
+    static member optsLib() = (GetStringFunc("optsLib",",,,") )
+    /// Base address for the library to be built
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:907)
+    static member optsBaseaddress() = (GetStringFunc("optsBaseaddress",",,,") )
+    /// Do not reference the default CLI assemblies by default
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:908)
+    static member optsNoframework() = (GetStringFunc("optsNoframework",",,,") )
+    /// Statically link the F# library and all referenced DLLs that depend on it into the assembly being generated
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:909)
+    static member optsStandalone() = (GetStringFunc("optsStandalone",",,,") )
+    /// Statically link the given assembly and all referenced DLLs that depend on this assembly. Use an assembly name e.g. mylib, not a DLL name.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:910)
+    static member optsStaticlink() = (GetStringFunc("optsStaticlink",",,,") )
+    /// Name the output debug file
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:911)
+    static member optsPdb() = (GetStringFunc("optsPdb",",,,") )
+    /// Resolve assembly references using directory-based mono rules rather than MSBuild resolution (Default=false except when running fsc.exe under mono)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:912)
+    static member optsSimpleresolution() = (GetStringFunc("optsSimpleresolution",",,,") )
+    /// Unrecognized target '%s', expected 'exe', 'winexe', 'library' or 'module'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:913)
+    static member optsUnrecognizedTarget(a0 : System.String) = (1048, GetStringFunc("optsUnrecognizedTarget",",,,%s,,,") a0)
+    /// Unrecognized debug type '%s', expected 'pdbonly' or 'full'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:914)
+    static member optsUnrecognizedDebugType(a0 : System.String) = (1049, GetStringFunc("optsUnrecognizedDebugType",",,,%s,,,") a0)
+    /// Invalid warning level '%d'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:915)
+    static member optsInvalidWarningLevel(a0 : System.Int32) = (1050, GetStringFunc("optsInvalidWarningLevel",",,,%d,,,") a0)
+    /// Short form of '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:916)
+    static member optsShortFormOf(a0 : System.String) = (GetStringFunc("optsShortFormOf",",,,%s,,,") a0)
+    /// The command-line option '--cliroot' has been deprecated. Use an explicit reference to a specific copy of mscorlib.dll instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:917)
+    static member optsClirootDeprecatedMsg() = (GetStringFunc("optsClirootDeprecatedMsg",",,,") )
+    /// Use to override where the compiler looks for mscorlib.dll and framework components
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:918)
+    static member optsClirootDescription() = (GetStringFunc("optsClirootDescription",",,,") )
+    /// - OUTPUT FILES -
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:919)
+    static member optsHelpBannerOutputFiles() = (GetStringFunc("optsHelpBannerOutputFiles",",,,") )
+    /// - INPUT FILES -
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:920)
+    static member optsHelpBannerInputFiles() = (GetStringFunc("optsHelpBannerInputFiles",",,,") )
+    /// - RESOURCES -
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:921)
+    static member optsHelpBannerResources() = (GetStringFunc("optsHelpBannerResources",",,,") )
+    /// - CODE GENERATION -
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:922)
+    static member optsHelpBannerCodeGen() = (GetStringFunc("optsHelpBannerCodeGen",",,,") )
+    /// - ADVANCED -
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:923)
+    static member optsHelpBannerAdvanced() = (GetStringFunc("optsHelpBannerAdvanced",",,,") )
+    /// - MISCELLANEOUS -
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:924)
+    static member optsHelpBannerMisc() = (GetStringFunc("optsHelpBannerMisc",",,,") )
+    /// - LANGUAGE -
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:925)
+    static member optsHelpBannerLanguage() = (GetStringFunc("optsHelpBannerLanguage",",,,") )
+    /// - ERRORS AND WARNINGS -
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:926)
+    static member optsHelpBannerErrsAndWarns() = (GetStringFunc("optsHelpBannerErrsAndWarns",",,,") )
+    /// Unknown --test argument: '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:927)
+    static member optsUnknownArgumentToTheTestSwitch(a0 : System.String) = (1063, GetStringFunc("optsUnknownArgumentToTheTestSwitch",",,,%s,,,") a0)
+    /// Unrecognized platform '%s', valid values are 'x86', 'x64', 'Itanium', and 'anycpu'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:928)
+    static member optsUnknownPlatform(a0 : System.String) = (1064, GetStringFunc("optsUnknownPlatform",",,,%s,,,") a0)
+    /// The command-line option '%s' is for internal use only
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:929)
+    static member optsInternalNoDescription(a0 : System.String) = (GetStringFunc("optsInternalNoDescription",",,,%s,,,") a0)
+    /// The command-line option '%s' has been deprecated
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:930)
+    static member optsDCLONoDescription(a0 : System.String) = (GetStringFunc("optsDCLONoDescription",",,,%s,,,") a0)
+    /// The command-line option '%s' has been deprecated. Use '%s' instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:931)
+    static member optsDCLODeprecatedSuggestAlternative(a0 : System.String, a1 : System.String) = (GetStringFunc("optsDCLODeprecatedSuggestAlternative",",,,%s,,,%s,,,") a0 a1)
+    /// The command-line option '%s' has been deprecated. HTML document generation is now part of the F# Power Pack, via the tool FsHtmlDoc.exe.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:932)
+    static member optsDCLOHtmlDoc(a0 : System.String) = (GetStringFunc("optsDCLOHtmlDoc",",,,%s,,,") a0)
+    /// This file was automatically generated by a call to Goto Definition
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:936)
+    static member gotoDefinitionHeader() = (GetStringFunc("gotoDefinitionHeader",",,,") )
+    /// Full name
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:940)
+    static member typeInfoFullName() = (GetStringFunc("typeInfoFullName",",,,") )
+    /// type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:941)
+    static member typeInfoType() = (GetStringFunc("typeInfoType",",,,") )
+    /// inherits
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:942)
+    static member typeInfoInherits() = (GetStringFunc("typeInfoInherits",",,,") )
+    /// implements
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:943)
+    static member typeInfoImplements() = (GetStringFunc("typeInfoImplements",",,,") )
+    /// and %d other overloads
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:944)
+    static member typeInfoOtherOverloads(a0 : System.Int32) = (GetStringFunc("typeInfoOtherOverloads",",,,%d,,,") a0)
+    /// union case
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:945)
+    static member typeInfoUnionCase() = (GetStringFunc("typeInfoUnionCase",",,,") )
+    /// active pattern result
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:946)
+    static member typeInfoActivePatternResult() = (GetStringFunc("typeInfoActivePatternResult",",,,") )
+    /// active recognizer
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:947)
+    static member typeInfoActiveRecognizer() = (GetStringFunc("typeInfoActiveRecognizer",",,,") )
+    /// field
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:948)
+    static member typeInfoField() = (GetStringFunc("typeInfoField",",,,") )
+    /// event
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:949)
+    static member typeInfoEvent() = (GetStringFunc("typeInfoEvent",",,,") )
+    /// property
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:950)
+    static member typeInfoProperty() = (GetStringFunc("typeInfoProperty",",,,") )
+    /// argument
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:951)
+    static member typeInfoArgument() = (GetStringFunc("typeInfoArgument",",,,") )
+    /// patvar
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:952)
+    static member typeInfoPatternVariable() = (GetStringFunc("typeInfoPatternVariable",",,,") )
+    /// namespace
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:953)
+    static member typeInfoNamespace() = (GetStringFunc("typeInfoNamespace",",,,") )
+    /// module
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:954)
+    static member typeInfoModule() = (GetStringFunc("typeInfoModule",",,,") )
+    /// namespace/module
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:955)
+    static member typeInfoNamespaceOrModule() = (GetStringFunc("typeInfoNamespaceOrModule",",,,") )
+    /// from %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:956)
+    static member typeInfoFromFirst(a0 : System.String) = (GetStringFunc("typeInfoFromFirst",",,,%s,,,") a0)
+    /// also from %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:957)
+    static member typeInfoFromNext(a0 : System.String) = (GetStringFunc("typeInfoFromNext",",,,%s,,,") a0)
+    /// Found by AssemblyFolders registry key
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:958)
+    static member assemblyResolutionFoundByAssemblyFoldersKey() = (GetStringFunc("assemblyResolutionFoundByAssemblyFoldersKey",",,,") )
+    /// Found by AssemblyFoldersEx registry key
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:959)
+    static member assemblyResolutionFoundByAssemblyFoldersExKey() = (GetStringFunc("assemblyResolutionFoundByAssemblyFoldersExKey",",,,") )
+    /// .NET Framework
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:960)
+    static member assemblyResolutionNetFramework() = (GetStringFunc("assemblyResolutionNetFramework",",,,") )
+    /// Global Assembly Cache
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:961)
+    static member assemblyResolutionGAC() = (GetStringFunc("assemblyResolutionGAC",",,,") )
+    /// Recursive class hierarchy in type '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:965)
+    static member recursiveClassHierarchy(a0 : System.String) = (1089, GetStringFunc("recursiveClassHierarchy",",,,%s,,,") a0)
+    /// Invalid recursive reference to an abstract slot
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:966)
+    static member InvalidRecursiveReferenceToAbstractSlot() = (1090, GetStringFunc("InvalidRecursiveReferenceToAbstractSlot",",,,") )
+    /// The event '%s' has a non-standard type. If this event is declared in another CLI language, you may need to access this event using the explicit %s and %s methods for the event. If this event is declared in F#, make the type of the event an instantiation of either 'IDelegateEvent<_>' or 'IEvent<_,_>'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:967)
+    static member eventHasNonStandardType(a0 : System.String, a1 : System.String, a2 : System.String) = (1091, GetStringFunc("eventHasNonStandardType",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The type '%s' is not accessible from this code location
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:968)
+    static member typeIsNotAccessible(a0 : System.String) = (1092, GetStringFunc("typeIsNotAccessible",",,,%s,,,") a0)
+    /// The union cases or fields of the type '%s' are not accessible from this code location
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:969)
+    static member unionCasesAreNotAccessible(a0 : System.String) = (1093, GetStringFunc("unionCasesAreNotAccessible",",,,%s,,,") a0)
+    /// The value '%s' is not accessible from this code location
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:970)
+    static member valueIsNotAccessible(a0 : System.String) = (1094, GetStringFunc("valueIsNotAccessible",",,,%s,,,") a0)
+    /// The union case '%s' is not accessible from this code location
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:971)
+    static member unionCaseIsNotAccessible(a0 : System.String) = (1095, GetStringFunc("unionCaseIsNotAccessible",",,,%s,,,") a0)
+    /// The record, struct or class field '%s' is not accessible from this code location
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:972)
+    static member fieldIsNotAccessible(a0 : System.String) = (1096, GetStringFunc("fieldIsNotAccessible",",,,%s,,,") a0)
+    /// The struct or class field '%s' is not accessible from this code location
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:973)
+    static member structOrClassFieldIsNotAccessible(a0 : System.String) = (1097, GetStringFunc("structOrClassFieldIsNotAccessible",",,,%s,,,") a0)
+    /// This construct is experimental
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:974)
+    static member experimentalConstruct() = (GetStringFunc("experimentalConstruct",",,,") )
+    /// No Invoke methods found for delegate type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:975)
+    static member noInvokeMethodsFound() = (1099, GetStringFunc("noInvokeMethodsFound",",,,") )
+    /// More than one Invoke method found for delegate type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:976)
+    static member moreThanOneInvokeMethodFound() = (GetStringFunc("moreThanOneInvokeMethodFound",",,,") )
+    /// Delegates are not allowed to have curried signatures
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:977)
+    static member delegatesNotAllowedToHaveCurriedSignatures() = (1101, GetStringFunc("delegatesNotAllowedToHaveCurriedSignatures",",,,") )
+    /// Unexpected TExpr_tchoose
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:981)
+    static member tlrUnexpectedTExpr() = (1102, GetStringFunc("tlrUnexpectedTExpr",",,,") )
+    /// Note: Lambda-lifting optimizations have not been applied because of the use of this local constrained generic function as a first class value. Adding type constraints may resolve this condition.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:982)
+    static member tlrLambdaLiftingOptimizationsNotApplied() = (1103, GetStringFunc("tlrLambdaLiftingOptimizationsNotApplied",",,,") )
+    /// Identifiers containing '@' are reserved for use in F# code generation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:986)
+    static member lexhlpIdentifiersContainingAtSymbolReserved() = (1104, GetStringFunc("lexhlpIdentifiersContainingAtSymbolReserved",",,,") )
+    /// The identifier '%s' is reserved for future use by F#
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:987)
+    static member lexhlpIdentifierReserved(a0 : System.String) = (GetStringFunc("lexhlpIdentifierReserved",",,,%s,,,") a0)
+    /// Missing variable '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:991)
+    static member patcMissingVariable(a0 : System.String) = (1106, GetStringFunc("patcMissingVariable",",,,%s,,,") a0)
+    /// Partial active patterns may only generate one result
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:992)
+    static member patcPartialActivePatternsGenerateOneResult() = (1107, GetStringFunc("patcPartialActivePatternsGenerateOneResult",",,,") )
+    /// The type '%s' is required here and is unavailable. You must add a reference to assembly '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:996)
+    static member impTypeRequiredUnavailable(a0 : System.String, a1 : System.String) = (1108, GetStringFunc("impTypeRequiredUnavailable",",,,%s,,,%s,,,") a0 a1)
+    /// A reference to the type '%s' in assembly '%s' was found, but the type could not be found in that assembly
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:997)
+    static member impReferencedTypeCouldNotBeFoundInAssembly(a0 : System.String, a1 : System.String) = (1109, GetStringFunc("impReferencedTypeCouldNotBeFoundInAssembly",",,,%s,,,%s,,,") a0 a1)
+    /// Internal error or badly formed metadata: not enough type parameters were in scope while importing
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:998)
+    static member impNotEnoughTypeParamsInScopeWhileImporting() = (1110, GetStringFunc("impNotEnoughTypeParamsInScopeWhileImporting",",,,") )
+    /// A reference to the DLL %s is required by assembly %s. The imported type %s is located in the first assembly and could not be resolved.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:999)
+    static member impReferenceToDllRequiredByAssembly(a0 : System.String, a1 : System.String, a2 : System.String) = (1111, GetStringFunc("impReferenceToDllRequiredByAssembly",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// An imported assembly uses the type '%s' but that type is not public
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1000)
+    static member impImportedAssemblyUsesNotPublicType(a0 : System.String) = (1112, GetStringFunc("impImportedAssemblyUsesNotPublicType",",,,%s,,,") a0)
+    /// The value '%s' was marked inline but its implementation makes use of an internal or private function which is not sufficiently accessible
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1004)
+    static member optValueMarkedInlineButIncomplete(a0 : System.String) = (1113, GetStringFunc("optValueMarkedInlineButIncomplete",",,,%s,,,") a0)
+    /// The value '%s' was marked inline but was not bound in the optimization environment
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1005)
+    static member optValueMarkedInlineButWasNotBoundInTheOptEnv(a0 : System.String) = (1114, GetStringFunc("optValueMarkedInlineButWasNotBoundInTheOptEnv",",,,%s,,,") a0)
+    /// Local value %s not found during optimization
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1006)
+    static member optLocalValueNotFoundDuringOptimization(a0 : System.String) = (1115, GetStringFunc("optLocalValueNotFoundDuringOptimization",",,,%s,,,") a0)
+    /// A value marked as 'inline' has an unexpected value
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1007)
+    static member optValueMarkedInlineHasUnexpectedValue() = (1116, GetStringFunc("optValueMarkedInlineHasUnexpectedValue",",,,") )
+    /// A value marked as 'inline' could not be inlined
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1008)
+    static member optValueMarkedInlineCouldNotBeInlined() = (1117, GetStringFunc("optValueMarkedInlineCouldNotBeInlined",",,,") )
+    /// Failed to inline the value '%s' marked 'inline', perhaps because a recursive value was marked 'inline'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1009)
+    static member optFailedToInlineValue(a0 : System.String) = (1118, GetStringFunc("optFailedToInlineValue",",,,%s,,,") a0)
+    /// Recursive ValValue %s
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1010)
+    static member optRecursiveValValue(a0 : System.String) = (1119, GetStringFunc("optRecursiveValValue",",,,%s,,,") a0)
+    /// The indentation of this 'in' token is incorrect with respect to the corresponding 'let'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1014)
+    static member lexfltIncorrentIndentationOfIn() = (GetStringFunc("lexfltIncorrentIndentationOfIn",",,,") )
+    /// Possible incorrect indentation: this token is offside of context started at position %s. Try indenting this token further or using standard formatting conventions.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1015)
+    static member lexfltTokenIsOffsideOfContextStartedEarlier(a0 : System.String) = (GetStringFunc("lexfltTokenIsOffsideOfContextStartedEarlier",",,,%s,,,") a0)
+    /// The '|' tokens separating rules of this pattern match are misaligned by one column. Consider realigning your code or using further indentation.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1016)
+    static member lexfltSeparatorTokensOfPatternMatchMisaligned() = (GetStringFunc("lexfltSeparatorTokensOfPatternMatchMisaligned",",,,") )
+    /// Invalid module/expression/type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1020)
+    static member nrInvalidModuleExprType() = (1123, GetStringFunc("nrInvalidModuleExprType",",,,") )
+    /// Multiple types exist called '%s', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1021)
+    static member nrTypeInstantiationNeededToDisambiguateTypesWithSameName(a0 : System.String, a1 : System.String) = (1124, GetStringFunc("nrTypeInstantiationNeededToDisambiguateTypesWithSameName",",,,%s,,,%s,,,") a0 a1)
+    /// The instantiation of the generic type '%s' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. '%s'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1022)
+    static member nrTypeInstantiationIsMissingAndCouldNotBeInferred(a0 : System.String, a1 : System.String) = (1125, GetStringFunc("nrTypeInstantiationIsMissingAndCouldNotBeInferred",",,,%s,,,%s,,,") a0 a1)
+    /// 'global' may only be used as the first name in a qualified path
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1023)
+    static member nrGlobalUsedOnlyAsFirstName() = (1126, GetStringFunc("nrGlobalUsedOnlyAsFirstName",",,,") )
+    /// This is not a constructor or literal, or a constructor is being used incorrectly
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1024)
+    static member nrIsNotConstructorOrLiteral() = (1127, GetStringFunc("nrIsNotConstructorOrLiteral",",,,") )
+    /// Unexpected empty long identifier
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1025)
+    static member nrUnexpectedEmptyLongId() = (1128, GetStringFunc("nrUnexpectedEmptyLongId",",,,") )
+    /// The type '%s' does not contain a field '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1026)
+    static member nrTypeDoesNotContainSuchField(a0 : System.String, a1 : System.String) = (1129, GetStringFunc("nrTypeDoesNotContainSuchField",",,,%s,,,%s,,,") a0 a1)
+    /// Invalid field label
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1027)
+    static member nrInvalidFieldLabel() = (1130, GetStringFunc("nrInvalidFieldLabel",",,,") )
+    /// Invalid expression '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1028)
+    static member nrInvalidExpression(a0 : System.String) = (1132, GetStringFunc("nrInvalidExpression",",,,%s,,,") a0)
+    /// No constructors are available for the type '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1029)
+    static member nrNoConstructorsAvailableForType(a0 : System.String) = (1133, GetStringFunc("nrNoConstructorsAvailableForType",",,,%s,,,") a0)
+    /// Unexpected error creating debug information file '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1033)
+    static member ilwriteErrorCreatingPdb(a0 : System.String) = (1135, GetStringFunc("ilwriteErrorCreatingPdb",",,,%s,,,") a0)
+    /// PDB files cannot be generated when running on Mono
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1034)
+    static member ilwriteNoPDBsOnMonoWarning() = (1136, GetStringFunc("ilwriteNoPDBsOnMonoWarning",",,,") )
+    /// This number is outside the allowable range for this integer type
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1038)
+    static member lexOutsideIntegerRange() = (1138, GetStringFunc("lexOutsideIntegerRange",",,,") )
+    /// '%s' is not permitted as a character in operator names and is reserved for future use
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1039)
+    static member lexCharNotAllowedInOperatorNames(a0 : System.String) = (GetStringFunc("lexCharNotAllowedInOperatorNames",",,,%s,,,") a0)
+    /// Character sequences beginning with '?' are no longer permitted as operator names
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1040)
+    static member lexOpNamesCannotStartWithQuestionMark() = (GetStringFunc("lexOpNamesCannotStartWithQuestionMark",",,,") )
+    /// Unexpected character '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1041)
+    static member lexUnexpectedChar(a0 : System.String) = (GetStringFunc("lexUnexpectedChar",",,,%s,,,") a0)
+    /// This byte array literal contains characters that do not encode as a single byte
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1042)
+    static member lexByteArrayCannotEncode() = (1140, GetStringFunc("lexByteArrayCannotEncode",",,,") )
+    /// Identifiers followed by '%s' are reserved for future use
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1043)
+    static member lexIdentEndInMarkReserved(a0 : System.String) = (1141, GetStringFunc("lexIdentEndInMarkReserved",",,,%s,,,") a0)
+    /// This number is outside the allowable range for 8-bit signed integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1044)
+    static member lexOutsideEightBitSigned() = (1142, GetStringFunc("lexOutsideEightBitSigned",",,,") )
+    /// This number is outside the allowable range for hexadecimal 8-bit signed integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1045)
+    static member lexOutsideEightBitSignedHex() = (1143, GetStringFunc("lexOutsideEightBitSignedHex",",,,") )
+    /// This number is outside the allowable range for 8-bit unsigned integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1046)
+    static member lexOutsideEightBitUnsigned() = (1144, GetStringFunc("lexOutsideEightBitUnsigned",",,,") )
+    /// This number is outside the allowable range for 16-bit signed integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1047)
+    static member lexOutsideSixteenBitSigned() = (1145, GetStringFunc("lexOutsideSixteenBitSigned",",,,") )
+    /// This number is outside the allowable range for 16-bit unsigned integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1048)
+    static member lexOutsideSixteenBitUnsigned() = (1146, GetStringFunc("lexOutsideSixteenBitUnsigned",",,,") )
+    /// This number is outside the allowable range for 32-bit signed integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1049)
+    static member lexOutsideThirtyTwoBitSigned() = (1147, GetStringFunc("lexOutsideThirtyTwoBitSigned",",,,") )
+    /// This number is outside the allowable range for 32-bit unsigned integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1050)
+    static member lexOutsideThirtyTwoBitUnsigned() = (1148, GetStringFunc("lexOutsideThirtyTwoBitUnsigned",",,,") )
+    /// This number is outside the allowable range for 64-bit signed integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1051)
+    static member lexOutsideSixtyFourBitSigned() = (1149, GetStringFunc("lexOutsideSixtyFourBitSigned",",,,") )
+    /// This number is outside the allowable range for 64-bit unsigned integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1052)
+    static member lexOutsideSixtyFourBitUnsigned() = (1150, GetStringFunc("lexOutsideSixtyFourBitUnsigned",",,,") )
+    /// This number is outside the allowable range for signed native integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1053)
+    static member lexOutsideNativeSigned() = (1151, GetStringFunc("lexOutsideNativeSigned",",,,") )
+    /// This number is outside the allowable range for unsigned native integers
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1054)
+    static member lexOutsideNativeUnsigned() = (1152, GetStringFunc("lexOutsideNativeUnsigned",",,,") )
+    /// Invalid floating point number
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1055)
+    static member lexInvalidFloat() = (1153, GetStringFunc("lexInvalidFloat",",,,") )
+    /// This number is outside the allowable range for decimal literals
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1056)
+    static member lexOusideDecimal() = (1154, GetStringFunc("lexOusideDecimal",",,,") )
+    /// This number is outside the allowable range for 32-bit floats
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1057)
+    static member lexOusideThirtyTwoBitFloat() = (1155, GetStringFunc("lexOusideThirtyTwoBitFloat",",,,") )
+    /// This is not a valid numeric literal. Sample formats include 4, 0x4, 0b0100, 4L, 4UL, 4u, 4s, 4us, 4y, 4uy, 4.0, 4.0f, 4I.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1058)
+    static member lexInvalidNumericLiteral() = (1156, GetStringFunc("lexInvalidNumericLiteral",",,,") )
+    /// This is not a valid byte literal
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1059)
+    static member lexInvalidByteLiteral() = (1157, GetStringFunc("lexInvalidByteLiteral",",,,") )
+    /// This is not a valid character literal
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1060)
+    static member lexInvalidCharLiteral() = (1158, GetStringFunc("lexInvalidCharLiteral",",,,") )
+    /// This Unicode encoding is only valid in string literals
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1061)
+    static member lexThisUnicodeOnlyInStringLiterals() = (1159, GetStringFunc("lexThisUnicodeOnlyInStringLiterals",",,,") )
+    /// This token is reserved for future use
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1062)
+    static member lexTokenReserved() = (1160, GetStringFunc("lexTokenReserved",",,,") )
+    /// TABs are not allowed in F# code unless the #indent \"off\" option is used
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1063)
+    static member lexTabsNotAllowed() = (1161, GetStringFunc("lexTabsNotAllowed",",,,") )
+    /// Invalid line number: '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1064)
+    static member lexInvalidLineNumber(a0 : System.String) = (1162, GetStringFunc("lexInvalidLineNumber",",,,%s,,,") a0)
+    /// #if directive must appear as the first non-whitespace character on a line
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1065)
+    static member lexHashIfMustBeFirst() = (1163, GetStringFunc("lexHashIfMustBeFirst",",,,") )
+    /// #else has no matching #if
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1066)
+    static member lexHashElseNoMatchingIf() = (GetStringFunc("lexHashElseNoMatchingIf",",,,") )
+    /// #endif required for #else
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1067)
+    static member lexHashEndifRequiredForElse() = (GetStringFunc("lexHashEndifRequiredForElse",",,,") )
+    /// #else directive must appear as the first non-whitespace character on a line
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1068)
+    static member lexHashElseMustBeFirst() = (1166, GetStringFunc("lexHashElseMustBeFirst",",,,") )
+    /// #endif has no matching #if
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1069)
+    static member lexHashEndingNoMatchingIf() = (GetStringFunc("lexHashEndingNoMatchingIf",",,,") )
+    /// #endif directive must appear as the first non-whitespace character on a line
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1070)
+    static member lexHashEndifMustBeFirst() = (1168, GetStringFunc("lexHashEndifMustBeFirst",",,,") )
+    /// #if directive should be immediately followed by an identifier
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1071)
+    static member lexHashIfMustHaveIdent() = (1169, GetStringFunc("lexHashIfMustHaveIdent",",,,") )
+    /// Syntax error. Wrong nested #endif, unexpected tokens before it.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1072)
+    static member lexWrongNestedHashEndif() = (1170, GetStringFunc("lexWrongNestedHashEndif",",,,") )
+    /// Expected single line comment or end of line
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1073)
+    static member lexExpectedSingleLineComment() = (1171, GetStringFunc("lexExpectedSingleLineComment",",,,") )
+    /// Infix operator member '%s' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ...
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1074)
+    static member memberOperatorDefinitionWithNoArguments(a0 : System.String) = (1172, GetStringFunc("memberOperatorDefinitionWithNoArguments",",,,%s,,,") a0)
+    /// Infix operator member '%s' has %d initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ...
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1075)
+    static member memberOperatorDefinitionWithNonPairArgument(a0 : System.String, a1 : System.Int32) = (1173, GetStringFunc("memberOperatorDefinitionWithNonPairArgument",",,,%s,,,%d,,,") a0 a1)
+    /// Infix operator member '%s' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ...
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1076)
+    static member memberOperatorDefinitionWithCurriedArguments(a0 : System.String) = (1174, GetStringFunc("memberOperatorDefinitionWithCurriedArguments",",,,%s,,,") a0)
+    /// All record, union and struct types in FSharp.Core.dll must be explicitly labelled with 'StructuralComparison' or 'NoComparison'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1077)
+    static member tcFSharpCoreRequiresExplicit() = (1175, GetStringFunc("tcFSharpCoreRequiresExplicit",",,,") )
+    /// The struct, record or union type '%s' has the 'StructuralComparison' attribute but the type parameter '%s' does not satisfy the 'comparison' constraint. Consider adding the 'comparison' constraint to the type parameter
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1078)
+    static member tcStructuralComparisonNotSatisfied1(a0 : System.String, a1 : System.String) = (1176, GetStringFunc("tcStructuralComparisonNotSatisfied1",",,,%s,,,%s,,,") a0 a1)
+    /// The struct, record or union type '%s' has the 'StructuralComparison' attribute but the component type '%s' does not satisfy the 'comparison' constraint
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1079)
+    static member tcStructuralComparisonNotSatisfied2(a0 : System.String, a1 : System.String) = (1177, GetStringFunc("tcStructuralComparisonNotSatisfied2",",,,%s,,,%s,,,") a0 a1)
+    /// The struct, record or union type '%s' is not structurally comparable because the type parameter %s does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type '%s' to clarify that the type is not comparable
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1080)
+    static member tcNoComparisonNeeded1(a0 : System.String, a1 : System.String, a2 : System.String) = (1178, GetStringFunc("tcNoComparisonNeeded1",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The struct, record or union type '%s' is not structurally comparable because the type '%s' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type '%s' to clarify that the type is not comparable
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1081)
+    static member tcNoComparisonNeeded2(a0 : System.String, a1 : System.String, a2 : System.String) = (1178, GetStringFunc("tcNoComparisonNeeded2",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The struct, record or union type '%s' does not support structural equality because the type parameter %s does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type '%s' to clarify that the type does not support structural equality
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1082)
+    static member tcNoEqualityNeeded1(a0 : System.String, a1 : System.String, a2 : System.String) = (1178, GetStringFunc("tcNoEqualityNeeded1",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The struct, record or union type '%s' does not support structural equality because the type '%s' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type '%s' to clarify that the type does not support structural equality
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1083)
+    static member tcNoEqualityNeeded2(a0 : System.String, a1 : System.String, a2 : System.String) = (1178, GetStringFunc("tcNoEqualityNeeded2",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The struct, record or union type '%s' has the 'StructuralEquality' attribute but the type parameter '%s' does not satisfy the 'equality' constraint. Consider adding the 'equality' constraint to the type parameter
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1084)
+    static member tcStructuralEqualityNotSatisfied1(a0 : System.String, a1 : System.String) = (1179, GetStringFunc("tcStructuralEqualityNotSatisfied1",",,,%s,,,%s,,,") a0 a1)
+    /// The struct, record or union type '%s' has the 'StructuralEquality' attribute but the component type '%s' does not satisfy the 'equality' constraint
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1085)
+    static member tcStructuralEqualityNotSatisfied2(a0 : System.String, a1 : System.String) = (1180, GetStringFunc("tcStructuralEqualityNotSatisfied2",",,,%s,,,%s,,,") a0 a1)
+    /// Each argument of the primary constructor for a struct must be given a type, for example 'type S(x1:int, x2: int) = ...'. These arguments determine the fields of the struct.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1086)
+    static member tcStructsMustDeclareTypesOfImplicitCtorArgsExplicitly() = (1181, GetStringFunc("tcStructsMustDeclareTypesOfImplicitCtorArgsExplicitly",",,,") )
+    /// The value '%s' is unused
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1087)
+    static member chkUnusedValue(a0 : System.String) = (1182, GetStringFunc("chkUnusedValue",",,,%s,,,") a0)
+    /// The recursive object reference '%s' is unused. The presence of a recursive object reference adds runtime initialization checks to members in this and derived types. Consider removing this recursive object reference.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1088)
+    static member chkUnusedThisVariable(a0 : System.String) = (1183, GetStringFunc("chkUnusedThisVariable",",,,%s,,,") a0)
+    /// A getter property may have at most one argument group
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1089)
+    static member parsGetterAtMostOneArgument() = (1184, GetStringFunc("parsGetterAtMostOneArgument",",,,") )
+    /// A setter property may have at most two argument groups
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1090)
+    static member parsSetterAtMostTwoArguments() = (1185, GetStringFunc("parsSetterAtMostTwoArguments",",,,") )
+    /// Invalid property getter or setter
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1091)
+    static member parsInvalidProperty() = (1186, GetStringFunc("parsInvalidProperty",",,,") )
+    /// An indexer property must be given at least one argument
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1092)
+    static member parsIndexerPropertyRequiresAtLeastOneArgument() = (1187, GetStringFunc("parsIndexerPropertyRequiresAtLeastOneArgument",",,,") )
+    /// This operation accesses a mutable top-level value defined in another assembly in an unsupported way. The value cannot be accessed through its address. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...', and if necessary assigning the value back after the completion of the operation
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1093)
+    static member tastInvalidAddressOfMutableAcrossAssemblyBoundary() = (1188, GetStringFunc("tastInvalidAddressOfMutableAcrossAssemblyBoundary",",,,") )
+    /// Type parameters must be placed directly adjacent to the type name, e.g. \"type C<'T>\", not     type \"C   <'T>\"
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1094)
+    static member parsNonAdjacentTypars() = (1189, GetStringFunc("parsNonAdjacentTypars",",,,") )
+    /// Type arguments must be placed directly adjacent to the type name, e.g. \"C<'T>\", not \"C  <'T>\"
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1095)
+    static member parsNonAdjacentTyargs() = (1190, GetStringFunc("parsNonAdjacentTyargs",",,,") )
+    /// The use of the type syntax 'int C' and 'C  <int>' is not permitted here. Consider adjusting this type to be written in the form 'C<int>'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1096)
+    static member parsNonAtomicType() = (GetStringFunc("parsNonAtomicType",",,,") )
+    /// The type %s did not contain the field '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1097)
+    static member tastUndefinedTyconItemField(a0 : System.String, a1 : System.String) = (1191, GetStringFunc("tastUndefinedTyconItemField",",,,%s,,,%s,,,") a0 a1)
+    /// The type %s did not contain the union case '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1098)
+    static member tastUndefinedTyconItemUnionCase(a0 : System.String, a1 : System.String) = (1192, GetStringFunc("tastUndefinedTyconItemUnionCase",",,,%s,,,%s,,,") a0 a1)
+    /// The module/namespace '%s' from compilation unit '%s' did not contain the module/namespace '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1099)
+    static member tastUndefinedItemRefModuleNamespace(a0 : System.String, a1 : System.String, a2 : System.String) = (1193, GetStringFunc("tastUndefinedItemRefModuleNamespace",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The module/namespace '%s' from compilation unit '%s' did not contain the val '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1100)
+    static member tastUndefinedItemRefVal(a0 : System.String, a1 : System.String, a2 : System.String) = (1194, GetStringFunc("tastUndefinedItemRefVal",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The module/namespace '%s' from compilation unit '%s' did not contain the namespace, module or type '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1101)
+    static member tastUndefinedItemRefModuleNamespaceType(a0 : System.String, a1 : System.String, a2 : System.String) = (1195, GetStringFunc("tastUndefinedItemRefModuleNamespaceType",",,,%s,,,%s,,,%s,,,") a0 a1 a2)
+    /// The 'UseNullAsTrueValue' attribute flag may only be used with union types that have one nullary case and at least one non-nullary case
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1102)
+    static member tcInvalidUseNullAsTrueValue() = (1196, GetStringFunc("tcInvalidUseNullAsTrueValue",",,,") )
+    /// The parameter '%s' was inferred to have byref type. Parameters of byref type must be given an explicit type annotation, e.g. 'x1: byref<int>'. When used, a byref parameter is implicitly dereferenced.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1103)
+    static member tcParameterInferredByref(a0 : System.String) = (1197, GetStringFunc("tcParameterInferredByref",",,,%s,,,") a0)
+    /// The generic member '%s' has been used at a non-uniform instantiation prior to this program point. Consider reordering the members so this member occurs first. Alternatively, specify the full type of the member explicitly, including argument types, return type and any additional generic parameters and constraints.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1104)
+    static member tcNonUniformMemberUse(a0 : System.String) = (1198, GetStringFunc("tcNonUniformMemberUse",",,,%s,,,") a0)
+    /// The use of named arguments in union case expressions is reserved for future use. Arguments of the form 'a=b' should be parenthesized.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1105)
+    static member tcNamedArgumentsCannotBeUsedInUnionCaseConstructions() = (1199, GetStringFunc("tcNamedArgumentsCannotBeUsedInUnionCaseConstructions",",,,") )
+    /// The attribute '%s' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1106)
+    static member tcAttribArgsDiffer(a0 : System.String) = (1200, GetStringFunc("tcAttribArgsDiffer",",,,%s,,,") a0)
+    /// Cannot call an abstract base member: '%s'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1107)
+    static member tcCannotCallAbstractBaseMember(a0 : System.String) = (1201, GetStringFunc("tcCannotCallAbstractBaseMember",",,,%s,,,") a0)
+    /// Could not resolve the ambiguity in the use of a generic construct with an 'unmanaged' constraint at or near this position
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1108)
+    static member typrelCannotResolveAmbiguityInUnmanaged() = (1202, GetStringFunc("typrelCannotResolveAmbiguityInUnmanaged",",,,") )
+    /// This construct is for ML compatibility. %s. You can disable this warning by using '--mlcompatibility' or '--nowarn:62'.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1111)
+    static member mlCompatMessage(a0 : System.String) = (GetStringFunc("mlCompatMessage",",,,%s,,,") a0)
+    /// The type '%s' has been marked as having an Explicit layout, but the field '%s' has not been marked with the 'FieldOffset' attribute
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1113)
+    static member ilFieldDoesNotHaveValidOffsetForStructureLayout(a0 : System.String, a1 : System.String) = (1206, GetStringFunc("ilFieldDoesNotHaveValidOffsetForStructureLayout",",,,%s,,,%s,,,") a0 a1)
+    /// Interfaces inherited by other interfaces should be declared using 'inherit ...' instead of 'interface ...'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1114)
+    static member tcInterfacesShouldUseInheritNotInterface() = (1207, GetStringFunc("tcInterfacesShouldUseInheritNotInterface",",,,") )
+    /// Invalid prefix operator
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1115)
+    static member parsInvalidPrefixOperator() = (1208, GetStringFunc("parsInvalidPrefixOperator",",,,") )
+    /// Invalid operator definition. Prefix operator definitions must use a valid prefix operator name.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1116)
+    static member parsInvalidPrefixOperatorDefinition() = (1208, GetStringFunc("parsInvalidPrefixOperatorDefinition",",,,") )
+    /// The file extensions '.ml' and '.mli' are for ML compatibility
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1117)
+    static member buildCompilingExtensionIsForML() = (GetStringFunc("buildCompilingExtensionIsForML",",,,") )
+    /// Consider using a file with extension '.ml' or '.mli' instead
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1118)
+    static member lexIndentOffForML() = (GetStringFunc("lexIndentOffForML",",,,") )
+    /// Active pattern '%s' is not a function
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1119)
+    static member activePatternIdentIsNotFunctionTyped(a0 : System.String) = (1209, GetStringFunc("activePatternIdentIsNotFunctionTyped",",,,%s,,,") a0)
+    /// Active pattern '%s' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice<int,unit> = A x'
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1120)
+    static member activePatternChoiceHasFreeTypars(a0 : System.String) = (1210, GetStringFunc("activePatternChoiceHasFreeTypars",",,,%s,,,") a0)
+    /// The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1121)
+    static member ilFieldHasOffsetForSequentialLayout() = (1211, GetStringFunc("ilFieldHasOffsetForSequentialLayout",",,,") )
+    /// Optional arguments must come at the end of the argument list, after any non-optional arguments
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1122)
+    static member tcOptionalArgsMustComeAfterNonOptionalArgs() = (1212, GetStringFunc("tcOptionalArgsMustComeAfterNonOptionalArgs",",,,") )
+    /// Attribute 'System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1123)
+    static member tcConditionalAttributeUsage() = (1213, GetStringFunc("tcConditionalAttributeUsage",",,,") )
+    /// Could not determine highest installed .NET framework version from Registry keys, using version 2.0
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1124)
+    static member monoRegistryBugWorkaround() = (1214, GetStringFunc("monoRegistryBugWorkaround",",,,") )
+    /// Extension members cannot provide operator overloads.  Consider defining the operator as part of the type definition instead.
+    /// (Originally from C:\fsharp\staging\src\fsharp\FSComp.txt:1125)
+    static member tcMemberOperatorDefinitionInExtrinsic() = (1215, GetStringFunc("tcMemberOperatorDefinitionInExtrinsic",",,,") )
+
+    /// Call this method once to validate that all known resources are valid; throws if not
+    static member RunStartupValidation() =
+        ignore(GetString("undefinedNameNamespace"))
+        ignore(GetString("undefinedNameNamespaceOrModule"))
+        ignore(GetString("undefinedNameFieldConstructorOrMember"))
+        ignore(GetString("undefinedNameValueConstructorNamespaceOrType"))
+        ignore(GetString("undefinedNameValueOfConstructor"))
+        ignore(GetString("undefinedNameValueNamespaceTypeOrModule"))
+        ignore(GetString("undefinedNameConstructorModuleOrNamespace"))
+        ignore(GetString("undefinedNameType"))
+        ignore(GetString("undefinedNameRecordLabelOrNamespace"))
+        ignore(GetString("undefinedNameRecordLabel"))
+        ignore(GetString("undefinedNameTypeParameter"))
+        ignore(GetString("undefinedNamePatternDiscriminator"))
+        ignore(GetString("buildUnexpectedTypeArgs"))
+        ignore(GetString("buildInvalidWarningNumber"))
+        ignore(GetString("buildInvalidVersionString"))
+        ignore(GetString("buildInvalidVersionFile"))
+        ignore(GetString("buildProductName"))
+        ignore(GetString("buildProblemWithFilename"))
+        ignore(GetString("buildNoInputsSpecified"))
+        ignore(GetString("buildMismatchOutputExtension"))
+        ignore(GetString("buildPdbRequiresDebug"))
+        ignore(GetString("buildInvalidSearchDirectory"))
+        ignore(GetString("buildSearchDirectoryNotFound"))
+        ignore(GetString("buildInvalidFilename"))
+        ignore(GetString("buildInvalidAssemblyName"))
+        ignore(GetString("buildInvalidPrivacy"))
+        ignore(GetString("buildMultipleReferencesNotAllowed"))
+        ignore(GetString("buildRequiresCLI2"))
+        ignore(GetString("buildCouldNotReadVersionInfoFromMscorlib"))
+        ignore(GetString("buildMscorlibAndReferencedAssemblyMismatch"))
+        ignore(GetString("buildCannotReadAssembly"))
+        ignore(GetString("buildMscorLibAndFSharpCoreMismatch"))
+        ignore(GetString("buildAssemblyResolutionFailed"))
+        ignore(GetString("buildImplicitModuleIsNotLegalIdentifier"))
+        ignore(GetString("buildMultiFileRequiresNamespaceOrModule"))
+        ignore(GetString("buildMultipleToplevelModules"))
+        ignore(GetString("buildUnknownFileSuffix"))
+        ignore(GetString("buildOptionRequiresParameter"))
+        ignore(GetString("buildCouldNotFindSourceFile"))
+        ignore(GetString("buildInvalidSourceFileExtension"))
+        ignore(GetString("buildCouldNotResolveAssembly"))
+        ignore(GetString("buildCouldNotResolveAssemblyRequiredByFile"))
+        ignore(GetString("buildErrorOpeningBinaryFile"))
+        ignore(GetString("buildDifferentVersionMustRecompile"))
+        ignore(GetString("buildInvalidHashIDirective"))
+        ignore(GetString("buildInvalidHashrDirective"))
+        ignore(GetString("buildInvalidHashloadDirective"))
+        ignore(GetString("buildInvalidHashtimeDirective"))
+        ignore(GetString("buildDirectivesInModulesAreIgnored"))
+        ignore(GetString("buildSignatureAlreadySpecified"))
+        ignore(GetString("buildImplementationAlreadyGivenDetail"))
+        ignore(GetString("buildImplementationAlreadyGiven"))
+        ignore(GetString("buildSignatureWithoutImplementation"))
+        ignore(GetString("buildArgInvalidInt"))
+        ignore(GetString("buildArgInvalidFloat"))
+        ignore(GetString("buildUnrecognizedOption"))
+        ignore(GetString("buildInvalidModuleOrNamespaceName"))
+        ignore(GetString("buildExplicitCoreLibRequiresNoFramework"))
+        ignore(GetString("buildDidNotExpectSigdataResource"))
+        ignore(GetString("buildExpectedSigdataFile"))
+        ignore(GetString("buildDidNotExpectOptDataResource"))
+        ignore(GetString("buildExpectedFileAlongSideFSharpCore"))
+        ignore(GetString("pickleErrorReadingWritingMetadata"))
+        ignore(GetString("tastTypeOrModuleNotConcrete"))
+        ignore(GetString("tastTypeHasAssemblyCodeRepresentation"))
+        ignore(GetString("tastNamespaceAndModuleWithSameNameInAssembly"))
+        ignore(GetString("tastTwoModulesWithSameNameInAssembly"))
+        ignore(GetString("tastDuplicateTypeDefinitionInAssembly"))
+        ignore(GetString("tastConflictingModuleAndTypeDefinitionInAssembly"))
+        ignore(GetString("tastInvalidMemberSignature"))
+        ignore(GetString("tastValueDoesNotHaveSetterType"))
+        ignore(GetString("tastInvalidFormForPropertyGetter"))
+        ignore(GetString("tastInvalidFormForPropertySetter"))
+        ignore(GetString("tastUnexpectedByRef"))
+        ignore(GetString("tastValueMustBeLocalAndMutable"))
+        ignore(GetString("tastInvalidMutationOfConstant"))
+        ignore(GetString("tastValueHasBeenCopied"))
+        ignore(GetString("tastRecursiveValuesMayNotBeInConstructionOfTuple"))
+        ignore(GetString("tastRecursiveValuesMayNotAppearInConstructionOfType"))
+        ignore(GetString("tastRecursiveValuesMayNotBeAssignedToNonMutableField"))
+        ignore(GetString("tastUnexpectedDecodeOfAutoOpenAttribute"))
+        ignore(GetString("tastUnexpectedDecodeOfInternalsVisibleToAttribute"))
+        ignore(GetString("tastUnexpectedDecodeOfInterfaceDataVersionAttribute"))
+        ignore(GetString("tastActivePatternsLimitedToSeven"))
+        ignore(GetString("tastConstantCannotBeCustomAttribute"))
+        ignore(GetString("tastNotAConstantExpression"))
+        ignore(GetString("ValueNotContainedMutabilityAttributesDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityNamesDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityCompiledNamesDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityDisplayNamesDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityAccessibilityMore"))
+        ignore(GetString("ValueNotContainedMutabilityInlineFlagsDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityLiteralConstantValuesDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityOneIsTypeFunction"))
+        ignore(GetString("ValueNotContainedMutabilityParameterCountsDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityTypesDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityExtensionsDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityArityNotInferred"))
+        ignore(GetString("ValueNotContainedMutabilityGenericParametersDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityGenericParametersAreDifferentKinds"))
+        ignore(GetString("ValueNotContainedMutabilityAritiesDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityDotNetNamesDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityStaticsDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityVirtualsDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityAbstractsDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityFinalsDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityOverridesDiffer"))
+        ignore(GetString("ValueNotContainedMutabilityOneIsConstructor"))
+        ignore(GetString("ValueNotContainedMutabilityStaticButInstance"))
+        ignore(GetString("ValueNotContainedMutabilityInstanceButStatic"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleNamesDiffer"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleParameterCountsDiffer"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleAccessibilityDiffer"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleMissingInterface"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleImplementationSaysNull"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleImplementationSaysNull2"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleSignatureSaysNull"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleSignatureSaysNull2"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleImplementationSealed"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleImplementationIsNotSealed"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleImplementationIsAbstract"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleSignatureIsAbstract"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleTypesHaveDifferentBaseTypes"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleNumbersDiffer"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleSignatureDefinesButImplDoesNot"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleImplDefinesButSignatureDoesNot"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleImplDefinesStruct"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleDotNetTypeRepresentationIsHidden"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleTypeIsHidden"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleTypeIsDifferentKind"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleILDiffer"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleRepresentationsDiffer"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleFieldWasPresent"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleFieldOrderDiffer"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleFieldRequiredButNotSpecified"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleFieldIsInImplButNotSig"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInImpl"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInSig"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleSignatureDeclaresDiffer"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleAbbreviationsDiffer"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleAbbreviationHiddenBySig"))
+        ignore(GetString("DefinitionsInSigAndImplNotCompatibleSigHasAbbreviation"))
+        ignore(GetString("ModuleContainsConstructorButNamesDiffer"))
+        ignore(GetString("ModuleContainsConstructorButDataFieldsDiffer"))
+        ignore(GetString("ModuleContainsConstructorButTypesOfFieldsDiffer"))
+        ignore(GetString("ModuleContainsConstructorButAccessibilityDiffers"))
+        ignore(GetString("FieldNotContainedNamesDiffer"))
+        ignore(GetString("FieldNotContainedAccessibilitiesDiffer"))
+        ignore(GetString("FieldNotContainedStaticsDiffer"))
+        ignore(GetString("FieldNotContainedMutablesDiffer"))
+        ignore(GetString("FieldNotContainedLiteralsDiffer"))
+        ignore(GetString("FieldNotContainedTypesDiffer"))
+        ignore(GetString("typrelCannotResolveImplicitGenericInstantiation"))
+        ignore(GetString("typrelCannotResolveAmbiguityInOverloadedOperator"))
+        ignore(GetString("typrelCannotResolveAmbiguityInPrintf"))
+        ignore(GetString("typrelCannotResolveAmbiguityInEnum"))
+        ignore(GetString("typrelCannotResolveAmbiguityInDelegate"))
+        ignore(GetString("typrelInvalidValue"))
+        ignore(GetString("typrelSigImplNotCompatibleParamCountsDiffer"))
+        ignore(GetString("typrelSigImplNotCompatibleCompileTimeRequirementsDiffer"))
+        ignore(GetString("typrelSigImplNotCompatibleConstraintsDiffer"))
+        ignore(GetString("typrelSigImplNotCompatibleConstraintsDifferRemove"))
+        ignore(GetString("typrelTypeImplementsIComparableShouldOverrideObjectEquals"))
+        ignore(GetString("typrelTypeImplementsIComparableDefaultObjectEqualsProvided"))
+        ignore(GetString("typrelExplicitImplementationOfGetHashCodeOrEquals"))
+        ignore(GetString("typrelExplicitImplementationOfGetHashCode"))
+        ignore(GetString("typrelExplicitImplementationOfEquals"))
+        ignore(GetString("ExceptionDefsNotCompatibleHiddenBySignature"))
+        ignore(GetString("ExceptionDefsNotCompatibleDotNetRepresentationsDiffer"))
+        ignore(GetString("ExceptionDefsNotCompatibleAbbreviationHiddenBySignature"))
+        ignore(GetString("ExceptionDefsNotCompatibleSignaturesDiffer"))
+        ignore(GetString("ExceptionDefsNotCompatibleExceptionDeclarationsDiffer"))
+        ignore(GetString("ExceptionDefsNotCompatibleFieldInSigButNotImpl"))
+        ignore(GetString("ExceptionDefsNotCompatibleFieldInImplButNotSig"))
+        ignore(GetString("ExceptionDefsNotCompatibleFieldOrderDiffers"))
+        ignore(GetString("typrelModuleNamespaceAttributesDifferInSigAndImpl"))
+        ignore(GetString("typrelMethodIsOverconstrained"))
+        ignore(GetString("typrelOverloadNotFound"))
+        ignore(GetString("typrelOverrideWasAmbiguous"))
+        ignore(GetString("typrelMoreThenOneOverride"))
+        ignore(GetString("typrelMethodIsSealed"))
+        ignore(GetString("typrelOverrideImplementsMoreThenOneSlot"))
+        ignore(GetString("typrelDuplicateInterface"))
+        ignore(GetString("typrelNeedExplicitImplementation"))
+        ignore(GetString("typrelNamedArgumentHasBeenAssignedMoreThenOnce"))
+        ignore(GetString("typrelNoImplementationGiven"))
+        ignore(GetString("typrelNoImplementationGivenWithSuggestion"))
+        ignore(GetString("typrelMemberDoesNotHaveCorrectNumberOfArguments"))
+        ignore(GetString("typrelMemberDoesNotHaveCorrectNumberOfTypeParameters"))
+        ignore(GetString("typrelMemberDoesNotHaveCorrectKindsOfGenericParameters"))
+        ignore(GetString("typrelMemberCannotImplement"))
+        ignore(GetString("astParseEmbeddedILError"))
+        ignore(GetString("astParseEmbeddedILTypeError"))
+        ignore(GetString("astDeprecatedIndexerNotation"))
+        ignore(GetString("astInvalidExprLeftHandOfAssignment"))
+        ignore(GetString("augNoRefEqualsOnStruct"))
+        ignore(GetString("augInvalidAttrs"))
+        ignore(GetString("augNoEqualityNeedsNoComparison"))
+        ignore(GetString("augStructCompNeedsStructEquality"))
+        ignore(GetString("augStructEqNeedsNoCompOrStructComp"))
+        ignore(GetString("augTypeCantHaveRefEqAndStructAttrs"))
+        ignore(GetString("augOnlyCertainTypesCanHaveAttrs"))
+        ignore(GetString("augRefEqCantHaveObjEquals"))
+        ignore(GetString("augCustomEqNeedsObjEquals"))
+        ignore(GetString("augCustomCompareNeedsIComp"))
+        ignore(GetString("augNoEqNeedsNoObjEquals"))
+        ignore(GetString("augNoCompCantImpIComp"))
+        ignore(GetString("augCustomEqNeedsNoCompOrCustomComp"))
+        ignore(GetString("forPositionalSpecifiersNotPermitted"))
+        ignore(GetString("forMissingFormatSpecifier"))
+        ignore(GetString("forFlagSetTwice"))
+        ignore(GetString("forPrefixFlagSpacePlusSetTwice"))
+        ignore(GetString("forHashSpecifierIsInvalid"))
+        ignore(GetString("forBadPrecision"))
+        ignore(GetString("forBadWidth"))
+        ignore(GetString("forDoesNotSupportZeroFlag"))
+        ignore(GetString("forPrecisionMissingAfterDot"))
+        ignore(GetString("forFormatDoesntSupportPrecision"))
+        ignore(GetString("forBadFormatSpecifier"))
+        ignore(GetString("forLIsUnnecessary"))
+        ignore(GetString("forHIsUnnecessary"))
+        ignore(GetString("forDoesNotSupportPrefixFlag"))
+        ignore(GetString("forBadFormatSpecifierGeneral"))
+        ignore(GetString("elSysEnvExitDidntExit"))
+        ignore(GetString("elDeprecatedOperator"))
+        ignore(GetString("chkProtectedOrBaseCalled"))
+        ignore(GetString("chkByrefUsedInInvalidWay"))
+        ignore(GetString("chkMutableUsedInInvalidWay"))
+        ignore(GetString("chkBaseUsedInInvalidWay"))
+        ignore(GetString("chkVariableUsedInInvalidWay"))
+        ignore(GetString("chkTypeLessAccessibleThanType"))
+        ignore(GetString("chkSystemVoidOnlyInTypeof"))
+        ignore(GetString("chkErrorUseOfByref"))
+        ignore(GetString("chkErrorContainsCallToRethrow"))
+        ignore(GetString("chkSplicingOnlyInQuotations"))
+        ignore(GetString("chkNoFirstClassSplicing"))
+        ignore(GetString("chkNoFirstClassAddressOf"))
+        ignore(GetString("chkNoFirstClassRethrow"))
+        ignore(GetString("chkNoByrefAtThisPoint"))
+        ignore(GetString("chkLimitationsOfBaseKeyword"))
+        ignore(GetString("chkObjCtorsCantUseExceptionHandling"))
+        ignore(GetString("chkNoAddressOfAtThisPoint"))
+        ignore(GetString("chkNoAddressStaticFieldAtThisPoint"))
+        ignore(GetString("chkNoAddressFieldAtThisPoint"))
+        ignore(GetString("chkNoAddressOfArrayElementAtThisPoint"))
+        ignore(GetString("chkFirstClassFuncNoByref"))
+        ignore(GetString("chkReturnTypeNoByref"))
+        ignore(GetString("chkInvalidCustAttrVal"))
+        ignore(GetString("chkAttrHasAllowMultiFalse"))
+        ignore(GetString("chkMemberUsedInInvalidWay"))
+        ignore(GetString("chkNoByrefAsTopValue"))
+        ignore(GetString("chkReflectedDefCantSplice"))
+        ignore(GetString("chkEntryPointUsage"))
+        ignore(GetString("chkUnionCaseCompiledForm"))
+        ignore(GetString("chkUnionCaseDefaultAugmentation"))
+        ignore(GetString("chkPropertySameNameMethod"))
+        ignore(GetString("chkGetterSetterDoNotMatchAbstract"))
+        ignore(GetString("chkPropertySameNameIndexer"))
+        ignore(GetString("chkCantStoreByrefValue"))
+        ignore(GetString("chkDuplicateMethod"))
+        ignore(GetString("chkDuplicateMethodWithSuffix"))
+        ignore(GetString("chkDuplicateMethodCurried"))
+        ignore(GetString("chkCurriedMethodsCantHaveOutParams"))
+        ignore(GetString("chkDuplicateProperty"))
+        ignore(GetString("chkDuplicatePropertyWithSuffix"))
+        ignore(GetString("chkDuplicateMethodInheritedType"))
+        ignore(GetString("chkDuplicateMethodInheritedTypeWithSuffix"))
+        ignore(GetString("chkMultipleGenericInterfaceInstantiations"))
+        ignore(GetString("chkValueWithDefaultValueMustHaveDefaultValue"))
+        ignore(GetString("chkNoByrefInTypeAbbrev"))
+        ignore(GetString("crefBoundVarUsedInSplice"))
+        ignore(GetString("crefQuotationsCantContainGenericExprs"))
+        ignore(GetString("crefQuotationsCantContainGenericFunctions"))
+        ignore(GetString("crefQuotationsCantContainObjExprs"))
+        ignore(GetString("crefQuotationsCantContainAddressOf"))
+        ignore(GetString("crefQuotationsCantContainStaticFieldRef"))
+        ignore(GetString("crefQuotationsCantContainInlineIL"))
+        ignore(GetString("crefQuotationsCantContainDescendingForLoops"))
+        ignore(GetString("crefQuotationsCantFetchUnionIndexes"))
+        ignore(GetString("crefQuotationsCantSetUnionFields"))
+        ignore(GetString("crefQuotationsCantSetExceptionFields"))
+        ignore(GetString("crefQuotationsCantRequireByref"))
+        ignore(GetString("crefQuotationsCantCallTraitMembers"))
+        ignore(GetString("crefQuotationsCantContainThisConstant"))
+        ignore(GetString("crefQuotationsCantContainThisPatternMatch"))
+        ignore(GetString("crefQuotationsCantContainArrayPatternMatching"))
+        ignore(GetString("crefQuotationsCantContainThisType"))
+        ignore(GetString("crefQuotationsCantContainLiteralByteArrays"))
+        ignore(GetString("crefNoInnerGenericsInQuotations"))
+        ignore(GetString("csTypeCannotBeResolvedAtCompileTime"))
+        ignore(GetString("csCodeLessGeneric"))
+        ignore(GetString("csTypeInferenceMaxDepth"))
+        ignore(GetString("csExpectedArguments"))
+        ignore(GetString("csIndexArgumentMismatch"))
+        ignore(GetString("csExpectTypeWithOperatorButGivenFunction"))
+        ignore(GetString("csTypeDoesNotSupportOperator"))
+        ignore(GetString("csTypeDoesNotSupportConversion"))
+        ignore(GetString("csMethodFoundButIsStatic"))
+        ignore(GetString("csMethodFoundButIsNotStatic"))
+        ignore(GetString("csStructConstraintInconsistent"))
+        ignore(GetString("csTypeDoesNotHaveNull"))
+        ignore(GetString("csTypeDoesNotSupportComparison1"))
+        ignore(GetString("csTypeDoesNotSupportComparison2"))
+        ignore(GetString("csTypeDoesNotSupportComparison3"))
+        ignore(GetString("csTypeDoesNotSupportEquality1"))
+        ignore(GetString("csTypeDoesNotSupportEquality2"))
+        ignore(GetString("csTypeDoesNotSupportEquality3"))
+        ignore(GetString("csTypeIsNotEnumType"))
+        ignore(GetString("csTypeHasNonStandardDelegateType"))
+        ignore(GetString("csTypeIsNotDelegateType"))
+        ignore(GetString("csTypeParameterCannotBeNullable"))
+        ignore(GetString("csGenericConstructRequiresStructType"))
+        ignore(GetString("csGenericConstructRequiresUnmanagedType"))
+        ignore(GetString("csTypeNotCompatibleBecauseOfPrintf"))
+        ignore(GetString("csGenericConstructRequiresReferenceSemantics"))
+        ignore(GetString("csGenericConstructRequiresNonAbstract"))
+        ignore(GetString("csGenericConstructRequiresPublicDefaultConstructor"))
+        ignore(GetString("csTypeInstantiationLengthMismatch"))
+        ignore(GetString("csOptionalArgumentNotPermittedHere"))
+        ignore(GetString("csMemberIsNotStatic"))
+        ignore(GetString("csMemberIsNotInstance"))
+        ignore(GetString("csArgumentLengthMismatch"))
+        ignore(GetString("csArgumentTypesDoNotMatch"))
+        ignore(GetString("csMethodExpectsParams"))
+        ignore(GetString("csMemberIsNotAccessible"))
+        ignore(GetString("csMemberIsNotAccessible2"))
+        ignore(GetString("csMethodIsNotAStaticMethod"))
+        ignore(GetString("csMethodIsNotAnInstanceMethod"))
+        ignore(GetString("csMemberHasNoArgumentOrReturnProperty"))
+        ignore(GetString("csRequiredSignatureIs"))
+        ignore(GetString("csMemberSignatureMismatch"))
+        ignore(GetString("csMemberSignatureMismatch2"))
+        ignore(GetString("csMemberSignatureMismatch3"))
+        ignore(GetString("csMemberSignatureMismatch4"))
+        ignore(GetString("csMemberSignatureMismatchArityNamed"))
+        ignore(GetString("csMemberSignatureMismatchArity"))
+        ignore(GetString("csMemberSignatureMismatchArityType"))
+        ignore(GetString("csMemberNotAccessible"))
+        ignore(GetString("csIncorrectGenericInstantiation"))
+        ignore(GetString("csMemberOverloadArityMismatch"))
+        ignore(GetString("csNoMemberTakesTheseArguments"))
+        ignore(GetString("csNoMemberTakesTheseArguments2"))
+        ignore(GetString("csNoMemberTakesTheseArguments3"))
+        ignore(GetString("csMethodNotFound"))
+        ignore(GetString("csNoOverloadsFound"))
+        ignore(GetString("csMethodIsOverloaded"))
+        ignore(GetString("parsDoCannotHaveVisibilityDeclarations"))
+        ignore(GetString("parsEofInHashIf"))
+        ignore(GetString("parsEofInString"))
+        ignore(GetString("parsEofInVerbatimString"))
+        ignore(GetString("parsEofInComment"))
+        ignore(GetString("parsEofInStringInComment"))
+        ignore(GetString("parsEofInVerbatimStringInComment"))
+        ignore(GetString("parsEofInIfOcaml"))
+        ignore(GetString("parsEofInDirective"))
+        ignore(GetString("parsNoHashEndIfFound"))
+        ignore(GetString("parsAttributesIgnored"))
+        ignore(GetString("parsUseBindingsIllegalInImplicitClassConstructors"))
+        ignore(GetString("parsUseBindingsIllegalInModules"))
+        ignore(GetString("parsIntegerForLoopRequiresSimpleIdentifier"))
+        ignore(GetString("parsOnlyOneWithAugmentationAllowed"))
+        ignore(GetString("parsUnexpectedSemicolon"))
+        ignore(GetString("parsUnexpectedEndOfFile"))
+        ignore(GetString("parsUnexpectedVisibilityDeclaration"))
+        ignore(GetString("parsOnlyHashDirectivesAllowed"))
+        ignore(GetString("parsVisibilityDeclarationsShouldComePriorToIdentifier"))
+        ignore(GetString("parsNamespaceOrModuleNotBoth"))
+        ignore(GetString("parsModuleAbbreviationMustBeSimpleName"))
+        ignore(GetString("parsIgnoreAttributesOnModuleAbbreviation"))
+        ignore(GetString("parsIgnoreAttributesOnModuleAbbreviationAlwaysPrivate"))
+        ignore(GetString("parsIgnoreVisibilityOnModuleAbbreviationAlwaysPrivate"))
+        ignore(GetString("parsUnClosedBlockInHashLight"))
+        ignore(GetString("parsUnmatchedBeginOrStruct"))
+        ignore(GetString("parsModuleDefnMustBeSimpleName"))
+        ignore(GetString("parsUnexpectedEmptyModuleDefn"))
+        ignore(GetString("parsAttributesMustComeBeforeVal"))
+        ignore(GetString("parsAttributesAreNotPermittedOnInterfaceImplementations"))
+        ignore(GetString("parsSyntaxError"))
+        ignore(GetString("parsAugmentationsIllegalOnDelegateType"))
+        ignore(GetString("parsUnmatchedClassInterfaceOrStruct"))
+        ignore(GetString("parsEmptyTypeDefinition"))
+        ignore(GetString("parsUnmatchedWith"))
+        ignore(GetString("parsGetOrSetRequired"))
+        ignore(GetString("parsOnlyClassCanTakeValueArguments"))
+        ignore(GetString("parsUnmatchedBegin"))
+        ignore(GetString("parsInvalidDeclarationSyntax"))
+        ignore(GetString("parsGetAndOrSetRequired"))
+        ignore(GetString("parsTypeAnnotationsOnGetSet"))
+        ignore(GetString("parsGetterMustHaveAtLeastOneArgument"))
+        ignore(GetString("parsMultipleAccessibilitiesForGetSet"))
+        ignore(GetString("parsSetSyntax"))
+        ignore(GetString("parsInterfacesHaveSameVisibilityAsEnclosingType"))
+        ignore(GetString("parsAccessibilityModsIllegalForAbstract"))
+        ignore(GetString("parsAttributesIllegalOnInherit"))
+        ignore(GetString("parsVisibilityIllegalOnInherit"))
+        ignore(GetString("parsInheritDeclarationsCannotHaveAsBindings"))
+        ignore(GetString("parsAttributesIllegalHere"))
+        ignore(GetString("parsTypeAbbreviationsCannotHaveVisibilityDeclarations"))
+        ignore(GetString("parsEnumTypesCannotHaveVisibilityDeclarations"))
+        ignore(GetString("parsAllEnumFieldsRequireValues"))
+        ignore(GetString("parsInlineAssemblyCannotHaveVisibilityDeclarations"))
+        ignore(GetString("parsUnexpectedIdentifier"))
+        ignore(GetString("parsUnionCasesCannotHaveVisibilityDeclarations"))
+        ignore(GetString("parsEnumFieldsCannotHaveVisibilityDeclarations"))
+        ignore(GetString("parsConsiderUsingSeparateRecordType"))
+        ignore(GetString("parsRecordFieldsCannotHaveVisibilityDeclarations"))
+        ignore(GetString("parsLetAndForNonRecBindings"))
+        ignore(GetString("parsUnmatchedLetOrDo"))
+        ignore(GetString("parsUnmatchedParen"))
+        ignore(GetString("parsSuccessivePatternsShouldBeSpacedOrTupled"))
+        ignore(GetString("parsNoMatchingInForLet"))
+        ignore(GetString("parsErrorInReturnForLetIncorrectIndentation"))
+        ignore(GetString("parsExpectedStatementAfterLet"))
+        ignore(GetString("parsUnmatchedIf"))
+        ignore(GetString("parsAssertIsNotFirstClassValue"))
+        ignore(GetString("parsDoneExpected"))
+        ignore(GetString("parsDoExpected"))
+        ignore(GetString("parsUnclosedFor"))
+        ignore(GetString("parsIdentifierExpected"))
+        ignore(GetString("parsEqualExpected"))
+        ignore(GetString("parsArrowUseIsLimited"))
+        ignore(GetString("parsSuccessiveArgsShouldBeSpacedOrTupled"))
+        ignore(GetString("parsUnmatchedBracket"))
+        ignore(GetString("parsMissingQualificationAfterDot"))
+        ignore(GetString("parsParenFormIsForML"))
+        ignore(GetString("parsMismatchedQuote"))
+        ignore(GetString("parsUnmatched"))
+        ignore(GetString("parsUnmatchedBracketBar"))
+        ignore(GetString("parsUnmatchedBrace"))
+        ignore(GetString("parsFieldBinding"))
+        ignore(GetString("parsMemberIllegalInObjectImplementation"))
+        ignore(GetString("parsMissingFunctionBody"))
+        ignore(GetString("parsErrorInFunctionBlock"))
+        ignore(GetString("parsSyntaxErrorInLabeledType"))
+        ignore(GetString("parsUnexpectedInfixOperator"))
+        ignore(GetString("parsMultiArgumentGenericTypeFormDeprecated"))
+        ignore(GetString("parsUnexpectedIntegerLiteral"))
+        ignore(GetString("parsUnexpectedOperatorForUnitOfMeasure"))
+        ignore(GetString("parsUnexpectedIntegerLiteralForUnitOfMeasure"))
+        ignore(GetString("parsUnexpectedTypeParameter"))
+        ignore(GetString("parsMismatchedQuotationName"))
+        ignore(GetString("parsActivePatternCaseMustBeginWithUpperCase"))
+        ignore(GetString("parsNoEqualShouldFollowNamespace"))
+        ignore(GetString("parsSyntaxModuleStructEndDeprecated"))
+        ignore(GetString("parsSyntaxModuleSigEndDeprecated"))
+        ignore(GetString("tcStaticFieldUsedWhenInstanceFieldExpected"))
+        ignore(GetString("tcMethodNotAccessible"))
+        ignore(GetString("tcTypeFunctionFieldsCannotBeMutated"))
+        ignore(GetString("tcImplicitMeasureFollowingSlash"))
+        ignore(GetString("tcUnexpectedMeasureAnon"))
+        ignore(GetString("tcNonZeroConstantCannotHaveGenericUnit"))
+        ignore(GetString("tcSeqResultsUseYield"))
+        ignore(GetString("tcUnexpectedBigRationalConstant"))
+        ignore(GetString("tcInvalidTypeForUnitsOfMeasure"))
+        ignore(GetString("tcUnexpectedConstUint16Array"))
+        ignore(GetString("tcUnexpectedConstByteArray"))
+        ignore(GetString("tcParameterRequiresName"))
+        ignore(GetString("tcReturnValuesCannotHaveNames"))
+        ignore(GetString("tcMemberKindPropertyGetSetNotExpected"))
+        ignore(GetString("tcNamespaceCannotContainValues"))
+        ignore(GetString("tcNamespaceCannotContainExtensionMembers"))
+        ignore(GetString("tcMultipleVisibilityAttributes"))
+        ignore(GetString("tcMultipleVisibilityAttributesWithLet"))
+        ignore(GetString("tcUnrecognizedAccessibilitySpec"))
+        ignore(GetString("tcInvalidMethodNameForRelationalOperator"))
+        ignore(GetString("tcInvalidMethodNameForEquality"))
+        ignore(GetString("tcInvalidMemberName"))
+        ignore(GetString("tcInvalidMemberNameFixedTypes"))
+        ignore(GetString("tcInvalidOperatorDefinitionRelational"))
+        ignore(GetString("tcInvalidOperatorDefinitionEquality"))
+        ignore(GetString("tcInvalidOperatorDefinition"))
+        ignore(GetString("tcInvalidIndexOperatorDefinition"))
+        ignore(GetString("tcExpectModuleOrNamespaceParent"))
+        ignore(GetString("tcImplementsIComparableExplicitly"))
+        ignore(GetString("tcImplementsGenericIComparableExplicitly"))
+        ignore(GetString("tcImplementsIStructuralComparableExplicitly"))
+        ignore(GetString("tcRecordFieldInconsistentTypes"))
+        ignore(GetString("tcDllImportStubsCannotBeInlined"))
+        ignore(GetString("tcStructsCanOnlyBindThisAtMemberDeclaration"))
+        ignore(GetString("tcUnexpectedExprAtRecInfPoint"))
+        ignore(GetString("tcLessGenericBecauseOfAnnotation"))
+        ignore(GetString("tcConstrainedTypeVariableCannotBeGeneralized"))
+        ignore(GetString("tcGenericParameterHasBeenConstrained"))
+        ignore(GetString("tcTypeParameterHasBeenConstrained"))
+        ignore(GetString("tcTypeParametersInferredAreNotStable"))
+        ignore(GetString("tcExplicitTypeParameterInvalid"))
+        ignore(GetString("tcOverridingMethodRequiresAllOrNoTypeParameters"))
+        ignore(GetString("tcFieldsDoNotDetermineUniqueRecordType"))
+        ignore(GetString("tcFieldAppearsTwiceInRecord"))
+        ignore(GetString("tcUnknownUnion"))
+        ignore(GetString("tcNotSufficientlyGenericBecauseOfScope"))
+        ignore(GetString("tcPropertyRequiresExplicitTypeParameters"))
+        ignore(GetString("tcConstructorCannotHaveTypeParameters"))
+        ignore(GetString("tcInstanceMemberRequiresTarget"))
+        ignore(GetString("tcUnexpectedPropertyInSyntaxTree"))
+        ignore(GetString("tcStaticInitializerRequiresArgument"))
+        ignore(GetString("tcObjectConstructorRequiresArgument"))
+        ignore(GetString("tcStaticMemberShouldNotHaveThis"))
+        ignore(GetString("tcExplicitStaticInitializerSyntax"))
+        ignore(GetString("tcExplicitObjectConstructorSyntax"))
+        ignore(GetString("tcUnexpectedPropertySpec"))
+        ignore(GetString("tcObjectExpressionFormDeprecated"))
+        ignore(GetString("tcInvalidDeclaration"))
+        ignore(GetString("tcAttributesInvalidInPatterns"))
+        ignore(GetString("tcFunctionRequiresExplicitTypeArguments"))
+        ignore(GetString("tcDoesNotAllowExplicitTypeArguments"))
+        ignore(GetString("tcTypeParameterArityMismatch"))
+        ignore(GetString("tcDefaultStructConstructorCall"))
+        ignore(GetString("tcCouldNotFindIDisposable"))
+        ignore(GetString("tcNonLiteralCannotBeUsedInPattern"))
+        ignore(GetString("tcFieldIsReadonly"))
+        ignore(GetString("tcNameArgumentsMustAppearLast"))
+        ignore(GetString("tcFunctionRequiresExplicitLambda"))
+        ignore(GetString("tcTypeCannotBeEnumerated"))
+        ignore(GetString("tcBadReturnTypeForGetEnumerator"))
+        ignore(GetString("tcInvalidMixtureOfRecursiveForms"))
+        ignore(GetString("tcInvalidObjectConstructionExpression"))
+        ignore(GetString("tcInvalidConstraint"))
+        ignore(GetString("tcInvalidConstraintTypeSealed"))
+        ignore(GetString("tcInvalidEnumConstraint"))
+        ignore(GetString("tcInvalidNewConstraint"))
+        ignore(GetString("tcInvalidPropertyType"))
+        ignore(GetString("tcExpectedUnitOfMeasureMarkWithAttribute"))
+        ignore(GetString("tcExpectedTypeParameter"))
+        ignore(GetString("tcExpectedTypeNotUnitOfMeasure"))
+        ignore(GetString("tcExpectedUnitOfMeasureNotType"))
+        ignore(GetString("tcInvalidUnitsOfMeasurePrefix"))
+        ignore(GetString("tcUnitsOfMeasureInvalidInTypeConstructor"))
+        ignore(GetString("tcRequireBuilderMethod"))
+        ignore(GetString("tcTypeHasNoNestedTypes"))
+        ignore(GetString("tcUnexpectedSymbolInTypeExpression"))
+        ignore(GetString("tcTypeParameterInvalidAsTypeConstructor"))
+        ignore(GetString("tcIllegalSyntaxInTypeExpression"))
+        ignore(GetString("tcAnonymousUnitsOfMeasureCannotBeNested"))
+        ignore(GetString("tcAnonymousTypeInvalidInDeclaration"))
+        ignore(GetString("tcUnexpectedSlashInType"))
+        ignore(GetString("tcUnexpectedTypeArguments"))
+        ignore(GetString("tcOptionalArgsOnlyOnMembers"))
+        ignore(GetString("tcNameNotBoundInPattern"))
+        ignore(GetString("tcInvalidNonPrimitiveLiteralInPatternMatch"))
+        ignore(GetString("tcInvalidTypeArgumentUsage"))
+        ignore(GetString("tcRequireActivePatternWithOneResult"))
+        ignore(GetString("tcInvalidArgForParameterizedPattern"))
+        ignore(GetString("tcInvalidIndexIntoActivePatternArray"))
+        ignore(GetString("tcUnionCaseDoesNotTakeArguments"))
+        ignore(GetString("tcUnionCaseRequiresOneArgument"))
+        ignore(GetString("tcUnionCaseExpectsTupledArguments"))
+        ignore(GetString("tcFieldIsNotStatic"))
+        ignore(GetString("tcFieldNotLiteralCannotBeUsedInPattern"))
+        ignore(GetString("tcRequireVarConstRecogOrLiteral"))
+        ignore(GetString("tcInvalidPattern"))
+        ignore(GetString("tcUseWhenPatternGuard"))
+        ignore(GetString("tcIllegalPattern"))
+        ignore(GetString("tcSyntaxErrorUnexpectedQMark"))
+        ignore(GetString("tcExpressionCountMisMatch"))
+        ignore(GetString("tcExprUndelayed"))
+        ignore(GetString("tcExpressionRequiresSequence"))
+        ignore(GetString("tcInvalidObjectExpressionSyntaxForm"))
+        ignore(GetString("tcInvalidObjectSequenceOrRecordExpression"))
+        ignore(GetString("tcInvalidSequenceExpressionSyntaxForm"))
+        ignore(GetString("tcExpressionWithIfRequiresParenthesis"))
+        ignore(GetString("tcUnableToParseFormatString"))
+        ignore(GetString("tcListLiteralMaxSize"))
+        ignore(GetString("tcExpressionFormRequiresObjectConstructor"))
+        ignore(GetString("tcNamedArgumentsCannotBeUsedInMemberTraits"))
+        ignore(GetString("tcUseTypeOf"))
+        ignore(GetString("tcNotValidEnumCaseName"))
+        ignore(GetString("tcFieldIsNotMutable"))
+        ignore(GetString("tcConstructRequiresListArrayOrSequence"))
+        ignore(GetString("tcConstructRequiresComputationExpressions"))
+        ignore(GetString("tcConstructRequiresSequenceOrComputations"))
+        ignore(GetString("tcConstructRequiresComputationExpression"))
+        ignore(GetString("tcInvalidIndexerExpression"))
+        ignore(GetString("tcObjectOfIndeterminateTypeUsedRequireTypeConstraint"))
+        ignore(GetString("tcCannotInheritFromVariableType"))
+        ignore(GetString("tcObjectConstructorsOnTypeParametersCannotTakeArguments"))
+        ignore(GetString("tcCompiledNameAttributeMisused"))
+        ignore(GetString("tcNamedTypeRequired"))
+        ignore(GetString("tcInheritCannotBeUsedOnInterfaceType"))
+        ignore(GetString("tcNewCannotBeUsedOnInterfaceType"))
+        ignore(GetString("tcAbstractTypeCannotBeInstantiated"))
+        ignore(GetString("tcIDisposableTypeShouldUseNew"))
+        ignore(GetString("tcSyntaxCanOnlyBeUsedToCreateObjectTypes"))
+        ignore(GetString("tcConstructorRequiresCall"))
+        ignore(GetString("tcUndefinedField"))
+        ignore(GetString("tcFieldRequiresAssignment"))
+        ignore(GetString("tcExtraneousFieldsGivenValues"))
+        ignore(GetString("tcObjectExpressionsCanOnlyOverrideAbstractOrVirtual"))
+        ignore(GetString("tcNoAbstractOrVirtualMemberFound"))
+        ignore(GetString("tcArgumentArityMismatch"))
+        ignore(GetString("tcArgumentArityMismatchOneOverload"))
+        ignore(GetString("tcSimpleMethodNameRequired"))
+        ignore(GetString("tcPredefinedTypeCannotBeUsedAsSuperType"))
+        ignore(GetString("tcNewMustBeUsedWithNamedType"))
+        ignore(GetString("tcCannotCreateExtensionOfSealedType"))
+        ignore(GetString("tcNoArgumentsForRecordValue"))
+        ignore(GetString("tcNoInterfaceImplementationForConstructionExpression"))
+        ignore(GetString("tcObjectConstructionCanOnlyBeUsedInClassTypes"))
+        ignore(GetString("tcOnlySimpleBindingsCanBeUsedInConstructionExpressions"))
+        ignore(GetString("tcObjectsMustBeInitializedWithObjectExpression"))
+        ignore(GetString("tcExpectedInterfaceType"))
+        ignore(GetString("tcConstructorForInterfacesDoNotTakeArguments"))
+        ignore(GetString("tcConstructorRequiresArguments"))
+        ignore(GetString("tcNewRequiresObjectConstructor"))
+        ignore(GetString("tcAtLeastOneOverrideIsInvalid"))
+        ignore(GetString("tcNumericLiteralRequiresModule"))
+        ignore(GetString("tcInvalidRecordConstruction"))
+        ignore(GetString("tcExpressionFormRequiresRecordTypes"))
+        ignore(GetString("tcInheritedTypeIsNotObjectModelType"))
+        ignore(GetString("tcObjectConstructionExpressionCanOnlyImplementConstructorsInObjectModelTypes"))
+        ignore(GetString("tcEmptyRecordInvalid"))
+        ignore(GetString("tcTypeIsNotARecordTypeNeedConstructor"))
+        ignore(GetString("tcTypeIsNotARecordType"))
+        ignore(GetString("tcConstructIsAmbiguousInComputationExpression"))
+        ignore(GetString("tcConstructIsAmbiguousInSequenceExpression"))
+        ignore(GetString("tcDoBangIllegalInSequenceExpression"))
+        ignore(GetString("tcUseForInSequenceExpression"))
+        ignore(GetString("tcTryIllegalInSequenceExpression"))
+        ignore(GetString("tcUseYieldBangForMultipleResults"))
+        ignore(GetString("tcUnexpectedTypeApplication"))
+        ignore(GetString("tcInvalidAssignment"))
+        ignore(GetString("tcInvalidUseOfTypeName"))
+        ignore(GetString("tcTypeHasNoAccessibleConstructor"))
+        ignore(GetString("tcInvalidUseOfTypeNameOrConstructor"))
+        ignore(GetString("tcInvalidUseOfTypeNameOrConstructorWithOverloads"))
+        ignore(GetString("tcInvalidUseOfInterfaceType"))
+        ignore(GetString("tcInvalidUseOfDelegate"))
+        ignore(GetString("tcPropertyIsNotStatic"))
+        ignore(GetString("tcPropertyIsNotReadable"))
+        ignore(GetString("tcLookupMayNotBeUsedHere"))
+        ignore(GetString("tcPropertyIsStatic"))
+        ignore(GetString("tcPropertyCannotBeSet1"))
+        ignore(GetString("tcConstructorsCannotBeFirstClassValues"))
+        ignore(GetString("tcSyntaxFormUsedOnlyWithRecordLabelsPropertiesAndFields"))
+        ignore(GetString("tcEventIsStatic"))
+        ignore(GetString("tcEventIsNotStatic"))
+        ignore(GetString("tcNamedArgumentDidNotMatch"))
+        ignore(GetString("tcOverloadsCannotHaveCurriedArguments"))
+        ignore(GetString("tcUnnamedArgumentsDoNotFormPrefix"))
+        ignore(GetString("tcStaticOptimizationConditionalsOnlyForFSharpLibrary"))
+        ignore(GetString("tcFormalArgumentIsNotOptional"))
+        ignore(GetString("tcInvalidOptionalAssignmentToPropertyOrField"))
+        ignore(GetString("tcDelegateConstructorMustBePassed"))
+        ignore(GetString("tcBindingCannotBeUseAndRec"))
+        ignore(GetString("tcVolatileOnlyOnClassLetBindings"))
+        ignore(GetString("tcAttributesAreNotPermittedOnLetBindings"))
+        ignore(GetString("tcDefaultValueAttributeRequiresVal"))
+        ignore(GetString("tcConditionalAttributeRequiresMembers"))
+        ignore(GetString("tcInvalidActivePatternName"))
+        ignore(GetString("tcEntryPointAttributeRequiresFunctionInModule"))
+        ignore(GetString("tcMutableValuesCannotBeInline"))
+        ignore(GetString("tcMutableValuesMayNotHaveGenericParameters"))
+        ignore(GetString("tcMutableValuesSyntax"))
+        ignore(GetString("tcOnlyFunctionsCanBeInline"))
+        ignore(GetString("tcIllegalAttributesForLiteral"))
+        ignore(GetString("tcLiteralCannotBeMutable"))
+        ignore(GetString("tcLiteralCannotBeInline"))
+        ignore(GetString("tcLiteralCannotHaveGenericParameters"))
+        ignore(GetString("tcInvalidConstantExpression"))
+        ignore(GetString("tcTypeIsInaccessible"))
+        ignore(GetString("tcUnexpectedConditionInImportedAssembly"))
+        ignore(GetString("tcUnrecognizedAttributeTarget"))
+        ignore(GetString("tcAttributeIsNotValidForLanguageElementUseDo"))
+        ignore(GetString("tcAttributeIsNotValidForLanguageElement"))
+        ignore(GetString("tcOptionalArgumentsCannotBeUsedInCustomAttribute"))
+        ignore(GetString("tcPropertyCannotBeSet0"))
+        ignore(GetString("tcPropertyOrFieldNotFoundInAttribute"))
+        ignore(GetString("tcCustomAttributeMustBeReferenceType"))
+        ignore(GetString("tcCustomAttributeArgumentMismatch"))
+        ignore(GetString("tcCustomAttributeMustInvokeConstructor"))
+        ignore(GetString("tcAttributeExpressionsMustBeConstructorCalls"))
+        ignore(GetString("tcUnsupportedAttribute"))
+        ignore(GetString("tcInvalidInlineSpecification"))
+        ignore(GetString("tcInvalidUseBinding"))
+        ignore(GetString("tcAbstractMembersIllegalInAugmentation"))
+        ignore(GetString("tcMethodOverridesIllegalHere"))
+        ignore(GetString("tcNoMemberFoundForOverride"))
+        ignore(GetString("tcOverrideArityMismatch"))
+        ignore(GetString("tcDefaultImplementationAlreadyExists"))
+        ignore(GetString("tcDefaultAmbiguous"))
+        ignore(GetString("tcNoPropertyFoundForOverride"))
+        ignore(GetString("tcAbstractPropertyMissingGetOrSet"))
+        ignore(GetString("tcInvalidSignatureForSet"))
+        ignore(GetString("tcPropertyAlreadyHasDefaultImplementation"))
+        ignore(GetString("tcPropertyImplementedIsAmbiguous"))
+        ignore(GetString("tcNewMemberHidesAbstractMember"))
+        ignore(GetString("tcNewMemberHidesAbstractMemberWithSuffix"))
+        ignore(GetString("tcStaticInitializersIllegalInInterface"))
+        ignore(GetString("tcObjectConstructorsIllegalInInterface"))
+        ignore(GetString("tcMemberOverridesIllegalInInterface"))
+        ignore(GetString("tcConcreteMembersIllegalInInterface"))
+        ignore(GetString("tcConstructorsDisallowedInExceptionAugmentation"))
+        ignore(GetString("tcStructsCannotHaveConstructorWithNoArguments"))
+        ignore(GetString("tcConstructorsIllegalForThisType"))
+        ignore(GetString("tcRecursiveBindingsWithMembersMustBeDirectAugmentation"))
+        ignore(GetString("tcOnlySimplePatternsInLetRec"))
+        ignore(GetString("tcOnlyRecordFieldsAndSimpleLetCanBeMutable"))
+        ignore(GetString("tcMemberIsNotSufficientlyGeneric"))
+        ignore(GetString("tcLiteralAttributeRequiresConstantValue"))
+        ignore(GetString("tcValueInSignatureRequiresLiteralAttribute"))
+        ignore(GetString("tcThreadStaticAndContextStaticMustBeStatic"))
+        ignore(GetString("tcVolatileFieldsMustBeMutable"))
+        ignore(GetString("tcUninitializedValFieldsMustBeMutable"))
+        ignore(GetString("tcStaticValFieldsMustBeMutableAndPrivate"))
+        ignore(GetString("tcFieldRequiresName"))
+        ignore(GetString("tcInvalidNamespaceModuleTypeUnionName"))
+        ignore(GetString("tcIllegalFormForExplicitTypeDeclaration"))
+        ignore(GetString("tcReturnTypesForUnionMustBeSameAsType"))
+        ignore(GetString("tcInvalidEnumerationLiteral"))
+        ignore(GetString("tcTypeIsNotInterfaceType1"))
+        ignore(GetString("tcDuplicateSpecOfInterface"))
+        ignore(GetString("tcFieldValIllegalHere"))
+        ignore(GetString("tcInheritIllegalHere"))
+        ignore(GetString("tcModuleRequiresQualifiedAccess"))
+        ignore(GetString("tcOpenUsedWithPartiallyQualifiedPath"))
+        ignore(GetString("tcLocalClassBindingsCannotBeInline"))
+        ignore(GetString("tcTypeAbbreviationsMayNotHaveMembers"))
+        ignore(GetString("tcEnumerationsMayNotHaveMembers"))
+        ignore(GetString("tcMeasureDeclarationsRequireStaticMembers"))
+        ignore(GetString("tcStructsMayNotContainDoBindings"))
+        ignore(GetString("tcStructsMayNotContainLetBindings"))
+        ignore(GetString("tcStaticLetBindingsRequireClassesWithImplicitConstructors"))
+        ignore(GetString("tcMeasureDeclarationsRequireStaticMembersNotConstructors"))
+        ignore(GetString("tcMemberAndLocalClassBindingHaveSameName"))
+        ignore(GetString("tcTypeAbbreviationsCannotHaveInterfaceDeclaration"))
+        ignore(GetString("tcEnumerationsCannotHaveInterfaceDeclaration"))
+        ignore(GetString("tcTypeIsNotInterfaceType0"))
+        ignore(GetString("tcAllImplementedInterfacesShouldBeDeclared"))
+        ignore(GetString("tcDefaultImplementationForInterfaceHasAlreadyBeenAdded"))
+        ignore(GetString("tcMemberNotPermittedInInterfaceImplementation"))
+        ignore(GetString("tcDeclarationElementNotPermittedInAugmentation"))
+        ignore(GetString("tcTypesCannotContainNestedTypes"))
+        ignore(GetString("tcTypeExceptionOrModule"))
+        ignore(GetString("tcTypeOrModule"))
+        ignore(GetString("tcImplementsIStructuralEquatableExplicitly"))
+        ignore(GetString("tcImplementsIEquatableExplicitly"))
+        ignore(GetString("tcExplicitTypeSpecificationCannotBeUsedForExceptionConstructors"))
+        ignore(GetString("tcExceptionAbbreviationsShouldNotHaveArgumentList"))
+        ignore(GetString("tcAbbreviationsFordotNetExceptionsCannotTakeArguments"))
+        ignore(GetString("tcExceptionAbbreviationsMustReferToValidExceptions"))
+        ignore(GetString("tcAbbreviationsFordotNetExceptionsMustHaveMatchingObjectConstructor"))
+        ignore(GetString("tcNotAnException"))
+        ignore(GetString("tcUnexpectedConstraintsOrParametersOnModule"))
+        ignore(GetString("tcUnexpectedConstraintOrTypeDef"))
+        ignore(GetString("tcInvalidModuleName"))
+        ignore(GetString("tcInvalidTypeExtension"))
+        ignore(GetString("tcAttributesOfTypeSpecifyMultipleKindsForType"))
+        ignore(GetString("tcKindOfTypeSpecifiedDoesNotMatchDefinition"))
+        ignore(GetString("tcMeasureDefinitionsCannotHaveTypeParameters"))
+        ignore(GetString("tcTypeRequiresDefinition"))
+        ignore(GetString("tcTypeAbbreviationHasTypeParametersMissingOnType"))
+        ignore(GetString("tcStructsInterfacesEnumsDelegatesMayNotInheritFromOtherTypes"))
+        ignore(GetString("tcTypesCannotInheritFromMultipleConcreteTypes"))
+        ignore(GetString("tcRecordsUnionsAbbreviationsStructsMayNotHaveAllowNullLiteralAttribute"))
+        ignore(GetString("tcAllowNullTypesMayOnlyInheritFromAllowNullTypes"))
+        ignore(GetString("tcGenericTypesCannotHaveStructLayout"))
+        ignore(GetString("tcOnlyStructsCanHaveStructLayout"))
+        ignore(GetString("tcRepresentationOfTypeHiddenBySignature"))
+        ignore(GetString("tcOnlyClassesCanHaveAbstract"))
+        ignore(GetString("tcOnlyTypesRepresentingUnitsOfMeasureCanHaveMeasure"))
+        ignore(GetString("tcOverridesCannotHaveVisibilityDeclarations"))
+        ignore(GetString("tcTypesAreAlwaysSealedDU"))
+        ignore(GetString("tcTypesAreAlwaysSealedRecord"))
+        ignore(GetString("tcTypesAreAlwaysSealedAssemblyCode"))
+        ignore(GetString("tcTypesAreAlwaysSealedStruct"))
+        ignore(GetString("tcTypesAreAlwaysSealedDelegate"))
+        ignore(GetString("tcTypesAreAlwaysSealedEnum"))
+        ignore(GetString("tcInterfaceTypesAndDelegatesCannotContainFields"))
+        ignore(GetString("tcAbbreviatedTypesCannotBeSealed"))
+        ignore(GetString("tcCannotInheritFromSealedType"))
+        ignore(GetString("tcCannotInheritFromInterfaceType"))
+        ignore(GetString("tcStructTypesCannotContainAbstractMembers"))
+        ignore(GetString("tcInterfaceTypesCannotBeSealed"))
+        ignore(GetString("tcInvalidDelegateSpecification"))
+        ignore(GetString("tcDelegatesCannotBeCurried"))
+        ignore(GetString("tcInvalidTypeForLiteralEnumeration"))
+        ignore(GetString("tcTypeDefinitionIsCyclic"))
+        ignore(GetString("tcTypeDefinitionIsCyclicThroughInheritance"))
+        ignore(GetString("tcReservedSyntaxForAugmentation"))
+        ignore(GetString("tcMembersThatExtendInterfaceMustBePlacedInSeparateModule"))
+        ignore(GetString("tcDeclaredTypeParametersForExtensionDoNotMatchOriginal"))
+        ignore(GetString("tcTypeDefinitionsWithImplicitConstructionMustHaveOneInherit"))
+        ignore(GetString("tcTypeDefinitionsWithImplicitConstructionMustHaveLocalBindingsBeforeMembers"))
+        ignore(GetString("tcInheritDeclarationMissingArguments"))
+        ignore(GetString("tcInheritConstructionCallNotPartOfImplicitSequence"))
+        ignore(GetString("tcLetAndDoRequiresImplicitConstructionSequence"))
+        ignore(GetString("tcTypeAbbreviationsCannotHaveAugmentations"))
+        ignore(GetString("tcModuleAbbreviationForNamespace"))
+        ignore(GetString("tcTypeUsedInInvalidWay"))
+        ignore(GetString("tcMemberUsedInInvalidWay"))
+        ignore(GetString("tcExplicitSignaturesInImplementationFileCannotBeUsed"))
+        ignore(GetString("tcModulesCannotUseNamedModuleSignatures"))
+        ignore(GetString("tcAttributeAutoOpenWasIgnored"))
+        ignore(GetString("ilUndefinedValue"))
+        ignore(GetString("ilLabelNotFound"))
+        ignore(GetString("ilIncorrectNumberOfTypeArguments"))
+        ignore(GetString("ilDynamicInvocationNotSupported"))
+        ignore(GetString("ilAddressOfLiteralFieldIsInvalid"))
+        ignore(GetString("ilAddressOfValueHereIsInvalid"))
+        ignore(GetString("ilValuesWithLiteralAttributeCannotBeMutable"))
+        ignore(GetString("ilValuesWithLiteralAttributeMustBeSimple"))
+        ignore(GetString("ilCustomMarshallersCannotBeUsedInFSharp"))
+        ignore(GetString("ilMarshalAsAttributeCannotBeDecoded"))
+        ignore(GetString("ilSignatureForExternalFunctionContainsTypeParameters"))
+        ignore(GetString("ilDllImportAttributeCouldNotBeDecoded"))
+        ignore(GetString("ilLiteralFieldsCannotBeSet"))
+        ignore(GetString("ilStaticMethodIsNotLambda"))
+        ignore(GetString("ilMutableVariablesCannotEscapeMethod"))
+        ignore(GetString("ilUnexpectedUnrealizedValue"))
+        ignore(GetString("ilMainModuleEmpty"))
+        ignore(GetString("ilTypeCannotBeUsedForLiteralField"))
+        ignore(GetString("ilUnexpectedGetSetAnnotation"))
+        ignore(GetString("ilFieldOffsetAttributeCouldNotBeDecoded"))
+        ignore(GetString("ilStructLayoutAttributeCouldNotBeDecoded"))
+        ignore(GetString("ilDefaultAugmentationAttributeCouldNotBeDecoded"))
+        ignore(GetString("ilReflectedDefinitionsCannotUseSliceOperator"))
+        ignore(GetString("optsProblemWithCodepage"))
+        ignore(GetString("optsCopyright"))
+        ignore(GetString("optsNameOfOutputFile"))
+        ignore(GetString("optsBuildConsole"))
+        ignore(GetString("optsBuildWindows"))
+        ignore(GetString("optsBuildLibrary"))
+        ignore(GetString("optsBuildModule"))
+        ignore(GetString("optsDelaySign"))
+        ignore(GetString("optsWriteXml"))
+        ignore(GetString("optsStrongKeyFile"))
+        ignore(GetString("optsStrongKeyContainer"))
+        ignore(GetString("optsPlatform"))
+        ignore(GetString("optsNoOpt"))
+        ignore(GetString("optsNoInterface"))
+        ignore(GetString("optsSig"))
+        ignore(GetString("optsReference"))
+        ignore(GetString("optsWin32res"))
+        ignore(GetString("optsWin32manifest"))
+        ignore(GetString("optsNowin32manifest"))
+        ignore(GetString("optsResource"))
+        ignore(GetString("optsLinkresource"))
+        ignore(GetString("optsDebugPM"))
+        ignore(GetString("optsDebug"))
+        ignore(GetString("optsOptimize"))
+        ignore(GetString("optsTailcalls"))
+        ignore(GetString("optsCrossoptimize"))
+        ignore(GetString("optsWarnaserrorPM"))
+        ignore(GetString("optsWarnaserror"))
+        ignore(GetString("optsWarn"))
+        ignore(GetString("optsNowarn"))
+        ignore(GetString("optsChecked"))
+        ignore(GetString("optsDefine"))
+        ignore(GetString("optsMlcompatibility"))
+        ignore(GetString("optsNologo"))
+        ignore(GetString("optsHelp"))
+        ignore(GetString("optsCodepage"))
+        ignore(GetString("optsUtf8output"))
+        ignore(GetString("optsFullpaths"))
+        ignore(GetString("optsLib"))
+        ignore(GetString("optsBaseaddress"))
+        ignore(GetString("optsNoframework"))
+        ignore(GetString("optsStandalone"))
+        ignore(GetString("optsStaticlink"))
+        ignore(GetString("optsPdb"))
+        ignore(GetString("optsSimpleresolution"))
+        ignore(GetString("optsUnrecognizedTarget"))
+        ignore(GetString("optsUnrecognizedDebugType"))
+        ignore(GetString("optsInvalidWarningLevel"))
+        ignore(GetString("optsShortFormOf"))
+        ignore(GetString("optsClirootDeprecatedMsg"))
+        ignore(GetString("optsClirootDescription"))
+        ignore(GetString("optsHelpBannerOutputFiles"))
+        ignore(GetString("optsHelpBannerInputFiles"))
+        ignore(GetString("optsHelpBannerResources"))
+        ignore(GetString("optsHelpBannerCodeGen"))
+        ignore(GetString("optsHelpBannerAdvanced"))
+        ignore(GetString("optsHelpBannerMisc"))
+        ignore(GetString("optsHelpBannerLanguage"))
+        ignore(GetString("optsHelpBannerErrsAndWarns"))
+        ignore(GetString("optsUnknownArgumentToTheTestSwitch"))
+        ignore(GetString("optsUnknownPlatform"))
+        ignore(GetString("optsInternalNoDescription"))
+        ignore(GetString("optsDCLONoDescription"))
+        ignore(GetString("optsDCLODeprecatedSuggestAlternative"))
+        ignore(GetString("optsDCLOHtmlDoc"))
+        ignore(GetString("gotoDefinitionHeader"))
+        ignore(GetString("typeInfoFullName"))
+        ignore(GetString("typeInfoType"))
+        ignore(GetString("typeInfoInherits"))
+        ignore(GetString("typeInfoImplements"))
+        ignore(GetString("typeInfoOtherOverloads"))
+        ignore(GetString("typeInfoUnionCase"))
+        ignore(GetString("typeInfoActivePatternResult"))
+        ignore(GetString("typeInfoActiveRecognizer"))
+        ignore(GetString("typeInfoField"))
+        ignore(GetString("typeInfoEvent"))
+        ignore(GetString("typeInfoProperty"))
+        ignore(GetString("typeInfoArgument"))
+        ignore(GetString("typeInfoPatternVariable"))
+        ignore(GetString("typeInfoNamespace"))
+        ignore(GetString("typeInfoModule"))
+        ignore(GetString("typeInfoNamespaceOrModule"))
+        ignore(GetString("typeInfoFromFirst"))
+        ignore(GetString("typeInfoFromNext"))
+        ignore(GetString("assemblyResolutionFoundByAssemblyFoldersKey"))
+        ignore(GetString("assemblyResolutionFoundByAssemblyFoldersExKey"))
+        ignore(GetString("assemblyResolutionNetFramework"))
+        ignore(GetString("assemblyResolutionGAC"))
+        ignore(GetString("recursiveClassHierarchy"))
+        ignore(GetString("InvalidRecursiveReferenceToAbstractSlot"))
+        ignore(GetString("eventHasNonStandardType"))
+        ignore(GetString("typeIsNotAccessible"))
+        ignore(GetString("unionCasesAreNotAccessible"))
+        ignore(GetString("valueIsNotAccessible"))
+        ignore(GetString("unionCaseIsNotAccessible"))
+        ignore(GetString("fieldIsNotAccessible"))
+        ignore(GetString("structOrClassFieldIsNotAccessible"))
+        ignore(GetString("experimentalConstruct"))
+        ignore(GetString("noInvokeMethodsFound"))
+        ignore(GetString("moreThanOneInvokeMethodFound"))
+        ignore(GetString("delegatesNotAllowedToHaveCurriedSignatures"))
+        ignore(GetString("tlrUnexpectedTExpr"))
+        ignore(GetString("tlrLambdaLiftingOptimizationsNotApplied"))
+        ignore(GetString("lexhlpIdentifiersContainingAtSymbolReserved"))
+        ignore(GetString("lexhlpIdentifierReserved"))
+        ignore(GetString("patcMissingVariable"))
+        ignore(GetString("patcPartialActivePatternsGenerateOneResult"))
+        ignore(GetString("impTypeRequiredUnavailable"))
+        ignore(GetString("impReferencedTypeCouldNotBeFoundInAssembly"))
+        ignore(GetString("impNotEnoughTypeParamsInScopeWhileImporting"))
+        ignore(GetString("impReferenceToDllRequiredByAssembly"))
+        ignore(GetString("impImportedAssemblyUsesNotPublicType"))
+        ignore(GetString("optValueMarkedInlineButIncomplete"))
+        ignore(GetString("optValueMarkedInlineButWasNotBoundInTheOptEnv"))
+        ignore(GetString("optLocalValueNotFoundDuringOptimization"))
+        ignore(GetString("optValueMarkedInlineHasUnexpectedValue"))
+        ignore(GetString("optValueMarkedInlineCouldNotBeInlined"))
+        ignore(GetString("optFailedToInlineValue"))
+        ignore(GetString("optRecursiveValValue"))
+        ignore(GetString("lexfltIncorrentIndentationOfIn"))
+        ignore(GetString("lexfltTokenIsOffsideOfContextStartedEarlier"))
+        ignore(GetString("lexfltSeparatorTokensOfPatternMatchMisaligned"))
+        ignore(GetString("nrInvalidModuleExprType"))
+        ignore(GetString("nrTypeInstantiationNeededToDisambiguateTypesWithSameName"))
+        ignore(GetString("nrTypeInstantiationIsMissingAndCouldNotBeInferred"))
+        ignore(GetString("nrGlobalUsedOnlyAsFirstName"))
+        ignore(GetString("nrIsNotConstructorOrLiteral"))
+        ignore(GetString("nrUnexpectedEmptyLongId"))
+        ignore(GetString("nrTypeDoesNotContainSuchField"))
+        ignore(GetString("nrInvalidFieldLabel"))
+        ignore(GetString("nrInvalidExpression"))
+        ignore(GetString("nrNoConstructorsAvailableForType"))
+        ignore(GetString("ilwriteErrorCreatingPdb"))
+        ignore(GetString("ilwriteNoPDBsOnMonoWarning"))
+        ignore(GetString("lexOutsideIntegerRange"))
+        ignore(GetString("lexCharNotAllowedInOperatorNames"))
+        ignore(GetString("lexOpNamesCannotStartWithQuestionMark"))
+        ignore(GetString("lexUnexpectedChar"))
+        ignore(GetString("lexByteArrayCannotEncode"))
+        ignore(GetString("lexIdentEndInMarkReserved"))
+        ignore(GetString("lexOutsideEightBitSigned"))
+        ignore(GetString("lexOutsideEightBitSignedHex"))
+        ignore(GetString("lexOutsideEightBitUnsigned"))
+        ignore(GetString("lexOutsideSixteenBitSigned"))
+        ignore(GetString("lexOutsideSixteenBitUnsigned"))
+        ignore(GetString("lexOutsideThirtyTwoBitSigned"))
+        ignore(GetString("lexOutsideThirtyTwoBitUnsigned"))
+        ignore(GetString("lexOutsideSixtyFourBitSigned"))
+        ignore(GetString("lexOutsideSixtyFourBitUnsigned"))
+        ignore(GetString("lexOutsideNativeSigned"))
+        ignore(GetString("lexOutsideNativeUnsigned"))
+        ignore(GetString("lexInvalidFloat"))
+        ignore(GetString("lexOusideDecimal"))
+        ignore(GetString("lexOusideThirtyTwoBitFloat"))
+        ignore(GetString("lexInvalidNumericLiteral"))
+        ignore(GetString("lexInvalidByteLiteral"))
+        ignore(GetString("lexInvalidCharLiteral"))
+        ignore(GetString("lexThisUnicodeOnlyInStringLiterals"))
+        ignore(GetString("lexTokenReserved"))
+        ignore(GetString("lexTabsNotAllowed"))
+        ignore(GetString("lexInvalidLineNumber"))
+        ignore(GetString("lexHashIfMustBeFirst"))
+        ignore(GetString("lexHashElseNoMatchingIf"))
+        ignore(GetString("lexHashEndifRequiredForElse"))
+        ignore(GetString("lexHashElseMustBeFirst"))
+        ignore(GetString("lexHashEndingNoMatchingIf"))
+        ignore(GetString("lexHashEndifMustBeFirst"))
+        ignore(GetString("lexHashIfMustHaveIdent"))
+        ignore(GetString("lexWrongNestedHashEndif"))
+        ignore(GetString("lexExpectedSingleLineComment"))
+        ignore(GetString("memberOperatorDefinitionWithNoArguments"))
+        ignore(GetString("memberOperatorDefinitionWithNonPairArgument"))
+        ignore(GetString("memberOperatorDefinitionWithCurriedArguments"))
+        ignore(GetString("tcFSharpCoreRequiresExplicit"))
+        ignore(GetString("tcStructuralComparisonNotSatisfied1"))
+        ignore(GetString("tcStructuralComparisonNotSatisfied2"))
+        ignore(GetString("tcNoComparisonNeeded1"))
+        ignore(GetString("tcNoComparisonNeeded2"))
+        ignore(GetString("tcNoEqualityNeeded1"))
+        ignore(GetString("tcNoEqualityNeeded2"))
+        ignore(GetString("tcStructuralEqualityNotSatisfied1"))
+        ignore(GetString("tcStructuralEqualityNotSatisfied2"))
+        ignore(GetString("tcStructsMustDeclareTypesOfImplicitCtorArgsExplicitly"))
+        ignore(GetString("chkUnusedValue"))
+        ignore(GetString("chkUnusedThisVariable"))
+        ignore(GetString("parsGetterAtMostOneArgument"))
+        ignore(GetString("parsSetterAtMostTwoArguments"))
+        ignore(GetString("parsInvalidProperty"))
+        ignore(GetString("parsIndexerPropertyRequiresAtLeastOneArgument"))
+        ignore(GetString("tastInvalidAddressOfMutableAcrossAssemblyBoundary"))
+        ignore(GetString("parsNonAdjacentTypars"))
+        ignore(GetString("parsNonAdjacentTyargs"))
+        ignore(GetString("parsNonAtomicType"))
+        ignore(GetString("tastUndefinedTyconItemField"))
+        ignore(GetString("tastUndefinedTyconItemUnionCase"))
+        ignore(GetString("tastUndefinedItemRefModuleNamespace"))
+        ignore(GetString("tastUndefinedItemRefVal"))
+        ignore(GetString("tastUndefinedItemRefModuleNamespaceType"))
+        ignore(GetString("tcInvalidUseNullAsTrueValue"))
+        ignore(GetString("tcParameterInferredByref"))
+        ignore(GetString("tcNonUniformMemberUse"))
+        ignore(GetString("tcNamedArgumentsCannotBeUsedInUnionCaseConstructions"))
+        ignore(GetString("tcAttribArgsDiffer"))
+        ignore(GetString("tcCannotCallAbstractBaseMember"))
+        ignore(GetString("typrelCannotResolveAmbiguityInUnmanaged"))
+        ignore(GetString("mlCompatMessage"))
+        ignore(GetString("ilFieldDoesNotHaveValidOffsetForStructureLayout"))
+        ignore(GetString("tcInterfacesShouldUseInheritNotInterface"))
+        ignore(GetString("parsInvalidPrefixOperator"))
+        ignore(GetString("parsInvalidPrefixOperatorDefinition"))
+        ignore(GetString("buildCompilingExtensionIsForML"))
+        ignore(GetString("lexIndentOffForML"))
+        ignore(GetString("activePatternIdentIsNotFunctionTyped"))
+        ignore(GetString("activePatternChoiceHasFreeTypars"))
+        ignore(GetString("ilFieldHasOffsetForSequentialLayout"))
+        ignore(GetString("tcOptionalArgsMustComeAfterNonOptionalArgs"))
+        ignore(GetString("tcConditionalAttributeUsage"))
+        ignore(GetString("monoRegistryBugWorkaround"))
+        ignore(GetString("tcMemberOperatorDefinitionInExtrinsic"))
+        ()
diff --git a/src/FSharp.PowerPack.Metadata/FSharp.PowerPack.Metadata.fsproj b/src/FSharp.PowerPack.Metadata/FSharp.PowerPack.Metadata.fsproj
new file mode 100755
index 0000000..1199442
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/FSharp.PowerPack.Metadata.fsproj
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{816cb737-0648-4889-8662-54484d42824d}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>FSharp.PowerPack.Metadata</AssemblyName>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TreatWarningsAsErrors>
+    </TreatWarningsAsErrors>
+    <!-- 5310 tracks reenabling -->
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <DefineConstants>INCLUDE_METADATA_READER;$(DefineConstants)</DefineConstants>
+    <DocumentationFile>FSharp.PowerPack.Metadata.xml</DocumentationFile>
+    <NoWarn>$(NoWarn);9;62</NoWarn>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <!-- References -->
+  <!-- Files -->
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="assemblyinfo.FSharp.PowerPack.Metadata.dll.fs">
+      <Link>assemblyinfo.FSharp.PowerPack.Metadata.dll.fs</Link>
+    </Compile>
+    <Compile Include="Prelude.fs" />
+    <Compile Include="FSComp.fs">
+      <Link>FSComp.fs</Link>
+    </Compile>
+    <Compile Include="FlatList.fs">
+      <Link>FlatList.fs</Link>
+    </Compile>
+    <Compile Include="QueueList.fs">
+      <Link>QueueList.fs</Link>
+    </Compile>
+    <Compile Include="PrettyNaming.fs">
+      <Link>PrettyNaming.fs</Link>
+    </Compile>
+    <Compile Include="il.fs">
+      <Link>il.fs</Link>
+    </Compile>
+    <Compile Include="tast.fs">
+      <Link>tast.fs</Link>
+    </Compile>
+    <Compile Include="env.fs">
+      <Link>env.fs</Link>
+    </Compile>
+    <Compile Include="tastops.fs">
+      <Link>tastops.fs</Link>
+    </Compile>
+    <Compile Include="pickle.fs">
+      <Link>pickle.fs</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\CompilerLocationUtils.fs">
+      <Link>CompilerLocationUtils.fs</Link>
+    </Compile>
+    <Compile Include="Metadata.fsi" />
+    <Compile Include="Metadata.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="FSharp.Core" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Metadata/FSharp.PowerPack.Metadata.fsproj.vspscc b/src/FSharp.PowerPack.Metadata/FSharp.PowerPack.Metadata.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/FSharp.PowerPack.Metadata.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FSharp.PowerPack.Metadata/FlatList.fs b/src/FSharp.PowerPack.Metadata/FlatList.fs
new file mode 100755
index 0000000..94de11e
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/FlatList.fs
@@ -0,0 +1,44 @@
+// (c) Microsoft Corporation. All rights reserved(
+
+namespace Microsoft.FSharp.Metadata.Reader.Internal
+
+open System.Collections
+open System.Collections.Generic
+
+type internal FlatList<'T> ='T list
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module internal FlatList =
+    let empty<'T> : 'T list = []
+    let collect (f: 'T -> FlatList<'T>) (x:FlatList<_>) =  List.collect f x
+    let exists f (x:FlatList<_>) = List.exists f x
+    let filter f (x:FlatList<_>) = List.filter f x
+    let fold f acc (x:FlatList<_>) = List.fold f acc x
+    let fold2 f acc (x:FlatList<_>) (y:FlatList<_>) = List.fold2 f acc x y
+    let foldBack f (x:FlatList<_>) acc  = List.foldBack f x acc
+    let foldBack2 f (x:FlatList<_>) (y:FlatList<_>) acc = List.foldBack2 f x y acc
+    let map2 f (x:FlatList<_>) (y:FlatList<_>) = List.map2 f x y
+    let forall f (x:FlatList<_>) = List.forall f x
+    let forall2 f (x1:FlatList<_>) (x2:FlatList<_>) = List.forall2 f x1 x2
+    let iter2 f (x1:FlatList<_>) (x2:FlatList<_>) = List.iter2 f x1 x2 
+    let partition f (x:FlatList<_>) = List.partition f x
+    let (* inline *) sum (x:FlatList<int>) = List.sum x
+    let (* inline *) sumBy (f: 'T -> int) (x:FlatList<'T>) = List.sumBy f x
+    let unzip (x:FlatList<_>) = List.unzip x
+    let physicalEquality (x:FlatList<_>) (y:FlatList<_>) = (LanguagePrimitives.PhysicalEquality x y)
+    let tryFind f (x:FlatList<_>) = List.tryFind f x
+    let concat (x:FlatList<_>) = List.concat x
+    let isEmpty (x:FlatList<_>) = List.isEmpty x
+    let one(x) = [x]
+    let toMap (x:FlatList<_>) = Map.ofList x
+    let length (x:FlatList<_>) = List.length x
+    let map f (x:FlatList<_>) = List.map f x
+    let mapi f (x:FlatList<_>) = List.mapi f x
+    let iter f (x:FlatList<_>) = List.iter f x
+    let iteri f (x:FlatList<_>) = List.iteri f x
+    let toList (x:FlatList<_>) = x
+    let ofSeq (x:seq<_>) = List.ofSeq x
+    let append(l1 : FlatList<'T>) (l2 : FlatList<'T>) =  List.append l1 l2
+    let ofList(l) = l
+    let init n f = List.init n f
+    let zip (x:FlatList<_>) (y:FlatList<_>) = List.zip x y
diff --git a/src/FSharp.PowerPack.Metadata/Metadata.fs b/src/FSharp.PowerPack.Metadata/Metadata.fs
new file mode 100755
index 0000000..b9feec2
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/Metadata.fs
@@ -0,0 +1,1315 @@
+// Copyright (c) Microsoft Corporation 2005-2009.
+// This sample code is provided "as is" without warranty of any kind. 
+// We disclaim all warranties, either express or implied, including the 
+// warranties of merchantability and fitness for a particular purpose. 
+//
+
+
+namespace Microsoft.FSharp.Metadata
+
+open System.IO
+open System.Collections.Generic
+open System.Reflection
+open Microsoft.FSharp.Metadata.Reader.Internal
+open Microsoft.FSharp.Metadata.Reader.Internal.AbstractIL.IL
+open Microsoft.FSharp.Metadata.Reader.Internal.Tast
+open Microsoft.FSharp.Metadata.Reader.Internal.Env
+open Microsoft.FSharp.Metadata.Reader.Internal.Prelude
+open Microsoft.FSharp.Metadata.Reader.Internal.Pickle
+
+#nowarn "44" // deprecated use of LoadWithPartialName
+module Impl = 
+    let isNull x = match x with null -> true  | _ -> false
+    
+    let readToEnd (s : Stream) = 
+        let n = int s.Length 
+        let res = Array.zeroCreate n 
+        let mutable i = 0 
+        while (i < n) do 
+            i <- i + s.Read(res,i,n - i) 
+        res 
+        
+    let makeReadOnlyCollection (arr:seq<'a>) = System.Collections.ObjectModel.ReadOnlyCollection<_>(Seq.toArray arr)
+    
+    let makeXmlDoc (XmlDoc x) = makeReadOnlyCollection(x)
+    
+    let isPublic a = (taccessPublic = a)
+
+
+    let tryRescopeEntity viewedCcu (entity:Entity) : EntityRef option = 
+        match entity.PublicPath with 
+        | Some pubpath -> Some (ERef_nonlocal (nleref_of_pubpath viewedCcu pubpath))
+        | None -> None
+
+    let rescopeEntity viewedCcu (entity:Entity) = 
+        match tryRescopeEntity viewedCcu entity with 
+        | None -> mk_local_tcref entity
+        | Some eref -> eref
+
+open Impl
+
+
+/// A limited implementation of type equality sufficient to resolve method signatures
+/// Nothing in this module may dereference inaccessible entities, e.g. entities in .NET assemblies
+module ApproxTypeEquiv = 
+
+    //--------------------------------------------------------------------------
+    // renamings
+    //--------------------------------------------------------------------------
+
+    type TyparInst = (Typar * typ) list
+
+    let empty_tpinst = ([] : TyparInst)
+
+    let rec inst_tpref tpinst ty tp  =
+        match tpinst with 
+        | [] -> ty
+        | (tp',ty')::t -> 
+            if typar_ref_eq tp tp' then ty' 
+            else inst_tpref t ty tp
+
+    let mk_typar_inst (typars: Typars) tyargs =  
+        (List.zip typars tyargs : TyparInst)
+
+    // This must not dereference inaccessible entities, e.g. entities in .NET assemblies
+    let rec inst_type (tpinst : TyparInst) (ty:typ) =
+        let ty = strip_tpeqns ty
+        match ty with
+        | TType_var tp as ty       -> inst_tpref tpinst ty tp
+        | TType_app (tcr,tinst) -> TType_app (tcr,inst_types tpinst tinst)
+        | TType_tuple l  -> TType_tuple (inst_types tpinst l)
+        | TType_fun (d,r) -> TType_fun (inst_type tpinst d, inst_type tpinst r)
+        | TType_forall (tps,ty) -> TType_forall (tps, inst_type tpinst ty)
+        | TType_measure unt -> TType_measure (inst_measure tpinst unt)
+        | _ -> ty
+
+    and inst_measure tpinst unt =
+        match unt with
+        | MeasureOne -> unt
+        | MeasureCon tcr -> unt
+        | MeasureProd(u1,u2) -> MeasureProd(inst_measure tpinst u1, inst_measure tpinst u2)
+        | MeasureInv u -> MeasureInv(inst_measure tpinst u)
+        | MeasureVar tp -> 
+              if ListAssoc.containsKey typar_ref_eq tp tpinst then 
+                  match ListAssoc.find typar_ref_eq tp tpinst with 
+                  | TType_measure unt -> unt
+                  | _ -> failwith "inst_measure: incorrect kinds"
+              else unt
+
+    and inst_types tpinst types = List.map (inst_type tpinst) types
+
+    let mk_tycon_inst (tycon: Tycon) tyargs = 
+        List.zip tycon.TyparsNoRange tyargs
+
+    let reduce_tycon_abbrev ty tycon tyargs = 
+        inst_type (mk_tycon_inst tycon tyargs) ty
+
+    let reduce_tycon_measureable (tycon:Tycon) tyargs = 
+        let repr = tycon.TypeReprInfo
+        match repr with 
+        | Some (TMeasureableRepr ty) -> 
+            if List.isEmpty tyargs then ty else inst_type (mk_tycon_inst tycon tyargs) ty
+        | _ -> invalidArg "tc" "this type definition is not a refinement"
+
+    [<NoEquality; NoComparison>]
+    type TypeEquivEnv = 
+        { ae_typars: Tastops.TyparMap<typ> }
+
+    let tyeq_env_empty = { ae_typars=Tastops.tpmap_empty() }
+
+    let bind_tyeq_env_types tps1 tys2 aenv =
+        {aenv with ae_typars=List.foldBack2 Tastops.tpmap_add tps1 tys2 aenv.ae_typars}
+
+    let bind_tyeq_env_typars tps1 tps2 aenv =
+        bind_tyeq_env_types tps1 (List.map mk_typar_ty tps2) aenv
+
+    let rec strip_tpeqns_and_tcabbrevs g ty = 
+        let ty = strip_tpeqnsA ty 
+        match ty with 
+        | TType_app (tcref,tinst) when tcref.CanDeref -> 
+            let tycon = tcref.Deref
+            match tycon.TypeAbbrev with 
+            | Some ty -> strip_tpeqns_and_tcabbrevs g (reduce_tycon_abbrev ty tycon tinst)
+            | None -> ty
+        | ty -> ty
+
+    let rec strip_tpeqns_and_tcabbrevs_and_erase g ty =
+        let ty = strip_tpeqns_and_tcabbrevs g ty
+        match ty with
+        | TType_app (tcref,args) when tcref.CanDeref -> 
+            let tycon = tcref.Deref
+            if tycon.IsMeasureableReprTycon  then
+                strip_tpeqns_and_tcabbrevs_and_erase g (reduce_tycon_measureable tycon args)
+            elif Tastops.tcref_eq g tcref g.nativeptr_tcr then 
+                strip_tpeqns_and_tcabbrevs_and_erase g (Tastops.mk_nativeint_typ g)
+            else
+                ty
+        | TType_fun(a,b) -> TType_app(g.fastFunc_tcr,[ a; b]) 
+        | TType_tuple(l) -> Tastops.compiled_tuple_ty g l
+        | ty -> ty
+
+    let rec type_aequiv_aux  g aenv ty1 ty2 = 
+        let ty1 = strip_tpeqns_and_tcabbrevs_and_erase g ty1 
+        let ty2 = strip_tpeqns_and_tcabbrevs_and_erase g ty2
+        match ty1, ty2 with
+        | TType_forall(tps1,rty1), TType_forall(tps2,rty2) -> 
+            tps1.Length = tps2.Length && type_aequiv_aux g (bind_tyeq_env_typars tps1 tps2 aenv) rty1 rty2
+        | TType_var tp1, TType_var tp2 when typar_ref_eq tp1 tp2 -> 
+            true
+        | TType_var tp1, _ when Tastops.tpmap_mem tp1 aenv.ae_typars -> 
+            type_equiv_aux g (Tastops.tpmap_find tp1 aenv.ae_typars) ty2
+        | TType_app (tc1,b1)  ,TType_app (tc2,b2) -> 
+            Tastops.tcref_eq g tc1 tc2 &&
+            types_aequiv_aux g aenv b1 b2
+        | TType_tuple l1,TType_tuple l2 -> 
+            types_aequiv_aux g aenv l1 l2
+        | TType_fun (dtys1,rty1),TType_fun (dtys2,rty2) -> 
+            type_aequiv_aux g aenv dtys1 dtys2 && type_aequiv_aux g aenv rty1 rty2
+        | TType_measure m1, TType_measure m2 -> true 
+        | _ -> false
+
+    and types_aequiv_aux g aenv l1 l2 = List.lengthsEqAndForall2 (type_aequiv_aux g aenv) l1 l2
+    and type_equiv_aux g ty1 ty2 =  type_aequiv_aux g tyeq_env_empty ty1 ty2
+
+
+
+type [<Sealed>] Env(typars:Typar list) = 
+   let typars = Array.ofList typars
+   member x.Typars = typars
+
+type [<Sealed>] SourceLocation(range:range) = 
+    member x.Document    = range.rangeFile
+    member x.StartLine   = range.rangeBegin.posLine
+    member x.StartColumn = range.rangeBegin.posCol
+    member x.EndLine     = range.rangeEnd.posLine
+    member x.EndColumn   = range.rangeEnd.posCol
+
+
+type [<Sealed>] AssemblyLoader() = 
+    static let table = Dictionary<string,FSharpAssembly>(100)
+     
+    static let fslib = AssemblyLoader.Add("FSharp.Core", typedefof<list<_>>.Assembly)
+    
+    static let _ = System.Reflection.Assembly.LoadWithPartialName "System"
+    static let _ = System.Type.GetType("System.Uri, System")
+     
+    static let globals = 
+        let p = [| "Microsoft"; "FSharp"; "Core" |]
+        let nlr = NonLocalEntityRef(fslib.RawCcuThunk,p)
+        { nativeptr_tcr = mk_nonlocal_tcref nlr "nativeptr`1" 
+          nativeint_tcr= mk_nonlocal_tcref nlr "nativeint" 
+          byref_tcr= mk_nonlocal_tcref nlr "byref`1" 
+          il_arr1_tcr= mk_nonlocal_tcref nlr "[]`1" 
+          il_arr2_tcr= mk_nonlocal_tcref nlr "[,]`1" 
+          il_arr3_tcr= mk_nonlocal_tcref nlr "[,,]`1" 
+          il_arr4_tcr= mk_nonlocal_tcref nlr "[,,,]`1" 
+          tuple1_tcr= mk_nonlocal_tcref nlr "Tuple`1" 
+          tuple2_tcr= mk_nonlocal_tcref nlr "Tuple`2" 
+          tuple3_tcr= mk_nonlocal_tcref nlr "Tuple`3" 
+          tuple4_tcr= mk_nonlocal_tcref nlr "Tuple`4" 
+          tuple5_tcr= mk_nonlocal_tcref nlr "Tuple`5" 
+          tuple6_tcr= mk_nonlocal_tcref nlr "Tuple`6" 
+          tuple7_tcr= mk_nonlocal_tcref nlr "Tuple`7" 
+          tuple8_tcr= mk_nonlocal_tcref nlr "Tuple`8" 
+          fastFunc_tcr= mk_nonlocal_tcref nlr "FSharpFunc`2" 
+          fslibCcu= fslib.RawCcuThunk
+          unit_tcr= mk_nonlocal_tcref nlr "unit"  }
+
+
+    static do  System.AppDomain.CurrentDomain.add_AssemblyResolve(new System.ResolveEventHandler(fun _ args -> 
+        let shortName = AssemblyName(args.Name).Name
+        lock table (fun () ->
+            if table.ContainsKey shortName then 
+                table.[shortName].ReflectionAssembly
+            else
+                null))
+            )
+
+    static member FSharpLibrary with get()  = fslib
+    static member TcGlobals with get() = globals
+
+    
+    static member TryLoad(name:string) : FSharpAssembly option = 
+        let existing = 
+            lock table (fun () ->
+                let found, result = table.TryGetValue(name)
+                if found then Some result else None
+            )
+        match existing with
+        |   Some _ -> existing
+        |   None ->
+                let assembly = Assembly.LoadWithPartialName name
+                AssemblyLoader.TryAdd(name, assembly)
+    
+    static member Get(assembly : Assembly) : FSharpAssembly =
+        let name = assembly.GetName().Name
+        let existing = 
+            lock table (fun () ->
+                let found, result = table.TryGetValue(name)
+                if found then Some result else None
+            )
+        match existing with
+        |   Some fsAss -> fsAss
+        |   None -> AssemblyLoader.Add(name, assembly)
+
+    static member private Add (name, assembly:Assembly) : FSharpAssembly = 
+        match AssemblyLoader.TryAdd (name, assembly) with 
+        | None -> invalidArg "name" (sprintf "could not produce an FSharpAssembly object for the assembly '%s' because this is not an F# assembly" name)
+        | Some res -> res
+
+    static member private TryAdd (name, assembly:Assembly) : FSharpAssembly option = 
+        let sref : ILScopeRef = ILScopeRef.Assembly(ILAssemblyRef.FromAssembly(assembly)) 
+        let bytes = 
+            match assembly.GetManifestResourceStream(FSharpSignatureDataResourceName ^ "." ^ name) with 
+            | null -> 
+                if name = "FSharp.Core" then 
+                    match Internal.Utilities.FSharpEnvironment.BinFolderOfDefaultFSharpCoreReferenceAssembly with 
+                    | Some path -> 
+                        let fileName = Path.Combine(path,"FSharp.Core.sigdata")
+                        if File.Exists(fileName) then
+                            Some (File.ReadAllBytes fileName)
+                        else
+                            None
+                    | None -> None
+                else
+                    None
+            | resourceStream ->
+                Some( resourceStream |> readToEnd)
+        match bytes with 
+        | None -> None
+        | Some bytes -> 
+            let data = unpickle_obj_with_dangling_ccus assembly.FullName sref unpickleModuleInfo bytes
+            let info = data.RawData
+            let ccuData = 
+                { ccu_scoref=sref;
+                  ccu_stamp = newStamp();
+                  ccu_filename = None; 
+                  ccu_qname= Some sref.QualifiedName;
+                  ccu_code_dir = info.compileTimeWorkingDir; 
+                  ccu_fsharp=true;
+                  ccu_contents = info.mspec; 
+                  ccu_usesQuotations = info.usesQuotations;
+                  ccu_memberSignatureEquality= (fun ty1 ty2 -> ApproxTypeEquiv.type_equiv_aux globals ty1 ty2);
+                  ccu_forwarders = PPLazy.Create (fun () -> Map.empty) }
+                    
+            let ccu = CcuThunk.Create(name, ccuData)
+            let assem = FSharpAssembly(ccu, Some assembly)
+            lock table (fun () -> table.[name] <- assem)
+            let info = data.OptionalFixup(fun nm -> match AssemblyLoader.TryLoad(nm) with Some x -> Some(x.RawCcuThunk) | _ -> None )
+            Some assem
+        
+
+and [<Sealed>] FSharpAssembly(ccu: CcuThunk, assemblyOpt: Assembly option) = 
+
+    member x.RawCcuThunk = ccu
+
+    static member FSharpLibrary with get() = AssemblyLoader.FSharpLibrary
+    
+    static member FromAssembly(assembly:Assembly) : FSharpAssembly = 
+        AssemblyLoader.Get(assembly)
+    
+    static member FromFile fileName =
+        let assembly = Assembly.LoadFrom fileName
+        if isNull assembly then invalidOp ("error loading assembly " + fileName)
+        FSharpAssembly.FromAssembly(assembly)
+    
+    member x.QualifiedName = ccu.QualifiedName.Value
+      
+    member x.CodeLocation = ccu.SourceCodeDirectory
+      
+    member x.ReflectionAssembly = 
+        match assemblyOpt with 
+        | None -> 
+            let res = Assembly.Load x.QualifiedName
+            if isNull res then invalidOp ("error loading assembly " + x.QualifiedName)
+            res
+        | Some x -> 
+            x
+
+    member x.GetEntity(name:string) = 
+        let path = name.Split [| '.' |]
+        if path.Length = 0 then invalidArg "name" "bad entity name"
+        let path1 = path.[0..path.Length-2] 
+        let nm = path.[path.Length-1]
+        let tcref  = mk_nonlocal_tcref (NonLocalEntityRef(ccu,path1)) nm
+        FSharpEntity(RealEntityRef tcref)
+      
+    member x.Entities = 
+        let rec loop(entity:Entity) = 
+            [| if entity.IsNamespace then 
+                  for entity in entity.ModuleOrNamespaceType.AllEntities do 
+                      yield! loop entity
+               elif isPublic entity.Accessibility  then
+                   yield FSharpEntity(RealEntityRef (rescopeEntity ccu entity)) 
+               else
+                   () |]
+        [| for entity in ccu.TopModulesAndNamespaces do 
+              yield! loop entity |] |> makeReadOnlyCollection
+                 
+
+and SimulatedEntityRef = 
+   | RealEntityRef of EntityRef
+   | FakeEntityRef of string
+
+and [<Sealed>] FSharpEntity(entity:SimulatedEntityRef) = 
+
+    static let computeIsExternal entity = 
+        match entity with 
+        | RealEntityRef (ERef_nonlocal (NonLocalEntityRef(ccu,_))) -> ccu.IsUnresolvedReference
+        | _ -> false
+
+    static let computeIsUnresolved entity = 
+        match entity with 
+        | RealEntityRef (ERef_nonlocal (NonLocalEntityRef(ccu,_)) as eref) -> ccu.IsUnresolvedReference && eref.TryDeref.IsNone 
+        | _ -> false
+
+    let isExternal() = computeIsExternal entity
+
+    let isUnresolved() = computeIsUnresolved entity
+
+    let poorAssembly() = 
+        match entity with 
+        | RealEntityRef entity -> System.Reflection.Assembly.LoadWithPartialName  entity.nlr.AssemblyName 
+        | FakeEntityRef _ -> FSharpAssembly.FSharpLibrary.ReflectionAssembly
+            
+    let poorQualifiedName() = 
+        match entity with 
+        | RealEntityRef entity -> 
+            if entity.nlr.AssemblyName = "mscorlib" then 
+                entity.nlr.DisplayName  + ", mscorlib"
+            else 
+                let ass = poorAssembly()
+                entity.nlr.DisplayName  + ", " + ass.FullName
+        | FakeEntityRef nm -> nm + ", " + (poorAssembly().FullName)
+            
+    let poorNamespace() = 
+        match entity with 
+        | RealEntityRef entity -> 
+            entity.nlr.EnclosingMangledPath |> String.concat "."
+        | FakeEntityRef  _ -> ""
+
+    let isFSharp() = 
+        not (isExternal()) && not (isUnresolved())
+
+    let checkIsFSharp() = 
+        if isExternal() then invalidOp (sprintf "The entity '%s' is external to F#. This operation may only be performed on an entity from an F# assembly" (poorQualifiedName()))
+        if isUnresolved() then invalidOp (sprintf "The entity '%s' does not exist or is in an unresolved assembly." (poorQualifiedName()))
+
+    static member FromType (ty: System.Type) = 
+        let assembly = ty.Assembly
+        let fassembly = FSharpAssembly.FromAssembly assembly
+        let gty = (if ty.IsGenericType then ty.GetGenericTypeDefinition() else ty)
+        let path = (if ty.IsGenericType then ty.GetGenericTypeDefinition() else ty).FullName.Split [| '.' |]
+        let path1 = if path.Length = 0 then [| |] else path.[0..path.Length-2] 
+        let nm = if path.Length = 0 then gty.Name else path.[path.Length-1]
+        let tcref  = mk_nonlocal_tcref (NonLocalEntityRef(fassembly.RawCcuThunk,path1)) nm
+        FSharpEntity(RealEntityRef tcref)
+
+    member private this.SimulatedEntity = entity
+
+    member x.ReflectionType  = 
+        let fail() = invalidOp (sprintf "the type %s is an abbreviation and does not have a System.Type" x.LogicalName)
+        match entity with 
+        | RealEntityRef entity -> 
+            // Don't call this: checkIsFSharp()   -- this one is valid on non-F# types
+            if isFSharp() && entity.IsTypeAbbrev then fail()
+            match System.Type.GetType x.QualifiedName  with 
+            | null -> invalidOp (sprintf "couldn't load type '%s'" x.QualifiedName)
+            | ty -> ty
+        | FakeEntityRef _ -> fail()
+        
+    member x.ReflectionAssembly = 
+        match entity with 
+        | RealEntityRef entity -> 
+            if isExternal() || isUnresolved() || (isFSharp() && (entity.IsTypeAbbrev || entity.IsMeasureableReprTycon || entity.IsAsmReprTycon)) then 
+                poorAssembly()     
+            else            
+                match entity.CompiledRepresentation with 
+                | TyrepNamed(tref,_,_) -> System.Type.GetType(x.QualifiedName).Assembly
+                | TyrepOpen _ -> typeof<int>.Assembly (* mscorlib *)
+        | FakeEntityRef _ -> FSharpAssembly.FSharpLibrary.ReflectionAssembly
+        
+
+    member x.LogicalName = 
+        match entity with 
+        | RealEntityRef entity -> 
+            if isFSharp() then entity.LogicalName else x.ReflectionType.Name
+        | FakeEntityRef  nm -> nm
+        
+
+    member x.CompiledName = 
+        match entity with 
+        | RealEntityRef entity -> 
+            if isFSharp() then entity.CompiledName else x.ReflectionType.Name
+        | FakeEntityRef nm -> nm
+
+    member x.DisplayName = 
+        match entity with 
+        | RealEntityRef entity -> 
+            if isFSharp() then 
+                if entity.IsModuleOrNamespace then entity.DemangledModuleOrNamespaceName
+                else entity.DisplayName 
+            else 
+                PrettyNaming.demangleGenericTypeName x.ReflectionType.Name
+        | FakeEntityRef nm -> nm
+
+    member x.Namespace = 
+        if isFSharp() then poorNamespace() else x.ReflectionType.Namespace
+
+    member x.DeclaringEntity = 
+        let fail() = invalidOp (sprintf "the type or module '%s' does not have a declaring entity" x.LogicalName)
+        match entity with 
+        | RealEntityRef entity -> 
+            match entity.PublicPath with 
+            | None -> fail()
+            | Some p -> 
+                let res = RealEntityRef(ERef_nonlocal(enclosing_nleref_of_pubpath entity.nlr.Ccu p))
+                if computeIsUnresolved res then  fail()
+                FSharpEntity res
+        | FakeEntityRef _ -> fail()
+    
+    
+    member x.QualifiedName = 
+        let fail() = invalidOp (sprintf "the type '%s' does not have a qualified name" x.LogicalName)
+        match entity with 
+        | RealEntityRef entity -> 
+            if isExternal() || isUnresolved() then 
+                poorQualifiedName()     
+            else            
+                if entity.IsTypeAbbrev then fail()
+                match entity.CompiledRepresentation with 
+                | TyrepNamed(tref,_,_) -> tref.QualifiedName
+                | TyrepOpen _ -> fail()
+        | _ -> fail()
+        
+
+    member x.DeclarationLocation = 
+        let fail() = invalidOp (sprintf "the type '%s' does not have a declaration location" x.LogicalName)
+        match entity with 
+        | RealEntityRef entity -> 
+            checkIsFSharp(); 
+            SourceLocation(entity.Range)
+        | FakeEntityRef _  -> fail()
+
+    member this.GenericParameters= 
+        checkIsFSharp(); 
+        match entity with 
+        | RealEntityRef entity -> 
+            let env = Env(entity.TyparsNoRange)
+            entity.TyparsNoRange |> List.map (fun tp -> FSharpGenericParameter(env,tp)) |> List.toArray |> makeReadOnlyCollection
+        | FakeEntityRef _  -> [ ] |> makeReadOnlyCollection
+
+    member x.IsMeasure = 
+        match entity with 
+        | RealEntityRef entity -> isFSharp() && (entity.TypeOrMeasureKind = KindMeasure)
+        | FakeEntityRef _ -> false
+    member x.IsModule = 
+        match entity with 
+        | RealEntityRef entity -> isFSharp() && entity.IsModule
+        | FakeEntityRef _ -> false
+    member x.HasFSharpModuleSuffix = 
+        match entity with 
+        | RealEntityRef entity -> isFSharp() && entity.IsModule && (entity.ModuleOrNamespaceType.ModuleOrNamespaceKind = ModuleOrNamespaceKind.FSharpModuleWithSuffix)
+        | FakeEntityRef _ -> false
+    member x.IsValueType  = 
+        match entity with 
+        | RealEntityRef entity -> if isFSharp() then entity.IsStructOrEnumTycon else x.ReflectionType.IsValueType
+        | FakeEntityRef _ -> false
+
+#if TODO
+    member x.IsClass = (not entity.IsNamespace && not entity.IsModule && entity.TypeOrMeasureKind = TyparKind.KindType)
+    member x.IsInterface = (not entity.IsNamespace && not entity.IsModule && entity.TypeOrMeasureKind = TyparKind.KindType)
+    member x.IsDelegate : bool
+    member x.IsAbstract : bool;                       
+    member x.IsEnum : bool
+#endif
+    
+    member x.IsExceptionDeclaration = 
+        match entity with 
+        | RealEntityRef entity -> isFSharp() && entity.IsExceptionDecl
+        | FakeEntityRef  _-> false
+
+    member x.IsExternal = 
+        isExternal()
+
+    member x.IsAbbreviation = 
+        match entity with 
+        | RealEntityRef entity -> isFSharp() && entity.IsTypeAbbrev 
+        | FakeEntityRef _ -> false
+
+    member x.IsRecord = 
+        match entity with 
+        | RealEntityRef entity -> isFSharp() && entity.IsRecordTycon
+        | FakeEntityRef _ -> false
+
+    member x.IsUnion = 
+        match entity with 
+        | RealEntityRef entity -> isFSharp() && entity.IsUnionTycon
+        | FakeEntityRef _ -> false
+
+    member x.HasAssemblyCodeRepresentation = 
+        match entity with 
+        | RealEntityRef entity -> isFSharp() && (entity.IsAsmReprTycon || entity.IsMeasureableReprTycon)
+        | FakeEntityRef _ -> false
+
+    static member op_Equality (left:FSharpEntity,right:FSharpEntity) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> left.Equals(right)
+    static member op_Inequality (left:FSharpEntity,right:FSharpEntity) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> not (left.Equals(right))
+
+
+#if TODO
+    member x.GetAssemblyCodeRepresentation : unit -> string 
+    // member TyconDelegateSlotSig : SlotSig option
+      
+
+#endif
+
+    member x.Accessibility = FSharpAccessibility() 
+    member x.RepresentationAccessibility = FSharpAccessibility()
+
+      /// Interface implementations - boolean indicates compiler-generated 
+    member this.Implements = 
+        match entity with 
+        | RealEntityRef entity -> 
+            checkIsFSharp(); 
+            let env = Env(entity.TyparsNoRange)
+            entity.InterfaceTypesOfFSharpTycon |> List.map (fun ty -> FSharpType(env,ty)) |> makeReadOnlyCollection
+        | FakeEntityRef _ -> 
+            makeReadOnlyCollection []
+
+      /// Super type, if any 
+    member this.BaseType = 
+        match entity with 
+        | RealEntityRef entity -> 
+            checkIsFSharp(); 
+            let env = Env(entity.TyparsNoRange)
+            match entity.TypeContents.tcaug_super with 
+            | None -> invalidOp "this entity has no base type"
+            | Some ty -> FSharpType(env,ty)
+        | FakeEntityRef _-> invalidOp "this entity has no base type"
+        
+      /// Indicates the type prefers the "tycon<a,b>" syntax for display etc. 
+    member x.UsesPrefixDisplay = 
+        match entity with 
+        | RealEntityRef entity -> not (isFSharp()) || entity.Deref.IsPrefixDisplay
+        | FakeEntityRef _ -> true
+
+
+      /// Properties, methods etc. with implementations
+    member this.MembersOrValues = 
+        match entity with 
+        | RealEntityRef entity -> 
+            checkIsFSharp(); 
+            ((entity.MembersOfFSharpTyconSorted
+              |> List.filter (fun v -> not v.IsOverrideOrExplicitImpl && 
+                                       not v.Deref.IsClassConstructor)
+              |> List.map (fun v -> FSharpMemberOrVal(this, v.Deref)))
+            @
+             (entity.ModuleOrNamespaceType.AllValsAndMembers
+              |> Seq.toList
+              |> List.filter (fun v -> v.IsExtensionMember || not v.IsMember) 
+              |> List.filter (fun v -> isPublic v.Accessibility) 
+              |> List.map (fun v -> FSharpMemberOrVal(this,v))))
+               
+              |> makeReadOnlyCollection
+        | FakeEntityRef _ -> 
+            makeReadOnlyCollection []
+
+    member x.XmlDocSig = 
+        match entity with 
+        | RealEntityRef entity -> 
+            checkIsFSharp(); 
+            entity.XmlDocSig 
+        | FakeEntityRef _ -> 
+            invalidOp "This entity does not have an XmlDocSig"
+
+    member x.NestedEntities = 
+        match entity with 
+        | RealEntityRef entity -> 
+            checkIsFSharp(); 
+            entity.ModuleOrNamespaceType.AllEntities 
+            |> QueueList.toList
+            |> List.filter (fun x -> isPublic x.Accessibility) 
+            |> List.map (fun x -> FSharpEntity(RealEntityRef (rescopeEntity entity.nlr.Ccu x)))
+            |> makeReadOnlyCollection
+        | FakeEntityRef _ -> 
+            makeReadOnlyCollection []
+
+    member this.UnionCases = 
+        match entity with 
+        | RealEntityRef entity -> 
+            checkIsFSharp(); 
+            let env = Env(entity.TyparsNoRange)
+            entity.UnionCasesAsList 
+            |> List.filter (fun x -> isPublic x.Accessibility) 
+            |> List.map (fun x -> FSharpUnionCase(env,x)) 
+            |> makeReadOnlyCollection
+        | FakeEntityRef _ -> 
+            makeReadOnlyCollection []
+
+    member this.RecordFields =
+        match entity with 
+        | RealEntityRef entity -> 
+            checkIsFSharp(); 
+            let env = Env(entity.TyparsNoRange)
+            entity.AllFieldsAsList 
+            |> List.filter (fun x -> isPublic x.Accessibility) 
+            |> List.map (fun x -> FSharpRecordField(env,x)) 
+            |> makeReadOnlyCollection
+        | FakeEntityRef _ -> 
+            makeReadOnlyCollection []
+
+    member this.AbbreviatedType   = 
+        match entity with 
+        | RealEntityRef entity -> 
+            checkIsFSharp(); 
+            let env = Env(entity.TyparsNoRange)
+            match entity.TypeAbbrev with 
+            | None -> invalidOp "not a type abbreviation"
+            | Some ty -> FSharpType(env,ty)
+        | FakeEntityRef _ -> 
+            invalidOp "not a type abbreviation"
+
+    member x.Attributes = 
+        match entity with 
+        | RealEntityRef entity -> 
+            checkIsFSharp(); 
+            entity.Attribs |> List.map (fun a -> FSharpAttribute(a)) |> makeReadOnlyCollection
+        | FakeEntityRef _ -> 
+            makeReadOnlyCollection []
+
+    override this.Equals(other : obj) =
+        if this :> obj === other then true
+        else
+            match other with
+            |   :? FSharpEntity as otherEntity ->
+                    match entity, otherEntity.SimulatedEntity with
+                    |   FakeEntityRef s1, FakeEntityRef s2 -> s1 = s2
+                    |   RealEntityRef eref1, RealEntityRef eref2 -> Tast.prim_entity_ref_eq eref1 eref2
+                    |   _ -> false
+            |   _ -> false
+
+    override this.GetHashCode() =
+        match entity with 
+        |   FakeEntityRef s -> (hash s) <<< 1
+        |   RealEntityRef er -> ((Tast.prim_entity_hash er) <<< 1) + 1
+
+
+and [<Sealed>] FSharpUnionCase(env:Env,v: UnionCase) =
+
+    member x.Name = v.DisplayName
+    member x.DeclarationLocation = SourceLocation(v.Range)
+    member this.Fields = v.RecdFields |> List.map (fun r -> FSharpRecordField(env,r)) |> List.toArray |> makeReadOnlyCollection
+    member x.ReturnType = FSharpType(env,v.ucase_rty)
+    member x.CompiledName = v.ucase_il_name
+    member x.XmlDocSig = v.XmlDocSig
+    member x.Attributes = v.Attribs |> List.map (fun a -> FSharpAttribute(a)) |> makeReadOnlyCollection
+    member x.Accessibility =  FSharpAccessibility();
+
+    member private this.V = v
+    override this.Equals(o : obj) =
+        if this :> obj === o then true
+        else
+            match o with
+            |   :? FSharpUnionCase as uc -> v === uc.V
+            |   _ -> false
+    
+    override this.GetHashCode() = (hash (box v))
+
+    static member op_Equality (left:FSharpUnionCase,right:FSharpUnionCase) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> left.Equals(right)
+    static member op_Inequality (left:FSharpUnionCase,right:FSharpUnionCase) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> not (left.Equals(right))
+
+
+and 
+    [<RequireQualifiedAccess>]
+    RecordFieldContainer = Entity of FSharpEntity | UnionCase of FSharpUnionCase
+
+and [<Sealed>] FSharpRecordField(env:Env,v: RecdField) =
+    member x.IsMutable = v.IsMutable
+    member x.XmlDocSig = v.XmlDocSig
+    member x.Type = 
+        FSharpType(env,v.FormalType)
+    member x.IsStatic = v.IsStatic
+    member x.Name = v.Name
+    member x.IsCompilerGenerated = v.IsCompilerGenerated
+    member x.DeclarationLocation = SourceLocation(v.Range)
+    member x.FieldAttributes = v.FieldAttribs |> List.map (fun a -> FSharpAttribute(a)) |> makeReadOnlyCollection
+    member x.PropertyAttributes = v.PropertyAttribs |> List.map (fun a -> FSharpAttribute(a)) |> makeReadOnlyCollection
+    //member x.LiteralValue = v.Is
+    member x.Accessibility =  FSharpAccessibility() 
+    member private this.V = v
+    override this.Equals(o : obj) =
+        if this :> obj === o then true
+        else
+            match o with
+            |   :? FSharpRecordField as uc -> v === uc.V
+            |   _ -> false
+
+    override this.GetHashCode() = (hash (box v))
+    static member op_Equality (left:FSharpRecordField,right:FSharpRecordField) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> left.Equals(right)
+    static member op_Inequality (left:FSharpRecordField,right:FSharpRecordField) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> not (left.Equals(right))
+
+
+and [<Sealed>] FSharpAccessibility() = 
+    //member x.IsPublic : bool
+    //member x.IsPrivate : bool
+    //member x.IsInternal : bool
+    class
+    end
+
+and [<RequireQualifiedAccess>]
+    GenericParameterContainer = Entity of FSharpEntity | MemberOrVal of FSharpMemberOrVal
+
+and [<Sealed>] FSharpGenericParameter(env:Env,v:Typar) = 
+
+    member x.Name = v.DisplayName
+    member x.DeclarationLocation = SourceLocation(v.Range)
+       
+    member x.IsMeasure = (v.Kind = TyparKind.KindMeasure)
+
+    member x.XmlDoc = v.Data.typar_xmldoc |> makeXmlDoc
+
+    member x.IsSolveAtCompileTime = (v.StaticReq = TyparStaticReq.HeadTypeStaticReq)
+       
+    member x.Attributes = v.Attribs |> List.map (fun a -> FSharpAttribute(a)) |> makeReadOnlyCollection
+
+    member x.Constraints = v.Constraints |> List.map (fun a -> FSharpGenericParameterConstraint(env,a)) |> makeReadOnlyCollection
+    
+    member private this.V = v
+
+    override this.Equals(o : obj) =
+        if this :> obj === o then true
+        else
+            match o with
+            |   :? FSharpGenericParameter as p -> typar_ref_eq v p.V
+            |   _ -> false
+    override this.GetHashCode() = (typar_ref_hash v)
+
+    static member op_Equality (left:FSharpGenericParameter,right:FSharpGenericParameter) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> left.Equals(right)
+    static member op_Inequality (left:FSharpGenericParameter,right:FSharpGenericParameter) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> not (left.Equals(right))
+
+
+and [<Sealed>] FSharpGenericParameterConstraint(env : Env, cx : TyparConstraint) = 
+
+    member x.IsMemberConstraint = 
+        match cx with 
+        | TTyparMayResolveMemberConstraint _ -> true 
+        | _ -> false
+
+    /// Indicates a constraint that a type is a subtype of the given type 
+    member x.IsCoercesToConstraint = 
+        match cx with 
+        | TTyparCoercesToType _ -> true 
+        | _ -> false
+
+    member x.CoercesToTarget = 
+        match cx with 
+        | TTyparCoercesToType(ty,_) -> FSharpType(env,ty) 
+        | _ -> invalidOp "not a coerces-to constraint"
+
+    /// Indicates a default value for an inference type variable should it be netiher generalized nor solved 
+    member x.IsDefaultsToConstraint = 
+        match cx with 
+        | TTyparDefaultsToType _ -> true 
+        | _ -> false
+
+    member x.DefaultsToPriority = 
+        match cx with 
+        | TTyparDefaultsToType(pri,_,_) -> pri 
+        | _ -> invalidOp "incorrect constraint kind"
+
+    member x.DefaultsToTarget = 
+        match cx with 
+        | TTyparDefaultsToType(_,ty,_) -> FSharpType(env,ty) 
+        | _ -> invalidOp "incorrect constraint kind"
+
+    /// Indicates a constraint that a type has a 'null' value 
+    member x.IsSupportsNullConstraint  = match cx with TTyparSupportsNull _ -> true | _ -> false
+
+    member x.MemberSources = 
+        match cx with 
+        | TTyparMayResolveMemberConstraint(TTrait(tys,_,_,_,_,_),_) -> tys   |> List.map (fun ty -> FSharpType(env,ty)) |> makeReadOnlyCollection
+        | _ -> invalidOp "incorrect constraint kind"
+
+    member x.MemberName = 
+        match cx with 
+        | TTyparMayResolveMemberConstraint(TTrait(_,nm,_,_,_,_),_) -> nm  
+        | _ -> invalidOp "incorrect constraint kind"
+
+    member x.MemberIsStatc = 
+        match cx with 
+        | TTyparMayResolveMemberConstraint(TTrait(_,_,flags,_,_,_),_) -> not flags.MemberIsInstance  
+        | _ -> invalidOp "incorrect constraint kind"
+
+    member x.MemberArgumentTypes = 
+        match cx with 
+        | TTyparMayResolveMemberConstraint(TTrait(_,_,_,tys,_,_),_) -> tys   |> List.map (fun ty -> FSharpType(env,ty)) |> makeReadOnlyCollection
+        | _ -> invalidOp "incorrect constraint kind"
+
+    member this.MemberReturnType = 
+        match cx with 
+        | TTyparMayResolveMemberConstraint(TTrait(tys,_,_,_,rty,_),_) -> 
+            match rty with 
+            | None -> FSharpType(env,TType_app(AssemblyLoader.TcGlobals.unit_tcr,[])) 
+            | Some ty -> FSharpType(env,ty) 
+        | _ -> invalidOp "incorrect constraint kind"
+
+    /// Indicates a constraint that a type is a non-Nullable value type 
+    member x.IsNonNullableValueTypeConstraint = 
+        match cx with 
+        | TTyparIsNotNullableValueType _ -> true 
+        | _ -> false
+    
+    /// Indicates a constraint that a type is a reference type 
+    member x.IsReferenceTypeConstraint  = 
+        match cx with 
+        | TTyparIsReferenceType _ -> true 
+        | _ -> false
+
+    /// Indicates a constraint that a type is a simple choice between one of the given ground types. Used by printf format strings.
+    member x.IsSimpleChoiceConstraint = 
+        match cx with 
+        | TTyparSimpleChoice _ -> true 
+        | _ -> false
+
+    member x.SimpleChoices = 
+        match cx with 
+        | TTyparSimpleChoice (tys,_) -> 
+            tys   |> List.map (fun ty -> FSharpType(env,ty)) |> makeReadOnlyCollection
+        | _ -> invalidOp "incorrect constraint kind"
+
+    /// Indicates a constraint that a type has a parameterless constructor 
+    member x.IsRequiresDefaultConstructorConstraint  = match cx with TTyparRequiresDefaultConstructor _ -> true | _ -> false
+
+    /// Indicates a constraint that a type is an enum with the given underlying 
+    member x.IsEnumConstraint = 
+        match cx with 
+        | TTyparIsEnum _ -> true 
+        | _ -> false
+
+    member x.EnumConstraintTarget = 
+        match cx with 
+        | TTyparIsEnum(ty,_) -> 
+            FSharpType(env,ty)
+        | _ -> invalidOp "incorrect constraint kind"
+    
+    member x.IsComparisonConstraint = 
+        match cx with 
+        | TTyparSupportsComparison _ -> true 
+        | _ -> false
+
+    member x.IsEqualityConstraint = 
+        match cx with 
+        | TTyparSupportsEquality _ -> true 
+        | _ -> false
+
+    member x.IsUnmanagedConstraint = 
+        match cx with 
+        | TyparConstraint.TTyparIsUnmanaged _ -> true 
+        | _ -> false
+
+    /// Indicates a constraint that a type is a delegate from the given tuple of args to the given return type 
+    member x.IsDelegateConstraint = 
+        match cx with 
+        | TTyparIsDelegate _ -> true 
+        | _ -> false
+
+    member x.DelegateTupledArgumentType = 
+        match cx with 
+        | TTyparIsDelegate (tupledArgTyp,_,_) -> 
+            FSharpType(env,tupledArgTyp)
+        | _ -> invalidOp "incorrect constraint kind"
+ 
+    member x.DelegateReturnType = 
+        match cx with 
+        | TTyparIsDelegate (_,rty,_) -> 
+            FSharpType(env,rty)
+        | _ -> invalidOp "incorrect constraint kind"
+
+and FSharpInlineAnnotation = 
+   | PsuedoValue = 3
+   | AlwaysInline = 2
+   | OptionalInline = 1
+   | NeverInline = 0
+
+and [<Sealed>] FSharpMemberOrVal(e:FSharpEntity,v:Val) = 
+
+    let g = AssemblyLoader.TcGlobals
+    let is_unit_typ ty = 
+        let ty = ApproxTypeEquiv.strip_tpeqns_and_tcabbrevs g ty 
+        match ty with 
+        | TType_app (tcr,_) -> prim_entity_ref_eq g.unit_tcr tcr 
+        | _ -> false
+
+    let is_fun_typ ty = 
+        let ty = ApproxTypeEquiv.strip_tpeqns_and_tcabbrevs g ty 
+        match ty with TType_fun _ -> true | _ -> false
+
+    let dest_fun_typ ty = 
+        let ty = ApproxTypeEquiv.strip_tpeqns_and_tcabbrevs g ty 
+        match ty with TType_fun (d,r) -> (d,r) | _ -> failwith "dest_fun_typ"
+
+    let dest_tuple_typ ty = 
+        let ty = ApproxTypeEquiv.strip_tpeqns_and_tcabbrevs g ty 
+        if is_unit_typ ty then [] else match ty with TType_tuple tys -> tys | _ -> [ty]
+
+    let rec strip_fun_typ_upto n ty = 
+        assert (n >= 0);
+        if n > 0 && is_fun_typ ty then 
+            let (d,r) = dest_fun_typ ty
+            let more,rty = strip_fun_typ_upto (n-1) r in d::more, rty
+        else [],ty
+
+    (* A 'tau' type is one with its type paramaeters stripped off *)
+    let GetTopTauTypeInFSharpForm (curriedArgInfos: TopArgInfo list list) tau m =
+
+        let argtys,rty = strip_fun_typ_upto curriedArgInfos.Length tau
+
+        if curriedArgInfos.Length <> argtys.Length then 
+            error(Error((0,"Invalid member signature encountered because of an earlier error"),m))
+
+        let argtysl = 
+            (curriedArgInfos,argtys) ||> List.map2 (fun argInfos argty -> 
+                match argInfos with 
+                | [] -> [] //else [ (mk_unit_typ g, TopValInfo.unnamedTopArg1) ]
+                | [argInfo] -> [ (argty, argInfo) ]
+                | _ -> List.zip (dest_tuple_typ argty) argInfos) 
+        argtysl,rty
+
+    member x.DeclarationLocation = SourceLocation(v.Range)
+
+    member x.LogicalEnclosingEntity = 
+        match v.ApparentParent with 
+        | ParentNone -> invalidOp "the value or member doesn't have a logical parent" 
+        | Parent p -> FSharpEntity(RealEntityRef p)
+
+    member this.GenericParameters = 
+        let env = Env(v.Typars)
+        v.Typars |> List.map (fun tp -> FSharpGenericParameter(env,tp)) |> List.toArray |> makeReadOnlyCollection
+
+    member this.Type = 
+        FSharpType(Env(v.Typars),v.TauType)
+
+    member x.EnclosingEntity = e
+
+    member x.IsCompilerGenerated = v.IsCompilerGenerated
+
+    member x.InlineAnnotation = 
+        match v.InlineInfo with 
+        | ValInlineInfo.PseudoValue -> FSharpInlineAnnotation.PsuedoValue
+        | ValInlineInfo.AlwaysInline -> FSharpInlineAnnotation.AlwaysInline
+        | ValInlineInfo.OptionalInline -> FSharpInlineAnnotation.OptionalInline
+        | ValInlineInfo.NeverInline -> FSharpInlineAnnotation.NeverInline
+
+    member x.IsMutable = v.IsMutable
+
+    member x.IsModuleValueOrMember = v.IsMember || v.IsModuleBinding
+    member x.IsMember = v.IsMember 
+    
+    member x.IsDispatchSlot = v.IsDispatchSlot
+
+    member x.IsGetterMethod = match v.MemberInfo with None -> false | Some memInfo -> memInfo.MemberFlags.MemberKind = MemberKindPropertyGet
+    member x.IsSetterMethod = match v.MemberInfo with None -> false | Some memInfo -> memInfo.MemberFlags.MemberKind = MemberKindPropertySet
+
+    member x.IsInstanceMember = v.IsInstanceMember
+
+    member x.IsExtensionMember = v.IsExtensionMember
+
+    member x.IsImplicitConstructor = v.IsIncrClassConstructor
+    
+    member x.IsTypeFunction = v.IsTypeFunction
+
+    member x.IsActivePattern =  
+        v.CoreDisplayName |> PrettyNaming.activePatternInfoOfValName |> isSome
+
+    member x.CompiledName = v.CompiledName
+
+    member x.LogicalName = v.LogicalName
+
+    member x.DisplayName = v.DisplayName
+
+    member x.XmlDocSig = v.XmlDocSig
+
+
+    member this.CurriedParameterGroups = 
+        let env = Env(v.Typars)
+        match v.TopValInfo with 
+        | None -> failwith "not a module let binding or member"
+        | Some (TopValInfo(typars,curriedArgInfos,retInfo)) -> 
+            let tau = v.TauType
+            let argtysl,_ = GetTopTauTypeInFSharpForm curriedArgInfos tau range0
+            let argtysl = if v.IsInstanceMember then argtysl.Tail else argtysl
+            
+            [ for argtys in argtysl do 
+                 yield 
+                   [ for argty, argInfo in argtys do 
+                        yield FSharpParameter(env,argty,argInfo) ] 
+                   |> makeReadOnlyCollection ]
+             |> makeReadOnlyCollection
+
+    member x.ReflectionMemberInfo = 
+        let ty = e.ReflectionType
+        let possibles = ty.GetMember(v.CompiledName)  
+        if possibles.Length = 0 then invalidOp (sprintf "member %s not found" v.CompiledName)
+        else possibles.[0]
+        // invalidOp "member ambiguous"
+        
+    member this.ReturnParameter  = 
+
+        let env = Env(v.Typars)
+        match v.TopValInfo with 
+        | None -> failwith "not a module let binding or member"; 
+        | Some (TopValInfo(typars,argInfos,retInfo)) -> 
+        
+            let tau = v.TauType
+            let _,rty = GetTopTauTypeInFSharpForm argInfos tau range0
+            
+            FSharpParameter(env,rty,retInfo) 
+
+
+    member x.Attributes = v.Attribs |> List.map (fun a -> FSharpAttribute(a)) |> makeReadOnlyCollection
+     
+(*
+    /// Is this "base" in "base.M(...)"
+    member x.IsBaseValue : bool
+
+    /// Is this the "x" in "type C() as x = ..."
+    member x.IsConstructorThisValue : bool
+
+    /// Is this the "x" in "member x.M = ..."
+    member x.IsMemberThisValue : bool
+
+    /// Is this a [<Literal>] value, and if so what value?
+    member x.LiteralValue : obj // may be null
+
+
+      /// Get the module, type or namespace where this value appears. For 
+      /// an extension member this is the type being extended 
+    member x.ApparentParent: FSharpEntity
+
+     /// Get the module, type or namespace where this value is compiled
+    member x.ActualParent: FSharpEntity;
+
+*)
+
+      /// How visible is this? 
+    member x.Accessibility = FSharpAccessibility()
+
+    member private this.V = v
+    override this.Equals(o : obj) =
+        if this :> obj === o then true
+        else
+            match o with
+            |   :? FSharpMemberOrVal as other -> v === this.V
+            |   _ -> false
+    override this.GetHashCode() = (hash (box v))
+    static member op_Equality (left:FSharpMemberOrVal,right:FSharpMemberOrVal) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> left.Equals(right)
+    static member op_Inequality (left:FSharpMemberOrVal,right:FSharpMemberOrVal) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> not (left.Equals(right))
+
+
+and [<Sealed>] FSharpType(env:Env, typ:typ) =
+
+    member x.IsNamed = (match typ with TType_app _ | TType_measure (MeasureCon _ | MeasureProd _ | MeasureInv _ | MeasureOne _) -> true | _ -> false)
+    member x.IsTuple = (match typ with TType_tuple _ -> true | _ -> false)
+
+    member x.NamedEntity = 
+        match typ with 
+        | TType_app (tcref,_) -> FSharpEntity(RealEntityRef tcref) 
+        | TType_measure (MeasureCon tcref) ->  FSharpEntity(RealEntityRef tcref) 
+        | TType_measure (MeasureProd (t1,t2)) ->  FSharpEntity(FakeEntityRef "*") 
+        | TType_measure MeasureOne ->  FSharpEntity(FakeEntityRef "1") 
+        | TType_measure (MeasureInv t1) ->  FSharpEntity(FakeEntityRef "/") 
+        | _ -> invalidOp "not a named type"
+
+    member x.GenericArguments = 
+        match typ with 
+        | TType_app (_,tyargs) 
+        | TType_tuple (tyargs) -> (tyargs |> List.map (fun ty -> FSharpType(env,ty)) |> makeReadOnlyCollection) 
+        | TType_fun(d,r) -> [| FSharpType(env,d); FSharpType(env,r) |] |> makeReadOnlyCollection
+        | TType_measure (MeasureCon tcref) ->  [| |] |> makeReadOnlyCollection
+        | TType_measure (MeasureProd (t1,t2)) ->  [| FSharpType(env,TType_measure t1); FSharpType(env,TType_measure t2) |] |> makeReadOnlyCollection
+        | TType_measure MeasureOne ->  [| |] |> makeReadOnlyCollection
+        | TType_measure (MeasureInv t1) ->  [| FSharpType(env,TType_measure t1); |] |> makeReadOnlyCollection
+        | _ -> invalidOp "not a named type"
+
+
+    member x.IsFunction = (match typ with TType_fun _ -> true | _ -> false)
+
+    member x.IsGenericParameter= 
+        match typ with 
+        | TType_var _ -> true 
+        | TType_measure (MeasureVar _) -> true 
+        | _ -> false
+
+    member x.GenericParameter = 
+        match typ with 
+        | TType_var tp 
+        | TType_measure (MeasureVar tp) -> 
+            FSharpGenericParameter (env, env.Typars |> Array.find (fun tp2 -> typar_ref_eq tp tp2)) 
+        | _ -> invalidOp "not a generic parameter type"
+
+    member x.GenericParameterIndex = 
+        match typ with 
+        | TType_var tp 
+        | TType_measure (MeasureVar tp) -> 
+            env.Typars |> Array.findIndex (fun tp2 -> typar_ref_eq tp tp2)
+        | _ -> invalidOp "not a generic parameter type"
+
+    member private x.Typ = typ
+
+    override this.Equals(other : obj) =
+        if this :> obj === other then true
+        else
+            match other with
+            |   :? FSharpType as t -> tau_typ_eq typ t.Typ
+            |   _ -> false
+    override this.GetHashCode() = tau_typ_hash typ
+    static member op_Equality (left:FSharpType,right:FSharpType) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> left.Equals(right)
+    static member op_Inequality (left:FSharpType,right:FSharpType) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> not (left.Equals(right))
+
+
+and [<Sealed>] FSharpAttribute(attrib) = 
+
+#if FSHARP_1_9_7
+    let (Attrib(tcref,kind,unnamedArgs,propVals,m)) = attrib
+#else
+    let (Attrib(tcref,kind,unnamedArgs,propVals,_,m)) = attrib
+#endif
+
+    member x.ReflectionType : System.Type = 
+        match kind with 
+        | ILAttrib(mspec) -> 
+            System.Type.GetType(mspec.EnclosingTypeRef.QualifiedName)
+        | FSAttrib(vref) -> 
+            System.Type.GetType(tcref.CompiledRepresentationForTyrepNamed.QualifiedName)
+
+    member x.Value = 
+        let ty = x.ReflectionType
+        let fail() = failwith "This custom attribute has an argument that can not yet be converted using this API"
+        let evalArg e = 
+            match e with
+            | TExpr_const(c,m,_) -> 
+                match c with 
+                | TConst_bool b -> box b
+                | TConst_sbyte  i  -> box i
+                | TConst_int16  i  -> box  i
+                | TConst_int32 i   -> box i
+                | TConst_int64 i   -> box i  
+                | TConst_byte i    -> box i
+                | TConst_uint16 i  -> box i
+                | TConst_uint32 i  -> box i
+                | TConst_uint64 i  -> box i
+                | TConst_float i   -> box i
+                | TConst_float32 i -> box i
+                | TConst_char i    -> box i
+                | TConst_zero -> null
+                | TConst_string s ->  box s
+                | _ -> fail()
+            | _ -> fail()
+        let args = unnamedArgs |> List.map (fun (AttribExpr(_,e)) -> evalArg e) |> List.toArray
+        let res = System.Activator.CreateInstance(ty,args)
+        propVals |> List.iter (fun (AttribNamedArg(nm,_,isField,AttribExpr(_, e))) -> 
+            ty.InvokeMember(nm,BindingFlags.Public ||| BindingFlags.NonPublic ||| (if isField then BindingFlags.SetField else BindingFlags.SetProperty),
+                            null,res,[| evalArg e |]) |> ignore)
+        res
+
+    member private this.Attrib = attrib
+    override this.Equals(o : obj) =
+        if box this === o then true
+        else 
+            match o with
+            |   :? FSharpAttribute as other -> attrib === other.Attrib
+            |   _ -> false
+
+    override this.GetHashCode() = hash (box attrib)
+    static member op_Equality (left:FSharpAttribute,right:FSharpAttribute) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> left.Equals(right)
+    static member op_Inequality (left:FSharpAttribute,right:FSharpAttribute) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> not (left.Equals(right))
+
+    
+and [<Sealed>] FSharpParameter(env:Env,typ:typ,topArgInfo:TopArgInfo) = 
+#if FSHARP_1_9_7
+    let (TopArgInfo(attribs,idOpt)) = topArgInfo
+#else
+    let attribs = topArgInfo.Attribs
+    let idOpt = topArgInfo.Name
+#endif
+    member x.Name = match idOpt with None -> null | Some v -> v.idText
+    member x.Type = FSharpType(env,typ)
+    member x.DeclarationLocation = SourceLocation(match idOpt with None -> range0 | Some v -> v.idRange)
+    member x.Attributes = attribs |> List.map (fun a -> FSharpAttribute(a)) |> makeReadOnlyCollection
+    
+    member private x.TopArgInfo = topArgInfo
+
+    override this.Equals(o : obj) =
+        if box this === o then true
+        else
+            match o with
+            |   :? FSharpParameter as p -> topArgInfo === p.TopArgInfo
+            |   _ -> false
+    override this.GetHashCode() = hash (box topArgInfo)
+
+    static member op_Equality (left:FSharpParameter,right:FSharpParameter) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> left.Equals(right)
+    static member op_Inequality (left:FSharpParameter,right:FSharpParameter) =
+        match box left, box right with
+        |   null, null -> true
+        |   null, _ | _, null -> false
+        |   _ -> not (left.Equals(right))
diff --git a/src/FSharp.PowerPack.Metadata/Metadata.fsi b/src/FSharp.PowerPack.Metadata/Metadata.fsi
new file mode 100755
index 0000000..33abd0a
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/Metadata.fsi
@@ -0,0 +1,470 @@
+// (c) Microsoft Corporation 2005-2009
+namespace Microsoft.FSharp.Metadata
+
+open System.Collections.ObjectModel
+
+type [<Sealed>] SourceLocation = 
+   member Document : string
+   member StartLine : int
+   member StartColumn : int
+   member EndLine : int
+   member EndColumn : int
+     
+type [<Sealed>] FSharpAssembly = 
+
+    /// Get the object representing the F# core library (FSharp.Core.dll) for the running program
+    static member FSharpLibrary : FSharpAssembly
+
+    /// This is one way of starting the loading process off. Dependencies are automatically
+    /// resolved by calling System.Reflection.Assembly.Load.
+    static member FromAssembly : System.Reflection.Assembly -> FSharpAssembly
+
+    /// This is one way of starting the loading process off. 
+    static member FromFile : fileName: string (* * loader:System.Func<string,FSharpAssembly> *) -> FSharpAssembly
+
+    /// Holds the full qualified assembly name
+    member QualifiedName: string; 
+    
+    /// Get the System.Reflection.Assembly object for the assembly
+    member ReflectionAssembly: System.Reflection.Assembly
+      
+    /// Return the System.Reflection.Assembly object for the assembly
+    member GetEntity : string -> FSharpEntity
+      
+      /// A hint as to where does the code for the CCU live (e.g what was the tcConfig.implicitIncludeDir at compilation time for this DLL?) 
+    member CodeLocation: string; 
+      
+      /// A handle to the full specification of the contents of the module contained in this Assembly 
+    member Entities:  ReadOnlyCollection<FSharpEntity>
+
+/// Represents an F# type or module
+and [<Sealed>] FSharpEntity = 
+
+      /// Return the FSharpEntity corresponding to a .NET type
+    static member FromType : System.Type -> FSharpEntity
+
+      /// Get the name of the type or module, possibly with `n mangling  
+    member LogicalName: string;
+
+      /// Get the compiled name of the type or module, possibly with `n mangling. This is identical to LogicalName
+      /// unless the CompiledName attribute is used.
+    member CompiledName: string;
+
+      /// Get the name of the type or module as displayed in F# code
+    member DisplayName: string;
+
+      /// Get the namespace containing the type or module, if any
+    member Namespace: string;
+
+      /// Get the entity containing the type or module, if any
+    member DeclaringEntity: FSharpEntity;
+
+      /// Get the fully qualified name of the type or module
+    member QualifiedName: string; 
+
+
+      /// Get the declaration location for the type constructor 
+    member DeclarationLocation: SourceLocation; 
+
+      /// Indicates the entity is a measure, type or exception abbreviation
+    member IsAbbreviation   : bool
+
+      /// Indicates the entity is record type
+    member IsRecord   : bool
+
+      /// Indicates the entity is union type
+    member IsUnion   : bool
+
+      /// Indicates the entity is a struct or enum
+    member IsValueType : bool
+
+
+      /// Indicates the entity is an F# module definition
+    member IsModule: bool; 
+
+      /// Get the generic parameters, possibly including unit-of-measure parameters
+    member GenericParameters: ReadOnlyCollection<FSharpGenericParameter>
+
+      /// Indicates that a module is compiled to a class with the given mangled name. The mangling is reversed during lookup 
+    member HasFSharpModuleSuffix : bool
+
+      /// Indicates the entity is a measure definition
+    member IsMeasure: bool;
+
+      /// Indicates an F# exception declaration
+    member IsExceptionDeclaration: bool; 
+
+    /// If true, then this is a reference to something in some .NET assembly from another .NET language
+    member IsExternal : bool
+
+    /// Get the System.Type for the type
+    ///
+    /// Raises InvalidOperationException if the type is an abbreviation or has an assembly code representation.
+    member ReflectionType : System.Type  
+
+    /// Get the System.Reflection.Assembly for the type
+    ///
+    /// May raise an exception if an assembly load fails
+    member ReflectionAssembly : System.Reflection.Assembly
+
+
+      /// Get the XML documentation signature for the entity
+    member XmlDocSig: string;
+
+      /// Indicates the type is implemented through a mapping to IL assembly code. THis is only
+      /// true for types in FSharp.Core.dll
+    member HasAssemblyCodeRepresentation: bool 
+
+    
+      /// Indicates the type prefers the "tycon<a,b>" syntax for display etc. 
+    member UsesPrefixDisplay: bool;                   
+
+      /// Get the declared attributes for the type 
+    member Attributes: ReadOnlyCollection<FSharpAttribute>;     
+
+      /// Interface implementations - boolean indicates compiler-generated 
+    member Implements : ReadOnlyCollection<FSharpType>;  
+
+      /// Base type, if any 
+    member BaseType : FSharpType;
+
+
+      /// Properties, methods etc. with implementations, also values in a module
+    member MembersOrValues : ReadOnlyCollection<FSharpMemberOrVal>;
+
+    member NestedEntities : ReadOnlyCollection<FSharpEntity>
+
+      /// Get the fields of the class, struct or enum 
+    member RecordFields : ReadOnlyCollection<FSharpRecordField>
+
+    member AbbreviatedType   : FSharpType 
+
+      /// Get the cases of a discriminated union
+    member UnionCases : ReadOnlyCollection<FSharpUnionCase>
+
+
+#if TODO
+      /// Indicates the type is implemented as IL assembly code using a closed type in ILDASM syntax
+      // NOTE: consider returning a System.Type
+    member GetAssemblyCodeRepresentation : unit -> string 
+
+
+    //   /// Indicates the type is a delegate with the given Invoke signature 
+    // member TyconDelegateSlotSig : SlotSig option
+
+
+#endif
+      /// Get the declared accessibility of the type
+    member Accessibility: FSharpAccessibility; 
+
+      /// Get the declared accessibility of the representation, not taking signatures into account 
+    member RepresentationAccessibility: FSharpAccessibility;
+
+    static member op_Equality : FSharpEntity * FSharpEntity -> bool
+    static member op_Inequality : FSharpEntity * FSharpEntity -> bool
+
+and [<Sealed>] FSharpUnionCase =
+      /// Get the name of the case 
+    member Name: string; 
+      /// Get the range of the name of the case 
+    member DeclarationLocation : SourceLocation
+    /// Get the data carried by the case. 
+    member Fields: ReadOnlyCollection<FSharpRecordField>;
+      /// Get type constructed by the case. Normally exactly the type of the enclosing type, sometimes an abbreviation of it 
+    member ReturnType: FSharpType;
+      /// Gete the name of the case in generated IL code 
+    member CompiledName: string;
+      /// Get the XML documentation signature for the case 
+    member XmlDocSig: string;
+
+      ///  Indicates the declared visibility of the union constructor, not taking signatures into account 
+    member Accessibility: FSharpAccessibility; 
+
+      /// Get the attributes for the case, attached to the generated static method to make instances of the case 
+    member Attributes: ReadOnlyCollection<FSharpAttribute>;
+
+    static member op_Equality : FSharpUnionCase * FSharpUnionCase -> bool
+    static member op_Inequality : FSharpUnionCase * FSharpUnionCase -> bool
+
+
+and [<Sealed>] FSharpRecordField =
+    /// Is the field declared in F#? 
+    member IsMutable: bool;
+      /// Get the XML documentation signature for the field 
+    member XmlDocSig: string;
+      /// Get the type of the field, w.r.t. the generic parameters of the enclosing type constructor 
+    member Type: FSharpType;
+      /// Indicates a static field 
+    member IsStatic: bool;
+      /// Indicates a compiler generated field, not visible to Intellisense or name resolution 
+    member IsCompilerGenerated: bool;
+      /// Get the declaration location of the field 
+    member DeclarationLocation: SourceLocation;
+      /// Get the attributes attached to generated property 
+    member PropertyAttributes: ReadOnlyCollection<FSharpAttribute>; 
+      /// Get the attributes attached to generated field 
+    member FieldAttributes: ReadOnlyCollection<FSharpAttribute>; 
+      /// Get the name of the field 
+    member Name : string
+
+#if TODO
+      /// Get the default initialization info, for static literals 
+    member LiteralValue: obj; 
+#endif
+      ///  Indicates the declared visibility of the field, not taking signatures into account 
+    member Accessibility: FSharpAccessibility; 
+
+    static member op_Equality : FSharpRecordField * FSharpRecordField -> bool
+    static member op_Inequality : FSharpRecordField * FSharpRecordField -> bool
+
+and [<Sealed>] FSharpAccessibility = 
+#if TODO
+    member IsPublic : bool
+    member IsPrivate : bool
+    member IsInternal : bool
+#endif
+
+    class
+    end
+        
+and [<Sealed>] FSharpGenericParameter = 
+    /// Get the name of the generic parameter 
+    member Name: string
+    /// Get the range of the generic parameter 
+    member DeclarationLocation : SourceLocation; 
+       
+    /// Indicates if this is a measure variable
+    member IsMeasure : bool
+
+    /// Get the documentation for the type parameter. 
+    member XmlDoc : ReadOnlyCollection<string>;
+       
+    /// Indicates if this is a statically resolved type variable
+    member IsSolveAtCompileTime : bool 
+
+    /// Get the declared attributes of the type parameter. 
+    member Attributes: ReadOnlyCollection<FSharpAttribute>;                      
+       
+    /// Get the declared or inferred constraints for the type parameter
+    member Constraints: ReadOnlyCollection<FSharpGenericParameterConstraint>; 
+
+    static member op_Equality : FSharpGenericParameter * FSharpGenericParameter -> bool
+    static member op_Inequality : FSharpGenericParameter * FSharpGenericParameter -> bool
+
+
+and [<Sealed>][<NoEquality>][<NoComparison>] 
+    FSharpGenericParameterConstraint = 
+    /// Indicates a constraint that a type is a subtype of the given type 
+    member IsCoercesToConstraint : bool
+    member CoercesToTarget : FSharpType 
+
+    /// Indicates a default value for an inference type variable should it be netiher generalized nor solved 
+    member IsDefaultsToConstraint : bool
+    member DefaultsToPriority : int
+    member DefaultsToTarget : FSharpType
+
+    /// Indicates a constraint that a type has a 'null' value 
+    member IsSupportsNullConstraint  : bool
+
+    /// Indicates a constraint that a type supports F# generic comparison
+    member IsComparisonConstraint  : bool
+
+    /// Indicates a constraint that a type supports F# generic equality
+    member IsEqualityConstraint  : bool
+
+    /// Indicates a constraint that a type is an unmanaged type
+    member IsUnmanagedConstraint  : bool
+
+    /// Indicates a constraint that a type has a member with the given signature 
+    member IsMemberConstraint : bool
+    member MemberSources : ReadOnlyCollection<FSharpType>
+    member MemberName : string 
+    member MemberIsStatc : bool
+    member MemberArgumentTypes : ReadOnlyCollection<FSharpType>
+    member MemberReturnType : FSharpType 
+
+    /// Indicates a constraint that a type is a non-Nullable value type 
+    member IsNonNullableValueTypeConstraint : bool
+    
+    /// Indicates a constraint that a type is a reference type 
+    member IsReferenceTypeConstraint  : bool
+
+    /// Indicates a constraint that a type is a simple choice between one of the given ground types. Used by printf format strings.
+    member IsSimpleChoiceConstraint : bool
+    member SimpleChoices : ReadOnlyCollection<FSharpType>
+
+    /// Indicates a constraint that a type has a parameterless constructor 
+    member IsRequiresDefaultConstructorConstraint  : bool
+
+    /// Indicates a constraint that a type is an enum with the given underlying 
+    member IsEnumConstraint : bool
+    member EnumConstraintTarget : FSharpType 
+    
+    /// Indicates a constraint that a type is a delegate from the given tuple of args to the given return type 
+    member IsDelegateConstraint : bool
+    member DelegateTupledArgumentType : FSharpType
+    member DelegateReturnType : FSharpType 
+
+
+and FSharpInlineAnnotation = 
+   | PsuedoValue = 3
+   /// Indictes the value is inlined but the code for the function still exists, e.g. to satisfy interfaces on objects, but that it is also always inlined 
+   | AlwaysInline = 2
+   | OptionalInline = 1
+   | NeverInline = 0
+
+and [<Sealed>] FSharpMemberOrVal = 
+    member EnclosingEntity : FSharpEntity
+    
+    /// Get the declaration location of the member or value
+    member DeclarationLocation: SourceLocation
+    
+    /// Get the typars of the member or value
+    member GenericParameters: ReadOnlyCollection<FSharpGenericParameter>
+
+    /// Get the full type of the member or value when used as a first class value
+    member Type: FSharpType
+
+    /// Indicates if this is a compiler generated value
+    member IsCompilerGenerated : bool
+
+    /// Get a result indicating if this is a must-inline value
+    member InlineAnnotation : FSharpInlineAnnotation
+
+    /// Indicates if this is a mutable value
+    member IsMutable : bool
+
+    /// Get the reflection object for this member
+    
+    [<System.Obsolete("This member does not yet return correct results for overloaded members")>]
+    member ReflectionMemberInfo :System.Reflection.MemberInfo
+
+    /// Indicates if this is a module or member value
+    member IsModuleValueOrMember : bool
+
+    /// Indicates if this is an extension member?
+    member IsExtensionMember : bool
+
+    /// Indicates if this is a member, including extension members?
+    member IsMember : bool
+
+    /// Indicates if this is an abstract member?
+    member IsDispatchSlot : bool
+
+    /// Indicates if this is a getter method for a property
+    member IsGetterMethod: bool 
+
+    /// Indicates if this is a setter method for a property
+    member IsSetterMethod: bool 
+
+    /// Indicates if this is an instance member, when seen from F#?
+    member IsInstanceMember : bool 
+    
+    /// Indicates if this is an implicit constructor?
+    member IsImplicitConstructor : bool
+    
+    /// Indicates if this is an F# type function
+    member IsTypeFunction : bool
+
+    /// Indicates if this value or member is an F# active pattern
+    member IsActivePattern : bool
+      
+      /// Get the member name in compiled code
+    member CompiledName: string
+
+      /// Get the logical name of the member
+    member LogicalName: string
+
+      /// Get the logical enclosing entity, which for an extension member is type being extended
+    member LogicalEnclosingEntity: FSharpEntity
+
+      /// Get the name as presented in F# error messages and documentation
+    member DisplayName : string
+
+    member CurriedParameterGroups : ReadOnlyCollection<ReadOnlyCollection<FSharpParameter>>
+
+    member ReturnParameter : FSharpParameter
+
+      /// Custom attributes attached to the value. These contain references to other values (i.e. constructors in types). Mutable to fixup  
+      /// these value references after copying a colelction of values. 
+    member Attributes: ReadOnlyCollection<FSharpAttribute>
+
+      /// XML documentation signature for the value.
+    member XmlDocSig: string;
+
+     
+#if TODO
+    /// Indicates if this is "base" in "base.M(...)"
+    member IsBaseValue : bool
+
+    /// Indicates if this is the "x" in "type C() as x = ..."
+    member IsConstructorThisValue : bool
+
+    /// Indicates if this is the "x" in "member x.M = ..."
+    member IsMemberThisValue : bool
+
+    /// Indicates if this is a [<Literal>] value, and if so what value?
+    member LiteralValue : obj // may be null
+
+      /// Get the module, type or namespace where this value appears. For 
+      /// an extension member this is the type being extended 
+    member ApparentParent: FSharpEntity
+
+     /// Get the module, type or namespace where this value is compiled
+    member ActualParent: FSharpEntity;
+
+#endif
+
+      /// How visible is this? 
+    member Accessibility : FSharpAccessibility
+
+    static member op_Equality : FSharpMemberOrVal * FSharpMemberOrVal -> bool
+    static member op_Inequality : FSharpMemberOrVal * FSharpMemberOrVal -> bool
+
+
+and [<Sealed>] FSharpParameter =
+    member Name: string
+    member DeclarationLocation : SourceLocation; 
+    member Type : FSharpType; 
+    member Attributes: ReadOnlyCollection<FSharpAttribute>
+    static member op_Equality : FSharpParameter * FSharpParameter -> bool
+    static member op_Inequality : FSharpParameter * FSharpParameter -> bool
+
+
+and [<Sealed>] FSharpType =
+
+    /// Indicates the type is constructed using a named entity
+    member IsNamed : bool
+    /// Get the named entity for a type constructed using a named entity
+    member NamedEntity : FSharpEntity 
+    /// Get the generic arguments for a tuple type, a function type or a type constructed using a named entity
+    member GenericArguments : ReadOnlyCollection<FSharpType>
+    
+    /// Indicates the type is a tuple type. The GenericArguments property returns the elements of the tuple type.
+    member IsTuple : bool
+
+    /// Indicates the type is a function type. The GenericArguments property returns the domain and range of the function type.
+    member IsFunction : bool
+
+    /// Indicates the type is a variable type, whether declared, generalized or an inference type parameter  
+    member IsGenericParameter : bool
+    /// Get the generic parameter data for a generic parameter type
+    member GenericParameter : FSharpGenericParameter
+    /// Get the index for a generic parameter type
+    member GenericParameterIndex : int
+
+    static member op_Equality : FSharpType * FSharpType -> bool
+    static member op_Inequality : FSharpType * FSharpType -> bool
+
+
+
+and [<Sealed>]
+    FSharpAttribute = 
+        member Value : obj  
+        
+        member ReflectionType: System.Type 
+        static member op_Equality : FSharpAttribute * FSharpAttribute -> bool
+        static member op_Inequality : FSharpAttribute * FSharpAttribute -> bool
+
+
+
diff --git a/src/FSharp.PowerPack.Metadata/Prelude.fs b/src/FSharp.PowerPack.Metadata/Prelude.fs
new file mode 100755
index 0000000..12030d2
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/Prelude.fs
@@ -0,0 +1,354 @@
+
+// (c) Microsoft Corporation. All rights reserved
+
+//---------------------------------------------------------------------------
+// This file contains definitions that mimic definitions from parts of the F#
+// compiler as necessary to allow the internal compiler typed abstract
+// syntax tree and metadata deserialization code to be loaded independently
+// of the rest of the compiler.
+//
+// This is used to give FSharp.PowerPack.Metadata.dll a minimal code base support
+// to ensure we can publish the source code for that DLL as an independent
+// sample. At some point we may fork the implementation of this DLL completely.
+//
+// Ideally this file would be empty, and gradually we will align the compiler
+// source to allow this to be the case.
+//---------------------------------------------------------------------------
+
+module internal Microsoft.FSharp.Metadata.Reader.Internal.Prelude
+open Microsoft.FSharp.Control
+
+    
+type PPLazyFailure(exn:exn) =
+    static let undefined = PPLazyFailure(System.InvalidOperationException("a lazy value was accessed during its own initialization"))
+    member x.Exception = exn
+    static member Undefined = undefined
+
+// Adding this StructuredFormatDisplay is _almost_ redundant, since it just calls ToString(). 
+// However it means that when structured formatting is also printing
+// properties then the properties are _not_ printed, which means the Value property is not explored.
+[<StructuredFormatDisplay("{StructuredFormatDisplay}")>]                                                     
+[<AllowNullLiteral>]
+type PPLazy<'T>(value : 'T, funcOrException: obj) = 
+
+    /// This field holds the result of a successful computation. It's initial value is Unchecked.defaultof
+    let mutable value = value 
+
+    /// This field holds either the function to run or a PPLazyFailure object recording the exception raised 
+    /// from running the function. It is null if the thunk has been evaluated successfully.
+    [<VolatileField>]
+    let mutable funcOrException = funcOrException
+
+    static member Create(f: (unit->'T)) : PPLazy<'T> = 
+        PPLazy<'T> (value = Unchecked.defaultof<'T>, funcOrException = box(f) )
+    static member CreateFromValue(x:'T) : PPLazy<'T> = 
+        PPLazy<'T> (value = x, funcOrException = null)
+    member x.IsValueCreated = (match funcOrException with null -> true | _ -> false)
+    member x.Value =  
+        match funcOrException with 
+        | null -> value 
+        | _ -> 
+            // Enter the lock in case another thread is in the process of evaluting the result
+            System.Threading.Monitor.Enter(x);
+            try 
+                match funcOrException with 
+                | null -> value 
+                | :? PPLazyFailure as res -> 
+                      raise(res.Exception)
+                | :? (unit -> 'T) as f -> 
+                      funcOrException <- box(PPLazyFailure.Undefined)
+                      try 
+                          let res = f () 
+                          value <- res; 
+                          funcOrException <- null; 
+                          res
+                      with e -> 
+                          funcOrException <- box(new PPLazyFailure(e)); 
+                          reraise()
+                | _ -> 
+                    failwith "unreachable"
+            finally
+                System.Threading.Monitor.Exit(x)
+
+    member internal x.StructuredFormatDisplay = x.ToString() // for the StructuredFormatDisplay attribute
+
+    override x.ToString() = 
+        if x.IsValueCreated then 
+            if box x.Value = null then
+                "<null>"
+            else
+                x.Value.ToString()
+        else
+            match funcOrException with 
+            | :? PPLazyFailure as res -> 
+                match res.Exception with 
+                | e when System.Runtime.CompilerServices.RuntimeHelpers.Equals(e,PPLazyFailure.Undefined) -> "<evaluating>"
+                | e ->  e.ToString()
+            | _ -> 
+                "<unevaluated>"
+        
+    member x.IsDelayed = not(x.IsValueCreated)
+
+    member x.IsForced = x.IsValueCreated
+
+    member x.IsException = false
+    
+    member x.Force() = x.Value
+    
+    member x.SynchronizedForce() = x.Value
+    
+    member x.UnsynchronizedForce() = x.Value
+
+type 'T ``pplazy`` = PPLazy<'T>       
+
+let isSome x = Option.isSome x
+let isNull (x : 'T) = match (x :> obj) with null -> true | _ -> false
+
+type pos =  { posLine: int; posCol: int }  
+
+let mk_pos x y = { posLine=x; posCol=y }
+type range = 
+    { rangeFile: string;
+      rangeBegin: pos;
+      rangeEnd: pos }  
+
+let mk_range file p1 p2 = 
+    { rangeFile = file; rangeBegin=p1; rangeEnd=p2 }
+
+let range0 =  mk_range "unknown" (mk_pos 1 0) (mk_pos 1 80)
+let rangeN filename line =  mk_range filename (mk_pos line 0) (mk_pos line 80)
+
+[<Sealed>]
+type ident (text:string,range:range) = 
+     member x.idText = text
+     member x.idRange = range
+     override x.ToString() = text
+let mksyn_id m s = ident(s,m)
+
+type MemberFlags =
+  { MemberIsInstance: bool;
+    MemberIsDispatchSlot: bool;
+    MemberIsOverrideOrExplicitImpl: bool;
+    MemberIsFinal: bool;
+    MemberKind: MemberKind }
+
+and MemberKind = 
+    | MemberKindClassConstructor
+    | MemberKindConstructor
+    | MemberKindMember 
+    | MemberKindPropertyGet 
+    | MemberKindPropertySet    
+    | MemberKindPropertyGetSet    
+
+and TyparStaticReq = 
+    | NoStaticReq 
+    | HeadTypeStaticReq 
+
+and [<NoEquality; NoComparison>]
+    SynTypar = 
+    | Typar of ident * TyparStaticReq * bool 
+
+[<NoEquality; NoComparison>]
+type LazyWithContext<'T,'ctxt> = 
+    { v: PPLazy<'T> }
+    member x.Force(_) = x.v.Force()
+    static member NotLazy (x:'T)  = { v = PPLazy.CreateFromValue x }
+    static member Create (f: unit -> 'T)  = { v = PPLazy.Create f }
+
+type XmlDoc = XmlDoc of string[]
+
+let emptyXmlDoc = XmlDoc[| |]
+let MergeXmlDoc (XmlDoc lines) (XmlDoc lines') = XmlDoc (Array.append lines lines')
+
+let notlazy v = PPLazy.CreateFromValue v
+module String =
+
+
+    let tryDropSuffix s t = 
+        let lens = String.length s
+        let lent = String.length t
+        if (lens >= lent && (s.Substring (lens-lent, lent) = t)) then 
+            Some (s.Substring (0,lens - lent))
+        else
+            None
+
+    let hasSuffix s t = (tryDropSuffix s t).IsSome
+    let dropSuffix s t = match (tryDropSuffix s t) with Some(res) -> res | None -> failwith "dropSuffix"
+
+module List = 
+
+    let lengthsEqAndForall2 p l1 l2 = 
+        List.length l1 = List.length l2 &&
+        List.forall2 p l1 l2
+    let mapSquared f xss = xss |> List.map (List.map f)
+
+    let frontAndBack l = 
+        let rec loop acc l = 
+            match l with
+            | [] -> 
+                System.Diagnostics.Debug.Assert(false, "empty list")
+                invalidArg "l" "empty list" 
+            | [h] -> List.rev acc,h
+            | h::t -> loop  (h::acc) t
+        loop [] l
+
+    let mapq (f: 'T -> 'T) inp =
+        assert not (typeof<'T>.IsValueType) 
+        match inp with
+        | [] -> inp
+        | _ -> 
+            let res = List.map f inp 
+            let rec check l1 l2 = 
+                match l1,l2 with 
+                | h1::t1,h2::t2 -> 
+                    System.Runtime.CompilerServices.RuntimeHelpers.Equals(h1,h2) && check t1 t2
+                | _ -> true
+            if check inp res then inp else res
+
+
+    let splitAfter n l = 
+        let rec split_after_acc n l1 l2 = if n <= 0 then List.rev l1,l2 else split_after_acc (n-1) ((List.head l2):: l1) (List.tail l2) 
+        split_after_acc n [] l
+
+module ListSet = 
+    let rec mem f x l = 
+        match l with 
+        | [] -> false
+        | x'::t -> f x x' || mem f x t
+
+    let isSubsetOf f l1 l2 = List.forall (fun x1 -> mem f x1 l2) l1
+    let isSupersetOf f l1 l2 = List.forall (fun x2 -> mem (fun y2 y1 ->  f y1 y2) x2 l1) l2
+    let equals f l1 l2 = isSubsetOf f l1 l2 && isSupersetOf f l1 l2
+
+    let rec remove f x l = 
+        match l with 
+        | (h::t) -> if f x h then t else h:: remove f x t
+        | [] -> []
+
+    (* NOTE: quadratic! *)
+    let rec subtract f l1 l2 = 
+      match l2 with 
+      | (h::t) -> subtract f (remove (fun y2 y1 ->  f y1 y2) h l1) t
+      | [] -> l1
+
+
+module ListAssoc = 
+
+    /// Treat a list of key-value pairs as a lookup collection.
+    /// This function looks up a value based on a match from the supplied
+    /// predicate function.
+    let rec find f x l = 
+      match l with 
+      | [] -> raise (System.Collections.Generic.KeyNotFoundException())
+      | (x',y)::t -> if f x x' then y else find f x t
+
+    /// Treat a list of key-value pairs as a lookup collection.
+    /// This function returns true if two keys are the same according to the predicate
+    /// function passed in.
+    let rec containsKey (f:'key->'key->bool) (x:'key) (l:('key*'value) list) : bool = 
+      match l with 
+      | [] -> false
+      | (x',y)::t -> f x x' || containsKey f x t
+
+type SequencePointInfoForBinding = unit
+type SequencePointInfoForTarget = unit
+type SequencePointInfoForTry = unit
+type SequencePointInfoForWith = unit
+type SequencePointInfoForFinally = unit
+type SequencePointInfoForSeq = unit
+type SequencePointInfoForForLoop =  unit
+type SequencePointInfoForWhileLoop = unit
+
+let SuppressSequencePointAtTarget = ()
+let NoSequencePointAtStickyBinding = ()
+let NoSequencePointAtTry = ()
+let NoSequencePointAtWith = ()
+let NoSequencePointAtFinally = ()
+let NoSequencePointAtForLoop = ()
+let NoSequencePointAtWhileLoop = ()
+let SuppressSequencePointOnExprOfSequential = ()
+
+let error e = raise e
+let errorR e = raise e
+let Error((n,s),m) = Failure s
+let InternalError(s,m) = Failure s
+let UnresolvedReferenceNoRange s = Failure ("unresolved reference " + s)
+let UnresolvedPathReferenceNoRange (s,p) = Failure ("unresolved reference " + s + " for path " + p)
+type NameMap<'T> = Map<string,'T>
+type ExprData = unit
+type NameMultiMap<'T> = 'T list NameMap
+type MultiMap<'T,'U when 'T : comparison> = Map<'T,'U list>
+
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module NameMap = 
+    let empty = Map.empty
+    let tryFind v (m: 'T NameMap) = Map.tryFind v m 
+    let ofKeyedList f l = List.foldBack (fun x acc -> Map.add (f x) x acc) l Map.empty
+    let range m = List.rev (Map.foldBack (fun _ x sofar -> x :: sofar) m [])
+    let add v x (m: 'T NameMap) = Map.add v x m
+    let foldRange f (l: 'T NameMap) acc = Map.foldBack (fun _ y acc -> f y acc) l acc
+    let mem v (m: 'T NameMap) = Map.containsKey v m
+    let find v (m: 'T NameMap) = Map.find v m
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module MultiMap = 
+    let existsInRange f (m: MultiMap<_,_>) = Map.exists (fun _ l -> List.exists f l) m
+    let find v (m: MultiMap<_,_>) = match Map.tryFind v m with None -> [] | Some r -> r
+    let add v x (m: MultiMap<_,_>) = Map.add v (x :: find v m) m
+    let range (m: MultiMap<_,_>) = Map.foldBack (fun _ x sofar -> x @ sofar) m []
+    //let chooseRange f (m: MultiMap<_,_>) = Map.foldBack (fun _ x sofar -> List.choose f x @ sofar) m []
+    let empty : MultiMap<_,_> = Map.empty
+    let initBy f xs : MultiMap<_,_> = xs |> Seq.groupBy f |> Seq.map (fun (k,v) -> (k,List.ofSeq v)) |> Map.ofSeq 
+
+
+type cache<'T> = NoCache
+let newCache() = NoCache
+let cacheOptRef _ f = f ()
+let cached _ f = f()
+let (===) x y = LanguagePrimitives.PhysicalEquality x y
+let dprintf fmt = printf fmt
+let text_of_path path = String.concat "." path
+type SkipFreeVarsCache = unit
+type FreeVarsCache = unit cache
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module NameMultiMap = 
+    let find v (m: NameMultiMap<'T>) = match Map.tryFind v m with None -> [] | Some r -> r
+    let add v x (m: NameMultiMap<'T>) = NameMap.add v (x :: find v m) m
+    let empty : NameMultiMap<'T> = Map.empty
+    let range (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> x @ sofar) m []
+    let rangeReversingEachBucket (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> List.rev x @ sofar) m []
+    let ofList (xs: (string * 'T) list) : NameMultiMap<'T> = xs |> Seq.groupBy fst |> Seq.map (fun (k,v) -> (k,List.ofSeq (Seq.map snd v))) |> Map.ofSeq 
+
+
+type ByteStream = 
+    { bytes: byte[]; 
+      mutable pos: int; 
+      max: int }
+
+module Bytestream = 
+
+    let of_bytes (b:byte[]) n len = 
+        if n < 0 || (n+len) > b.Length then failwith "Bytestream.of_bytes";
+        { bytes = b; pos = n; max = n+len }
+
+    let read_byte b  = 
+        if b.pos >= b.max then failwith "Bytestream.of_bytes.read_byte: end of stream";
+        let res = b.bytes.[b.pos] 
+        b.pos <- b.pos + 1;
+        int32 res 
+      
+    let read_bytes b n  = 
+        if b.pos + n > b.max then failwith "Bytestream.read_bytes: end of stream";
+        let res = Array.sub b.bytes b.pos n 
+        b.pos <- b.pos + n;
+        res 
+
+    let position b = b.pos 
+    let skip b n = b.pos <- b.pos + n
+
+    let read_utf8_bytes_as_string (b: ByteStream) n = 
+        let res = System.Text.Encoding.UTF8.GetString(b.bytes,b.pos,n) 
+        b.pos <- b.pos + n; res 
+
diff --git a/src/FSharp.PowerPack.Metadata/PrettyNaming.fs b/src/FSharp.PowerPack.Metadata/PrettyNaming.fs
new file mode 100755
index 0000000..87bfdca
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/PrettyNaming.fs
@@ -0,0 +1,241 @@
+// (c) Microsoft Corporation. All rights reserved
+//----------------------------------------------------------------------------
+// Some general F# utilities for mangling / unmangling / manipulating names.
+//--------------------------------------------------------------------------
+
+
+module internal Microsoft.FSharp.Metadata.Reader.Internal.PrettyNaming
+
+    open Microsoft.FSharp.Metadata.Reader.Internal.Prelude
+    
+    open System.Globalization
+    open System.Collections.Generic
+
+    let private opNameTable = 
+     [ ("[]", "op_Nil");
+       ("::", "op_ColonColon");
+       ("+", "op_Addition");
+       ("~%", "op_Splice");
+       ("~%%", "op_SpliceUntyped");
+       ("~++", "op_Increment");
+       ("~--", "op_Decrement");
+       ("-", "op_Subtraction");
+       ("*", "op_Multiply");
+       ("**", "op_Exponentiation");
+       ("/", "op_Division");
+       ("@", "op_Append");
+       ("^", "op_Concatenate");
+       ("%", "op_Modulus");
+       ("&&&", "op_BitwiseAnd");
+       ("|||", "op_BitwiseOr");
+       ("^^^", "op_ExclusiveOr");
+       ("<<<", "op_LeftShift");
+       ("~~~", "op_LogicalNot");
+       (">>>", "op_RightShift");
+       ("~+", "op_UnaryPlus");
+       ("~-", "op_UnaryNegation");
+       ("~&", "op_AddressOf");
+       ("~&&", "op_IntegerAddressOf");
+       ("&&", "op_BooleanAnd");
+       ("||", "op_BooleanOr");
+       ("<=", "op_LessThanOrEqual");
+       ("=","op_Equality");
+       ("<>","op_Inequality");
+       (">=", "op_GreaterThanOrEqual");
+       ("<", "op_LessThan");
+       (">", "op_GreaterThan");
+       ("|>", "op_PipeRight");
+       ("||>", "op_PipeRight2");
+       ("|||>", "op_PipeRight3");
+       ("<|", "op_PipeLeft");
+       ("<||", "op_PipeLeft2");
+       ("<|||", "op_PipeLeft3");
+       ("!", "op_Dereference");
+       (">>", "op_ComposeRight");
+       ("<<", "op_ComposeLeft");
+       ("<< >>", "op_TypedQuotationUnicode");
+       ("<<| |>>", "op_ChevronsBar");
+       ("<@ @>", "op_Quotation");
+       ("<@@ @@>", "op_QuotationUntyped");
+       ("+=", "op_AdditionAssignment");
+       ("-=", "op_SubtractionAssignment");
+       ("*=", "op_MultiplyAssignment");
+       ("/=", "op_DivisionAssignment");
+       ("..", "op_Range");
+       (".. ..", "op_RangeStep"); 
+       ("?", "op_Dynamic");
+       ("?<-", "op_DynamicAssignment");
+       (".()", "op_ArrayLookup");
+       (".()<-", "op_ArrayAssign");
+       ]
+
+    let opCharTranslateTable =
+      [ ( '>', "Greater");
+        ( '<', "Less"); 
+        ( '+', "Plus");
+        ( '-', "Minus");
+        ( '*', "Multiply");
+        ( '=', "Equals");
+        ( '~', "Twiddle");
+        ( '%', "Percent");
+        ( '.', "Dot");
+        ( '$', "Dollar");
+        ( '&', "Amp");
+        ( '|', "Bar");
+        ( '@', "At");
+        ( '#', "Hash");
+        ( '^', "Hat");
+        ( '!', "Bang");
+        ( '?', "Qmark");
+        ( '/', "Divide");
+        ( ':', "Colon");
+        ( '(', "LParen");
+        ( ',', "Comma");
+        ( ')', "RParen");
+        ( ' ', "Space");
+        ( '[', "LBrack");
+        ( ']', "RBrack"); ]
+
+    let opCharDict = 
+        let t = new Dictionary<_,_>()
+        for (c,_) in opCharTranslateTable do 
+            t.Add(c,1)
+        t
+        
+    let isOpName (n:string) =
+        let rec loop i = (i < n.Length && (opCharDict.ContainsKey(n.[i]) || loop (i+1)))
+        loop 0
+
+    let decompileOpName = 
+      let t = new Dictionary<string,string>()
+      for (x,y) in opNameTable do
+          t.Add(y,x)
+      fun n -> 
+          let mutable res = Unchecked.defaultof<_>
+          if t.TryGetValue(n,&res) then 
+              res
+          else
+              if n.StartsWith("op_",System.StringComparison.Ordinal) then 
+                let rec loop (remaining:string) = 
+                    let l = remaining.Length
+                    if l = 0 then Some(remaining) else
+                    let choice = 
+                      opCharTranslateTable |> List.tryPick (fun (a,b) -> 
+                          let bl = b.Length
+                          if bl <= l && remaining.Substring(0,bl) = b then 
+                            Some(string a, remaining.Substring(bl,l - bl)) 
+                          else None) 
+                        
+                    match choice with 
+                    | Some (a,remaining2) -> 
+                        match loop remaining2 with 
+                        | None -> None
+                        | Some a2 -> Some(a^a2)
+                    | None -> None (* giveup *)
+                match loop (n.Substring(3,n.Length - 3)) with
+                | Some res -> res
+                | None -> n
+              else n
+                  
+    //-------------------------------------------------------------------------
+    // Handle mangled .NET generic type names
+    //------------------------------------------------------------------------- 
+     
+    let private mangledGenericTypeNameSym = '`'
+
+    let isMangledGenericName (n:string) = 
+        n.IndexOf mangledGenericTypeNameSym <> -1 &&
+        // check what comes after the symbol is a number 
+        let m = n.LastIndexOf mangledGenericTypeNameSym
+        let mutable res = m < n.Length - 1
+        for i = m + 1 to n.Length - 1 do
+            res <- res && n.[i] >= '0' && n.[i] <= '9';
+        res
+
+    type NameArityPair = NameArityPair of string*int
+
+    let demangleGenericTypeName n = 
+        if  isMangledGenericName n then 
+            let pos = n.LastIndexOf mangledGenericTypeNameSym
+            n.Substring(0,pos)
+        else n
+
+    //-------------------------------------------------------------------------
+    // Property name mangling.
+    // Expecting s to be in the form (as returned by qualified_mangled_name_of_tcref) of:
+    //    get_P                         or  set_P
+    //    Names/Space/Class/NLPath-get_P  or  Names/Space/Class/NLPath.set_P
+    // Required to return "P"
+    //-------------------------------------------------------------------------
+
+    let private chopStringTo (s:string) (c:char) =
+        (* chopStringTo "abcdef" 'c' --> "def" *)
+        if s.IndexOf c <> -1 then
+            let i =  s.IndexOf c + 1
+            s.Substring(i, s.Length - i)
+        else
+            s
+
+    /// Try to chop "get_" or "set_" from a string
+    let tryChopPropertyName (s: string) =
+        // extract the logical name from any mangled name produced by MakeMemberDataAndMangledNameForMemberVal 
+        let s = 
+            if s.StartsWith("get_", System.StringComparison.Ordinal) || 
+               s.StartsWith("set_", System.StringComparison.Ordinal) 
+            then s 
+            else chopStringTo s '.'
+
+        if s.Length <= 4 || (let s = s.Substring(0,4) in s <> "get_" && s <> "set_") then
+            None
+        else 
+            Some(s.Substring(4,s.Length - 4) )
+
+
+    let chopPropertyName s =
+        match tryChopPropertyName s with 
+        | None -> failwith("Invalid internal property name: '"^s^"'");
+        | Some res -> res
+        
+
+    let demangleOperatorName nm = 
+        let nm = decompileOpName nm
+        if isOpName nm then "( "^nm^" )" else nm 
+
+    let fsharpModuleSuffix = "Module"
+
+    let isActivePatternName (nm:string) =
+        (nm.IndexOf '|' = 0) &&
+        nm.Length >= 3 &&
+        (nm.LastIndexOf '|' = nm.Length - 1) &&
+        (let core = nm.Substring(1,nm.Length - 2) 
+         // no operator characters except '|'
+         core |> String.forall (fun c -> c = '|' || not (opCharDict.ContainsKey c)) &&
+         // at least one non-operator character
+         core |> String.exists (fun c -> not (opCharDict.ContainsKey c)))
+
+    //isActivePatternName "|+|" = false
+    //isActivePatternName "|ABC|" = true
+    //isActivePatternName "|ABC|DEF|" = true
+    //isActivePatternName "|||" = false
+    //isActivePatternName "||S|" = true
+
+    type ActivePatternInfo = 
+        | APInfo of bool * string list 
+        member x.IsTotal = let (APInfo(p,_)) = x in p
+        member x.ActiveTags = let (APInfo(_,tags)) = x in tags
+
+    let activePatternInfoOfValName nm = 
+        let rec loop (nm:string) = 
+            let n = nm.IndexOf '|'
+            if n > 0 then 
+               nm.[0..n-1] :: loop nm.[n+1..]
+            else
+               [nm]
+        let nm = decompileOpName nm
+        if isActivePatternName nm then 
+            let res = loop nm.[1..nm.Length-2]
+            let resH,resT = List.frontAndBack res
+            Some(if resT = "_" then APInfo(false,resH) else APInfo(true,res))
+        else 
+            None
+    
diff --git a/src/FSharp.PowerPack.Metadata/QueueList.fs b/src/FSharp.PowerPack.Metadata/QueueList.fs
new file mode 100755
index 0000000..42ec2e0
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/QueueList.fs
@@ -0,0 +1,64 @@
+// (c) Microsoft Corporation. All rights reserved(
+
+namespace Microsoft.FSharp.Metadata.Reader.Internal
+
+open System.Collections
+open System.Collections.Generic
+
+/// Iterable functional collection with O(1) append-1 time. Useful for data structures where elements get added at the
+/// end but the collection must occadionally be iterated. Iteration is slower and may allocate because 
+/// a suffix of elements is stored in reverse order.
+///
+/// The type doesn't support structural hashing or comparison.
+type internal
+    QueueList<'T>(firstElementsIn: FlatList<'T>, lastElementsRevIn:  'T list, numLastElementsIn: int) = 
+    let numFirstElements = firstElementsIn.Length 
+    // Push the lastElementsRev onto the firstElements every so often
+    let push = numLastElementsIn > numFirstElements / 5
+    
+    // Compute the contents after pushing.
+    let firstElements = if push then FlatList.append firstElementsIn (FlatList.ofList (List.rev lastElementsRevIn)) else firstElementsIn
+    let lastElementsRev = if push then [] else lastElementsRevIn
+    let numLastElements = if push then 0 else numLastElementsIn
+
+    // Compute the last elements on demand
+    let lastElements() = if push then [] else List.rev lastElementsRev
+
+    static let empty = QueueList<'T>(FlatList.empty, [], 0)
+    static member Empty : QueueList<'T> = empty
+    new (xs:FlatList<'T>) = QueueList(xs,[],0)
+    
+    member internal x.FirstElements = firstElements
+    member internal x.LastElements = lastElements()
+
+    /// Note this operation is O(1), unless a push happens, which is rare 
+    member x.AppendOne(y) = QueueList(firstElements, y :: lastElementsRev, numLastElements+1)
+    member x.Append(ys:seq<_>) = QueueList(firstElements, (List.rev (Seq.toList ys) @ lastElementsRev), numLastElements+1)
+    
+    /// Note this operation is O(n) anyway, so executing lastElements() here is OK
+    interface IEnumerable<'T> with 
+        member x.GetEnumerator() : IEnumerator<'T> = 
+           if push then (firstElements :> IEnumerable<_>).GetEnumerator()
+           else (seq { yield! firstElements 
+                       yield! lastElements() }).GetEnumerator()
+    interface IEnumerable with 
+        member x.GetEnumerator() : IEnumerator = ((x :> IEnumerable<'T>).GetEnumerator() :> IEnumerator)
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module internal QueueList =
+    let empty<'T> : QueueList<'T> = QueueList<'T>.Empty
+    let ofSeq (x:seq<_>) = QueueList(FlatList.ofSeq x)
+    let rec iter f (x:QueueList<_>) = Seq.iter f x 
+    let rec map f (x:QueueList<_>) = ofSeq (Seq.map f x)
+    let rec exists f (x:QueueList<_>) = Seq.exists f x
+    let rec filter f (x:QueueList<_>) = ofSeq (Seq.filter f x)
+    let rec foldBack f (x:QueueList<_>) acc = FlatList.foldBack f  x.FirstElements (List.foldBack f x.LastElements acc)
+    let forall f (x:QueueList<_>) = Seq.forall f x
+    let ofList (x:list<_>) = QueueList(FlatList.ofList x)
+    let toList (x:QueueList<_>) = Seq.toList x
+    let tryFind f (x:QueueList<_>) = Seq.tryFind f x
+    let one(x) = QueueList (FlatList.one x)
+    let appendOne (x:QueueList<_>) y = x.AppendOne(y)
+    let append (x:QueueList<_>) (ys:QueueList<_>) = x.Append(ys)
+
+
diff --git a/src/FSharp.PowerPack.Metadata/assemblyinfo.FSharp.PowerPack.Metadata.dll.fs b/src/FSharp.PowerPack.Metadata/assemblyinfo.FSharp.PowerPack.Metadata.dll.fs
new file mode 100755
index 0000000..3018013
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/assemblyinfo.FSharp.PowerPack.Metadata.dll.fs
@@ -0,0 +1,8 @@
+
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("FSharp.PowerPack.Metadata.dll")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("FSharp.PowerPack.Metadata.dll")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
diff --git a/src/FSharp.PowerPack.Metadata/env.fs b/src/FSharp.PowerPack.Metadata/env.fs
new file mode 100755
index 0000000..aabfe47
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/env.fs
@@ -0,0 +1,33 @@
+(* (c) Microsoft Corporation 2005-2009.  *)
+
+
+
+module internal Microsoft.FSharp.Metadata.Reader.Internal.Env
+
+open System.Collections.Generic 
+open Microsoft.FSharp.Metadata.Reader.Internal.AbstractIL.IL
+open Microsoft.FSharp.Metadata.Reader.Internal.PrettyNaming
+open Microsoft.FSharp.Metadata.Reader.Internal.Prelude
+open Microsoft.FSharp.Metadata.Reader.Internal.Tast
+
+[<NoEquality; NoComparison>]
+type TcGlobals = 
+    { nativeptr_tcr:TyconRef;
+      nativeint_tcr:TyconRef;
+      tuple1_tcr      : TyconRef;
+      tuple2_tcr      : TyconRef;
+      tuple3_tcr      : TyconRef;
+      tuple4_tcr      : TyconRef;
+      tuple5_tcr      : TyconRef;
+      tuple6_tcr      : TyconRef;
+      tuple7_tcr      : TyconRef;
+      tuple8_tcr      : TyconRef;
+      fastFunc_tcr    : TyconRef;
+      fslibCcu : CcuThunk
+      byref_tcr:TyconRef;
+      il_arr1_tcr:TyconRef;
+      il_arr2_tcr:TyconRef;
+      il_arr3_tcr:TyconRef;
+      il_arr4_tcr:TyconRef;
+      unit_tcr:TyconRef; }
+
diff --git a/src/FSharp.PowerPack.Metadata/il.fs b/src/FSharp.PowerPack.Metadata/il.fs
new file mode 100755
index 0000000..2f6357c
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/il.fs
@@ -0,0 +1,1671 @@
+// (c) Microsoft Corporation. All rights reserved
+
+module internal Microsoft.FSharp.Metadata.Reader.Internal.AbstractIL.IL
+
+open System.Collections.Generic
+open System.Collections
+#nowarn "343" // The type 'ILAssemblyRef' implements 'System.IComparable' explicitly but provides no corresponding override for 'Object.Equals'.
+#nowarn "346" // The struct, record or union type 'IlxExtensionType' has an explicit implementation of 'Object.Equals'. ...
+
+type Lazy<'T> = Microsoft.FSharp.Metadata.Reader.Internal.Prelude.PPLazy<'T>
+
+let notlazy v = Lazy.CreateFromValue v
+
+/// A little ugly, but the idea is that if a data structure does not 
+/// contain lazy values then we don't add laziness.  So if the thing to map  
+/// is already evaluated then immediately apply the function.  
+let lazyMap f (x:Lazy<_>) =  
+      if x.IsValueCreated then notlazy (f (x.Force())) else Lazy.Create (fun () -> f (x.Force()))
+
+// -------------------------------------------------------------------- 
+// Ordered lists with a lookup table
+// --------------------------------------------------------------------
+
+/// This is used to store event, property and field maps.
+///
+/// Review: this is not such a great data structure.
+type LazyOrderedMultiMap<'Key,'Data when 'Key : equality>(keyf : 'Data -> 'Key, lazyItems : Lazy<'Data list>) = 
+
+    let quickMap= 
+        lazyItems |> lazyMap (fun entries -> 
+            let t = new Dictionary<_,_>(entries.Length, HashIdentity.Structural)
+            do entries |> List.iter (fun y -> let key = keyf y in t.[key] <- y :: (if t.ContainsKey(key) then t.[key] else [])) 
+            t)
+
+    member self.Entries() = lazyItems.Force()
+
+    member self.Add(y) = new LazyOrderedMultiMap<'Key,'Data>(keyf, lazyItems |> lazyMap (fun x -> y :: x))
+    
+    member self.Filter(f) = new LazyOrderedMultiMap<'Key,'Data>(keyf, lazyItems |> lazyMap (List.filter f))
+
+    member self.Item with get(x) = let t = quickMap.Force() in if t.ContainsKey x then t.[x] else []
+
+
+//---------------------------------------------------------------------
+// SHA1 hash-signing algorithm.  Used to get the public key token from
+// the public key.
+//---------------------------------------------------------------------
+
+
+let b0 n =  (n &&& 0xFF)
+let b1 n =  ((n >>> 8) &&& 0xFF)
+let b2 n =  ((n >>> 16) &&& 0xFF)
+let b3 n =  ((n >>> 24) &&& 0xFF)
+
+
+module SHA1 = 
+    let inline (>>>&)  (x:int) (y:int)  = int32 (uint32 x >>> y)
+    let f(t,b,c,d) = 
+        if t < 20 then (b &&& c) ||| ((~~~b) &&& d) else
+        if t < 40 then b ^^^ c ^^^ d else
+        if t < 60 then (b &&& c) ||| (b &&& d) ||| (c &&& d) else
+        b ^^^ c ^^^ d
+
+    let k0to19 = 0x5A827999
+    let k20to39 = 0x6ED9EBA1
+    let k40to59 = 0x8F1BBCDC
+    let k60to79 = 0xCA62C1D6
+
+    let k(t) = 
+        if t < 20 then k0to19 
+        elif t < 40 then k20to39 
+        elif t < 60 then k40to59 
+        else k60to79 
+
+
+    type chan = SHABytes of byte[] 
+    type sha_instream = 
+        { stream: chan;
+          mutable pos: int;
+          mutable eof:  bool; }
+
+    let rot_left32 x n =  (x <<< n) ||| (x >>>& (32-n))
+
+    let sha_eof sha = sha.eof
+
+    (* padding and length (in bits!) recorded at end *)
+    let sha_after_eof sha  = 
+        let n = sha.pos
+        let len = 
+          (match sha.stream with
+          | SHABytes s -> s.Length)
+        if n = len then 0x80
+        else 
+          let padded_len = (((len + 9 + 63) / 64) * 64) - 8
+          if n < padded_len - 8  then 0x0  
+          elif (n &&& 63) = 56 then int32 ((int64 len * int64 8) >>> 56) &&& 0xff
+          elif (n &&& 63) = 57 then int32 ((int64 len * int64 8) >>> 48) &&& 0xff
+          elif (n &&& 63) = 58 then int32 ((int64 len * int64 8) >>> 40) &&& 0xff
+          elif (n &&& 63) = 59 then int32 ((int64 len * int64 8) >>> 32) &&& 0xff
+          elif (n &&& 63) = 60 then int32 ((int64 len * int64 8) >>> 24) &&& 0xff
+          elif (n &&& 63) = 61 then int32 ((int64 len * int64 8) >>> 16) &&& 0xff
+          elif (n &&& 63) = 62 then int32 ((int64 len * int64 8) >>> 8) &&& 0xff
+          elif (n &&& 63) = 63 then (sha.eof <- true; int32 (int64 len * int64 8) &&& 0xff)
+          else 0x0
+
+    let sha_read8 sha = 
+        let b = 
+            match sha.stream with 
+            | SHABytes s -> if sha.pos >= s.Length then sha_after_eof sha else int32 s.[sha.pos]
+        sha.pos <- sha.pos + 1; 
+        b
+        
+    let sha_read32 sha  = 
+        let b0 = sha_read8 sha
+        let b1 = sha_read8 sha
+        let b2 = sha_read8 sha
+        let b3 = sha_read8 sha
+        let res = (b0 <<< 24) ||| (b1 <<< 16) ||| (b2 <<< 8) ||| b3
+        res
+
+
+    let sha1_hash sha = 
+        let h0 = ref 0x67452301
+        let h1 = ref 0xEFCDAB89
+        let h2 = ref 0x98BADCFE
+        let h3 = ref 0x10325476
+        let h4 = ref 0xC3D2E1F0
+        let a = ref 0
+        let b = ref 0
+        let c = ref 0
+        let d = ref 0
+        let e = ref 0
+        let w = Array.create 80 0x00
+        while (not (sha_eof sha)) do
+            for i = 0 to 15 do
+                w.[i] <- sha_read32 sha
+            for t = 16 to 79 do
+                w.[t] <- rot_left32 (w.[t-3] ^^^ w.[t-8] ^^^ w.[t-14] ^^^ w.[t-16]) 1;
+            a := !h0; 
+            b := !h1; 
+            c := !h2; 
+            d := !h3; 
+            e := !h4;
+            for t = 0 to 79 do
+                let temp =  (rot_left32 !a 5) + f(t,!b,!c,!d) + !e + w.[t] + k(t)
+                e := !d; 
+                d := !c; 
+                c :=  rot_left32 !b 30; 
+                b := !a; 
+                a := temp;
+            h0 := !h0 + !a; 
+            h1 := !h1 + !b; 
+            h2 := !h2 + !c;  
+            h3 := !h3 + !d; 
+            h4 := !h4 + !e
+        (!h0,!h1,!h2,!h3,!h4)
+
+    let sha1_hash_bytes s = 
+        let (_h0,_h1,_h2,h3,h4) = sha1_hash { stream = SHABytes s; pos = 0; eof = false }   // the result of the SHA algorithm is stored in registers 3 and 4
+        Array.map byte [|  b0 h4; b1 h4; b2 h4; b3 h4; b0 h3; b1 h3; b2 h3; b3 h3; |]
+
+
+let sha1_hash_bytes s = SHA1.sha1_hash_bytes s
+
+// --------------------------------------------------------------------
+// 
+// -------------------------------------------------------------------- 
+
+type ILVersionInfo = uint16 * uint16 * uint16 * uint16
+
+type Locale = string
+
+[<StructuralEquality; StructuralComparison>]
+type PublicKey =
+    | PublicKey of byte[]
+    | PublicKeyToken of byte[]
+    member x.IsKey=match x with PublicKey _ -> true | _ -> false
+    member x.IsKeyToken=match x with PublicKeyToken _ -> true | _ -> false
+    member x.Key=match x with PublicKey b -> b | _ -> invalidOp "not a key"
+    member x.KeyToken=match x with PublicKeyToken b -> b | _ -> invalidOp"not a key token"
+
+    member x.ToToken() = 
+        match x with 
+        | PublicKey bytes -> SHA1.sha1_hash_bytes bytes
+        | PublicKeyToken token -> token
+    static member KeyAsToken(k) = PublicKeyToken(PublicKey(k).ToToken())
+
+[<StructuralEquality; StructuralComparison>]
+type AssemblyRefData =
+    { assemRefName: string;
+      assemRefHash: byte[] option;
+      assemRefPublicKeyInfo: PublicKey option;
+      assemRefRetargetable: bool;
+      assemRefVersion: ILVersionInfo option;
+      assemRefLocale: Locale option; } 
+
+/// Global state: table of all assembly references keyed by AssemblyRefData
+
+[<Sealed>]
+type ILAssemblyRef(data)  =  
+    member x.Name=data.assemRefName
+    member x.Hash=data.assemRefHash
+    member x.PublicKey=data.assemRefPublicKeyInfo
+    member x.Retargetable=data.assemRefRetargetable  
+    member x.Version=data.assemRefVersion
+    member x.Locale=data.assemRefLocale
+    member x.Data = data
+    interface System.IComparable with
+        override x.CompareTo(yobj) = compare x.Data (yobj :?> ILAssemblyRef).Data 
+    override x.GetHashCode() = hash data
+    override x.Equals(yobj) = ((yobj :?> ILAssemblyRef).Data = data)
+    static member Create(name,hash,publicKey,retargetable,version,locale) =
+        ILAssemblyRef
+            { assemRefName=name;
+              assemRefHash=hash;
+              assemRefPublicKeyInfo=publicKey;
+              assemRefRetargetable=retargetable;
+              assemRefVersion=version;
+              assemRefLocale=locale; } 
+
+    static member FromAssembly(assembly:System.Reflection.Assembly) =
+        let aname = assembly.GetName()
+        let locale = None
+        let publicKey = 
+           match aname.GetPublicKey()  with 
+           | null | [| |] -> 
+               match aname.GetPublicKeyToken()  with 
+               | null | [| |] -> None
+               | bytes -> Some (PublicKeyToken bytes)
+           | bytes -> 
+               Some (PublicKey bytes)
+        
+        let version = 
+           match aname.Version with 
+           | null -> None
+           | v -> Some (uint16 v.Major,uint16 v.Minor,uint16 v.Build,uint16 v.Revision)
+
+        ILAssemblyRef.Create(aname.Name,None,publicKey,false,version,locale)
+
+    member aref.QualifiedName = 
+        let b = new System.Text.StringBuilder(100)
+        let add (s:string) = (b.Append(s) |> ignore)
+        let addC (s:char) = (b.Append(s) |> ignore)
+        add(aref.Name);
+        match aref.Version with 
+        | None -> ()
+        | Some (a,b,c,d) -> 
+            add ", Version=";
+            add (string (int a))
+            add ".";
+            add (string (int b))
+            add ".";
+            add (string (int c))
+            add ".";
+            add (string (int d))
+            add ", Culture="
+            match aref.Locale with 
+            | None -> add "neutral"
+            | Some b -> add b
+            add ", PublicKeyToken="
+            match aref.PublicKey with 
+            | None -> add "null"
+            | Some pki -> 
+                  let pkt = pki.ToToken()
+                  let convDigit(digit) = 
+                      let digitc = 
+                          if digit < 10 
+                          then  System.Convert.ToInt32 '0' + digit 
+                          else System.Convert.ToInt32 'a' + (digit - 10) 
+                      System.Convert.ToChar(digitc)
+                  for i = 0 to pkt.Length-1 do
+                      let v = pkt.[i]
+                      addC (convDigit(System.Convert.ToInt32(v)/16))
+                      addC (convDigit(System.Convert.ToInt32(v)%16))
+        b.ToString()
+
+
+[<StructuralEquality; StructuralComparison>]
+type ILModuleRef = 
+    { name: string;
+      hasMetadata: bool; 
+      hash: byte[] option; }
+    static member Create(name,hasMetadata,hash) = 
+        { name=name;
+          hasMetadata= hasMetadata;
+          hash=hash }
+    
+    member x.Name=x.name
+    member x.HasMetadata=x.hasMetadata
+    member x.Hash=x.hash 
+
+[<StructuralEquality; StructuralComparison>]
+type ILScopeRef = 
+    | ScopeRef_local
+    | ScopeRef_module of ILModuleRef 
+    | ScopeRef_assembly of ILAssemblyRef
+    static member Local = ScopeRef_local
+    static member Module(mref) = ScopeRef_module(mref)
+    static member Assembly(aref) = ScopeRef_assembly(aref)
+    member x.IsLocalRef   = match x with ScopeRef_local      -> true | _ -> false
+    member x.IsModuleRef  = match x with ScopeRef_module _   -> true | _ -> false
+    member x.IsAssemblyRef= match x with ScopeRef_assembly _ -> true | _ -> false
+    member x.ModuleRef    = match x with ScopeRef_module x   -> x | _ -> failwith "not a module reference"
+    member x.AssemblyRef  = match x with ScopeRef_assembly x -> x | _ -> failwith "not an assembly reference"
+
+    member scoref.QualifiedName = 
+        match scoref with 
+        | ScopeRef_local -> ""
+        | ScopeRef_module mref -> "module "^mref.Name
+        | ScopeRef_assembly aref when aref.Name = "mscorlib" -> ""
+        | ScopeRef_assembly aref -> aref.QualifiedName
+
+    member scoref.QualifiedNameWithNoShortMscorlib = 
+        match scoref with 
+        | ScopeRef_local -> ""
+        | ScopeRef_module mref -> "module "^mref.Name
+        | ScopeRef_assembly aref -> aref.QualifiedName
+
+type ILArrayBound = int32 option 
+type ILArrayBounds = ILArrayBound * ILArrayBound
+
+[<StructuralEquality; StructuralComparison>]
+type ILArrayShape = 
+    | ILArrayShape of ILArrayBounds list (* lobound/size pairs *)
+    member x.Rank = (let (ILArrayShape l) = x in l.Length)
+
+
+/// Calling conventions.  These are used in method pointer types.
+[<StructuralEquality; StructuralComparison>]
+type ILArgumentConvention = 
+    | CC_default
+    | CC_cdecl 
+    | CC_stdcall 
+    | CC_thiscall 
+    | CC_fastcall 
+    | CC_vararg
+      
+[<StructuralEquality; StructuralComparison>]
+type ILThisConvention =
+    | CC_instance
+    | CC_instance_explicit
+    | CC_static
+
+let mutable instance_callconv : obj = new obj()
+let mutable static_callconv : obj = new obj()
+
+[<StructuralEquality; StructuralComparison>]
+type ILCallingConv =
+    | Callconv of ILThisConvention * ILArgumentConvention
+    member x.ThisConv           = let (Callconv(a,_b)) = x in a
+    member x.BasicConv          = let (Callconv(_a,b)) = x in b
+    member x.IsInstance         = match x.ThisConv with CC_instance -> true | _ -> false
+    member x.IsInstanceExplicit = match x.ThisConv with CC_instance_explicit -> true | _ -> false
+    member x.IsStatic           = match x.ThisConv with CC_static -> true | _ -> false
+
+    static member Instance : ILCallingConv = unbox(instance_callconv) 
+    static member Static : ILCallingConv = unbox(static_callconv) 
+
+do instance_callconv <- box (Callconv(CC_instance,CC_default))
+do static_callconv <- box (Callconv(CC_static,CC_default))
+
+let callconv_eq (a:ILCallingConv) b = (a = b)
+
+type ILBoxity = 
+  | AsObject 
+  | AsValue
+
+// IL type references have a pre-computed hash code to enable quick lookup tables during binary generation.
+[<CustomEquality; CustomComparison>]
+type ILTypeRef = 
+    { trefScope: ILScopeRef;
+      trefEnclosing: string list;
+      trefName: string; 
+      hashCode : int }
+      
+    static member Create(scope,enclosing,name) = 
+        let hashCode = hash scope * 17 ^^^ (hash enclosing * 101 <<< 1) ^^^ (hash name * 47 <<< 2)
+        { trefScope=scope;
+          trefEnclosing= enclosing;
+          trefName=name;
+          hashCode=hashCode }
+          
+    member x.Scope= x.trefScope
+    member x.Enclosing= x.trefEnclosing
+    member x.Name=x.trefName
+    member x.ApproxId= x.hashCode
+    override x.GetHashCode() = x.hashCode
+    override x.Equals(yobj) = 
+         let y = (yobj :?> ILTypeRef) 
+         (x.ApproxId = y.ApproxId) && 
+         (x.Scope = y.Scope) && 
+         (x.Name = y.Name) && 
+         (x.Enclosing = y.Enclosing)
+    interface System.IComparable with
+        override x.CompareTo(yobj) = 
+            let y = (yobj :?> ILTypeRef) 
+            let c = compare x.ApproxId y.ApproxId
+            if c <> 0 then c else
+            let c = compare x.Scope y.Scope
+            if c <> 0 then c else
+            let c = compare x.Name y.Name 
+            if c <> 0 then c else
+            compare x.Enclosing y.Enclosing
+        
+    member tref.FullName = String.concat "." (tref.Enclosing @ [tref.Name])
+        
+    member tref.BasicQualifiedName = 
+        String.concat "+" (tref.Enclosing @ [ tref.Name ])
+
+    member tref.AddQualifiedNameExtensionWithNoShortMscorlib(basic) = 
+        let sco = tref.Scope.QualifiedNameWithNoShortMscorlib
+        if sco = "" then basic else String.concat ", " [basic;sco]
+
+    member tref.QualifiedNameWithNoShortMscorlib = 
+        tref.AddQualifiedNameExtensionWithNoShortMscorlib(tref.BasicQualifiedName)
+
+    member tref.QualifiedName = 
+        let basic = tref.BasicQualifiedName
+        let sco = tref.Scope.QualifiedName
+        if sco = "" then basic else String.concat ", " [basic;sco]
+
+
+    override x.ToString() = x.FullName
+
+type 
+    [<StructuralEquality; StructuralComparison>]
+    ILTypeSpec = 
+    { tspecTypeRef: ILTypeRef;    
+      /// The type instantiation if the type is generic
+      tspecInst: ILGenericArgs }    
+    member x.TypeRef=x.tspecTypeRef
+    member x.Scope=x.TypeRef.Scope
+    member x.Enclosing=x.TypeRef.Enclosing
+    member x.Name=x.TypeRef.Name
+    member x.GenericArgs=x.tspecInst
+    static member Create(tref,inst) = { tspecTypeRef =tref; tspecInst=inst }
+    override x.ToString() = x.TypeRef.ToString() + (match x.GenericArgs with [] -> "" | _ -> "<...>")
+    member x.BasicQualifiedName = 
+        let tc = x.TypeRef.BasicQualifiedName
+        match x.GenericArgs with 
+        | [] -> tc
+        | args -> tc + "[" + String.concat "," (args |> List.map (fun arg -> "[" + arg.QualifiedNameWithNoShortMscorlib + "]")) + "]"
+
+    member x.AddQualifiedNameExtensionWithNoShortMscorlib(basic) = 
+        x.TypeRef.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
+
+and [<StructuralEquality; StructuralComparison>]
+    ILType =
+    | Type_void                   
+    | Type_array    of ILArrayShape * ILType 
+    | Type_value    of ILTypeSpec      
+    | Type_boxed    of ILTypeSpec      
+    | Type_ptr      of ILType             
+    | Type_byref    of ILType           
+    | Type_fptr     of ILCallingSignature 
+    | Type_tyvar    of uint16              
+    | Type_modified of bool * ILTypeRef * ILType
+
+    member x.BasicQualifiedName = 
+        match x with 
+        | Type_tyvar n -> "!" + string n
+        | Type_modified(_,_ty1,ty2) -> ty2.BasicQualifiedName
+        | Type_array (ILArrayShape(s),ty) -> ty.BasicQualifiedName + "[" + System.String(',',s.Length-1) + "]"
+        | Type_value tr | Type_boxed tr -> tr.BasicQualifiedName
+        | Type_void -> "void"
+        | Type_ptr _ty -> failwith "unexpected pointer type"
+        | Type_byref _ty -> failwith "unexpected byref type"
+        | Type_fptr _mref -> failwith "unexpected function pointer type"
+
+    member x.AddQualifiedNameExtensionWithNoShortMscorlib(basic) = 
+        match x with 
+        | Type_tyvar _n -> basic
+        | Type_modified(_,_ty1,ty2) -> ty2.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
+        | Type_array (ILArrayShape(_s),ty) -> ty.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
+        | Type_value tr | Type_boxed tr -> tr.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
+        | Type_void -> failwith "void"
+        | Type_ptr _ty -> failwith "unexpected pointer type"
+        | Type_byref _ty -> failwith "unexpected byref type"
+        | Type_fptr _mref -> failwith "unexpected function pointer type"
+        
+    member x.QualifiedNameWithNoShortMscorlib = 
+        x.AddQualifiedNameExtensionWithNoShortMscorlib(x.BasicQualifiedName)
+
+and 
+    [<CustomEquality; CustomComparison>]
+    IlxExtensionType = 
+    | Ext_typ of obj
+    member x.Value = (let (Ext_typ(v)) = x in v)
+    override x.Equals(yobj) = match yobj with :? IlxExtensionType as y -> Unchecked.equals x.Value y.Value | _ -> false
+    interface System.IComparable with
+        override x.CompareTo(yobj) = match yobj with :? IlxExtensionType as y -> Unchecked.compare x.Value y.Value | _ -> invalidOp "bad comparison"
+
+and [<StructuralEquality; StructuralComparison>]
+    ILCallingSignature = 
+    { callsigCallconv: ILCallingConv;
+      callsigArgs: ILType list;
+      callsigReturn: ILType }
+    member x.CallingConv = x.callsigCallconv
+    member x.ArgTypes = x.callsigArgs
+    member x.ReturnType = x.callsigReturn
+
+
+and ILGenericArgs = 
+    ILType list
+
+
+type ILMethodRef =
+    { mrefParent: ILTypeRef;
+      mrefCallconv: ILCallingConv;
+      mrefGenericArity: int; 
+      mrefName: string;
+      mrefArgs: ILType list;
+      mrefReturn: ILType }
+    member x.EnclosingTypeRef = x.mrefParent
+    member x.CallingConv = x.mrefCallconv
+    member x.Name = x.mrefName
+    member x.GenericArity = x.mrefGenericArity
+    member x.ArgCount = x.mrefArgs.Length
+    member x.ArgTypes = x.mrefArgs
+    member x.ReturnType = x.mrefReturn
+
+    static member Create(a,b,c,d,e,f) = 
+        { mrefParent= a;mrefCallconv=b;mrefName=c;mrefGenericArity=d; mrefArgs=e;mrefReturn=f }
+    override x.ToString() = x.EnclosingTypeRef.ToString() + "::" + x.Name + "(...)"
+
+
+[<StructuralEquality; StructuralComparison>]
+type ILFieldRef = 
+    { frefParent: ILTypeRef;
+      frefName: string;
+      frefType: ILType }
+    member x.EnclosingTypeRef = x.frefParent
+    member x.Name = x.frefName
+    member x.Type = x.frefType
+    override x.ToString() = x.EnclosingTypeRef.ToString() + "::" + x.Name
+
+[<StructuralEquality; StructuralComparison>]
+type ILMethodSpec = 
+    { mspecMethodRefF: ILMethodRef;
+      mspecEnclosingTypeF: ILType;          
+      mspecMethodInstF: ILGenericArgs; }     
+    static member Create(a,b,c) = { mspecEnclosingTypeF=a; mspecMethodRefF =b; mspecMethodInstF=c }
+    member x.MethodRef = x.mspecMethodRefF
+    member x.EnclosingType=x.mspecEnclosingTypeF
+    member x.GenericArgs=x.mspecMethodInstF
+    member x.Name=x.MethodRef.Name
+    member x.CallingConv=x.MethodRef.CallingConv
+    member x.GenericArity = x.MethodRef.GenericArity
+    member x.FormalArgTypes = x.MethodRef.ArgTypes
+    member x.FormalReturnType = x.MethodRef.ReturnType
+    override x.ToString() = x.MethodRef.ToString() + "(...)"
+
+type ILFieldSpec =
+    { fspecFieldRef: ILFieldRef;
+      fspecEnclosingType: ILType }         
+    member x.FieldRef         = x.fspecFieldRef
+    member x.EnclosingType    = x.fspecEnclosingType
+    member x.FormalType       = x.FieldRef.Type
+    member x.Name             = x.FieldRef.Name
+    member x.EnclosingTypeRef = x.FieldRef.EnclosingTypeRef
+    override x.ToString() = x.FieldRef.ToString()
+
+
+// --------------------------------------------------------------------
+// Debug info.                                                     
+// -------------------------------------------------------------------- 
+
+type Guid =  byte[]
+
+type ILPlatform = 
+    | X86
+    | AMD64
+    | IA64
+
+type ILSourceDocument = 
+    { sourceLanguage: Guid option; 
+      sourceVendor: Guid option;
+      sourceDocType: Guid option;
+      sourceFile: string; }
+    static member Create(language,vendor,docType,file) =
+        { sourceLanguage=language; 
+          sourceVendor=vendor;
+          sourceDocType=docType;
+          sourceFile=file; }
+    member x.Language=x.sourceLanguage
+    member x.Vendor=x.sourceVendor
+    member x.DocumentType=x.sourceDocType
+    member x.File=x.sourceFile
+
+type ILSourceMarker =
+    { sourceDocument: ILSourceDocument;
+      sourceLine: int;
+      sourceColumn: int;
+      sourceEndLine: int;
+      sourceEndColumn: int }
+    static member Create(document, line, column, endLine, endColumn) = 
+        { sourceDocument=document;
+          sourceLine=line;
+          sourceColumn=column;
+          sourceEndLine=endLine;
+          sourceEndColumn=endColumn }
+    member x.Document=x.sourceDocument
+    member x.Line=x.sourceLine
+    member x.Column=x.sourceColumn
+    member x.EndLine=x.sourceEndLine
+    member x.EndColumn=x.sourceEndColumn
+    override x.ToString() = sprintf "(%d,%d)-(%d,%d)" x.Line x.Column x.EndLine x.EndColumn
+
+// --------------------------------------------------------------------
+// Custom attributes                                                     
+// -------------------------------------------------------------------- 
+
+type ILAttributeElement =  
+  | CustomElem_string of string  option
+  | CustomElem_bool of bool
+  | CustomElem_char of char
+  | CustomElem_int8 of int8
+  | CustomElem_int16 of int16
+  | CustomElem_int32 of int32
+  | CustomElem_int64 of int64
+  | CustomElem_uint8 of uint8
+  | CustomElem_uint16 of uint16
+  | CustomElem_uint32 of uint32
+  | CustomElem_uint64 of uint64
+  | CustomElem_float32 of single
+  | CustomElem_float64 of double
+  | CustomElem_objnull 
+  | CustomElem_type of ILType option
+  | CustomElem_tref of ILTypeRef option
+  | CustomElem_array of ILType * ILAttributeElement list
+
+type ILAttributeNamedArg =  (string * ILType * bool * ILAttributeElement)
+type ILAttribute = 
+    { customMethod: ILMethodSpec;
+      customData: byte[] }
+    member x.Data = x.customData
+    member x.Method =x.customMethod
+
+[<NoEquality; NoComparison>]
+type ILAttributes = 
+   | CustomAttrs of Lazy<ILAttribute list>
+
+type ILCodeLabel = int
+
+// --------------------------------------------------------------------
+// Instruction set.                                                     
+// -------------------------------------------------------------------- 
+
+type ILBasicType =
+  | DT_R
+  | DT_I1
+  | DT_U1
+  | DT_I2
+  | DT_U2
+  | DT_I4
+  | DT_U4
+  | DT_I8
+  | DT_U8
+  | DT_R4
+  | DT_R8
+  | DT_I
+  | DT_U
+  | DT_REF
+
+type ILTokenSpec = 
+  | Token_type of ILType 
+  | Token_method of ILMethodSpec 
+  | Token_field of ILFieldSpec
+
+[<StructuralEquality; StructuralComparison>]
+type ILConstSpec = 
+  | NUM_I4 of int32
+  | NUM_I8 of int64
+  | NUM_R4 of single
+  | NUM_R8 of double
+
+type Tailcall = 
+  | Tailcall
+  | Normalcall
+
+type Alignment =  
+  | Aligned
+  | Unaligned_1
+  | Unaligned_2
+  | Unaligned_4
+
+type Volatility =  
+  | Volatile
+  | Nonvolatile
+
+type ReadonlySpec =  
+  | ReadonlyAddress
+  | NormalAddress
+
+type varargs = ILType list option
+
+[<StructuralEquality; StructuralComparison>]
+type ILComparisonInstr = 
+  | BI_beq        
+  | BI_bge        
+  | BI_bge_un     
+  | BI_bgt        
+  | BI_bgt_un        
+  | BI_ble        
+  | BI_ble_un        
+  | BI_blt        
+  | BI_blt_un 
+  | BI_bne_un 
+  | BI_brfalse 
+  | BI_brtrue 
+
+[<StructuralEquality; StructuralComparison>]
+type ILArithInstr = 
+  | AI_add    
+  | AI_add_ovf
+  | AI_add_ovf_un
+  | AI_and    
+  | AI_div   
+  | AI_div_un
+  | AI_ceq      
+  | AI_cgt      
+  | AI_cgt_un   
+  | AI_clt     
+  | AI_clt_un  
+  | AI_conv      of ILBasicType
+  | AI_conv_ovf  of ILBasicType
+  | AI_conv_ovf_un  of ILBasicType
+  | AI_mul       
+  | AI_mul_ovf   
+  | AI_mul_ovf_un
+  | AI_rem       
+  | AI_rem_un       
+  | AI_shl       
+  | AI_shr       
+  | AI_shr_un
+  | AI_sub       
+  | AI_sub_ovf   
+  | AI_sub_ovf_un   
+  | AI_xor       
+  | AI_or        
+  | AI_neg       
+  | AI_not       
+  | AI_ldnull    
+  | AI_dup       
+  | AI_pop
+  | AI_ckfinite 
+  | AI_nop
+  | AI_ldc of ILBasicType * ILConstSpec 
+
+
+
+[<StructuralEquality; NoComparison>]
+type ILInstr = 
+  | I_arith of ILArithInstr
+  | I_ldarg     of uint16
+  | I_ldarga    of uint16
+  | I_ldind     of Alignment * Volatility * ILBasicType
+  | I_ldloc     of uint16
+  | I_ldloca    of uint16
+  | I_starg     of uint16
+  | I_stind     of  Alignment * Volatility * ILBasicType
+  | I_stloc     of uint16
+
+  | I_br    of  ILCodeLabel
+  | I_jmp   of ILMethodSpec
+  | I_brcmp of ILComparisonInstr * ILCodeLabel * ILCodeLabel (* second label is fall-through *)
+  | I_switch    of (ILCodeLabel list * ILCodeLabel) (* last label is fallthrough *)
+  | I_ret 
+
+  | I_call     of Tailcall * ILMethodSpec * varargs
+  | I_callvirt of Tailcall * ILMethodSpec * varargs
+  | I_callconstraint of Tailcall * ILType * ILMethodSpec * varargs
+  | I_calli    of Tailcall * ILCallingSignature * varargs
+  | I_ldftn    of ILMethodSpec
+  | I_newobj  of ILMethodSpec  * varargs
+  
+  | I_throw
+  | I_endfinally
+  | I_endfilter
+  | I_leave     of  ILCodeLabel
+
+  | I_ldsfld      of Volatility * ILFieldSpec
+  | I_ldfld       of Alignment * Volatility * ILFieldSpec
+  | I_ldsflda     of ILFieldSpec
+  | I_ldflda      of ILFieldSpec 
+  | I_stsfld      of Volatility  *  ILFieldSpec
+  | I_stfld       of Alignment * Volatility * ILFieldSpec
+  | I_ldstr       of string
+  | I_isinst      of ILType
+  | I_castclass   of ILType
+  | I_ldtoken     of ILTokenSpec
+  | I_ldvirtftn   of ILMethodSpec
+
+  | I_cpobj       of ILType
+  | I_initobj     of ILType
+  | I_ldobj       of Alignment * Volatility * ILType
+  | I_stobj       of Alignment * Volatility * ILType
+  | I_box         of ILType
+  | I_unbox       of ILType
+  | I_unbox_any   of ILType
+  | I_sizeof      of ILType
+
+  | I_ldelem      of ILBasicType
+  | I_stelem      of ILBasicType
+  | I_ldelema     of ReadonlySpec * ILArrayShape * ILType
+  | I_ldelem_any  of ILArrayShape * ILType
+  | I_stelem_any  of ILArrayShape * ILType
+  | I_newarr      of ILArrayShape * ILType 
+  | I_ldlen
+
+  | I_mkrefany    of ILType
+  | I_refanytype  
+  | I_refanyval   of ILType
+  | I_rethrow
+
+  | I_break 
+  | I_seqpoint of ILSourceMarker
+
+  | I_arglist  
+
+  | I_localloc
+  | I_cpblk of Alignment * Volatility
+  | I_initblk of Alignment  * Volatility
+
+  (* FOR EXTENSIONS, e.g. MS-ILX *)  
+  | EI_ilzero of ILType
+  | EI_ldlen_multi      of int32 * int32
+  | I_other    of IlxExtensionInstr
+
+and IlxExtensionInstr = Ext_instr of obj
+
+
+type ILDebugMapping = 
+    { localNum: int;
+      localName: string; }
+    member x.LocalVarIndex = x.localNum
+    member x.Name = x.localName
+
+type ILBasicBlock = 
+    { bblockLabel: ILCodeLabel;
+      bblockInstrs: ILInstr array }
+    member x.Label = x.bblockLabel
+    member x.Instructions = x.bblockInstrs
+
+type ILCode = 
+    | ILBasicBlock    of ILBasicBlock
+    | GroupBlock    of ILDebugMapping list * ILCode list
+    | RestrictBlock of ILCodeLabel list * ILCode
+    | TryBlock      of ILCode * ILExceptionBlock
+
+and ILExceptionBlock = 
+    | FaultBlock       of ILCode 
+    | FinallyBlock     of ILCode
+    | FilterCatchBlock of (ILFilterBlock * ILCode) list
+
+and ILFilterBlock = 
+    | TypeFilter of ILType
+    | CodeFilter of ILCode
+
+type Local = 
+    { localType: ILType;
+      localPinned: bool }
+    member x.Type = x.localType
+    member x.IsPinned = x.localPinned
+      
+type ILMethodBody = 
+    { ilZeroInit: bool;
+      ilMaxStack: int32;
+      ilNoInlining: bool;
+      ilLocals: Local list;
+      ilCode:  ILCode;
+      ilSource: ILSourceMarker option }
+
+type ILMemberAccess = 
+    | MemAccess_assembly
+    | MemAccess_compilercontrolled
+    | MemAccess_famandassem
+    | MemAccess_famorassem
+    | MemAccess_family
+    | MemAccess_private 
+    | MemAccess_public 
+
+[<StructuralEquality; StructuralComparison>]
+[<RequireQualifiedAccess>]
+type ILFieldInit = 
+    | String of string
+    | Bool of bool
+    | Char of uint16
+    | Int8 of int8
+    | Int16 of int16
+    | Int32 of int32
+    | Int64 of int64
+    | UInt8 of uint8
+    | UInt16 of uint16
+    | UInt32 of uint32
+    | UInt64 of uint64
+    | Single of single
+    | Double of double
+    | Null
+  
+// -------------------------------------------------------------------- 
+// Native Types, for marshalling to the native C interface.
+// These are taken directly from the ILASM syntax, and don't really
+// correspond yet to the ECMA Spec (Partition II, 7.4).  
+// -------------------------------------------------------------------- 
+
+[<StructuralEquality; StructuralComparison>]
+type ILNativeType = 
+    | NativeType_empty
+    | NativeType_custom of Guid * string * string * byte[] (* guid,nativeTypeName,custMarshallerName,cookieString *)
+    | NativeType_fixed_sysstring of int32
+    | NativeType_fixed_array of int32
+    | NativeType_currency
+    | NativeType_lpstr
+    | NativeType_lpwstr
+    | NativeType_lptstr
+    | NativeType_byvalstr
+    | NativeType_tbstr
+    | NativeType_lpstruct
+    | NativeType_struct
+    | NativeType_void
+    | NativeType_bool
+    | NativeType_int8
+    | NativeType_int16
+    | NativeType_int32
+    | NativeType_int64
+    | NativeType_float32
+    | NativeType_float64
+    | NativeType_unsigned_int8
+    | NativeType_unsigned_int16
+    | NativeType_unsigned_int32
+    | NativeType_unsigned_int64
+    | NativeType_array of ILNativeType option * (int32 * int32 option) option (* optional idx of parameter giving size plus optional additive i.e. num elems *)
+    | NativeType_int
+    | NativeType_unsigned_int
+    | NativeType_method
+    | NativeType_as_any
+    | (* COM interop *) NativeType_bstr
+    | (* COM interop *) NativeType_iunknown
+    | (* COM interop *) NativeType_idsipatch
+    | (* COM interop *) NativeType_interface
+    | (* COM interop *) NativeType_error               
+    | (* COM interop *) NativeType_safe_array of ILNativeVariantType * string option 
+    | (* COM interop *) NativeType_ansi_bstr
+    | (* COM interop *) NativeType_variant_bool
+
+
+  and ILNativeVariantType = 
+    | VariantType_empty
+    | VariantType_null
+    | VariantType_variant
+    | VariantType_currency
+    | VariantType_decimal               
+    | VariantType_date               
+    | VariantType_bstr               
+    | VariantType_lpstr               
+    | VariantType_lpwstr               
+    | VariantType_iunknown               
+    | VariantType_idispatch               
+    | VariantType_safearray               
+    | VariantType_error               
+    | VariantType_hresult               
+    | VariantType_carray               
+    | VariantType_userdefined               
+    | VariantType_record               
+    | VariantType_filetime
+    | VariantType_blob               
+    | VariantType_stream               
+    | VariantType_storage               
+    | VariantType_streamed_object               
+    | VariantType_stored_object               
+    | VariantType_blob_object               
+    | VariantType_cf                
+    | VariantType_clsid
+    | VariantType_void 
+    | VariantType_bool
+    | VariantType_int8
+    | VariantType_int16                
+    | VariantType_int32                
+    | VariantType_int64                
+    | VariantType_float32                
+    | VariantType_float64                
+    | VariantType_unsigned_int8                
+    | VariantType_unsigned_int16                
+    | VariantType_unsigned_int32                
+    | VariantType_unsigned_int64                
+    | VariantType_ptr                
+    | VariantType_array of ILNativeVariantType                
+    | VariantType_vector of ILNativeVariantType                
+    | VariantType_byref of ILNativeVariantType                
+    | VariantType_int                
+    | VariantType_unsigned_int                
+
+type ILSecurityAction = 
+    | SecAction_request 
+    | SecAction_demand
+    | SecAction_assert
+    | SecAction_deny
+    | SecAction_permitonly
+    | SecAction_linkcheck 
+    | SecAction_inheritcheck
+    | SecAction_reqmin
+    | SecAction_reqopt
+    | SecAction_reqrefuse
+    | SecAction_prejitgrant
+    | SecAction_prejitdeny
+    | SecAction_noncasdemand
+    | SecAction_noncaslinkdemand
+    | SecAction_noncasinheritance
+    | SecAction_linkdemandchoice
+    | SecAction_inheritancedemandchoice
+    | SecAction_demandchoice
+
+type ILPermission = 
+    | PermissionSet of ILSecurityAction * byte[]
+
+type ILPermissions =
+    | SecurityDecls of Lazy<ILPermission list>
+
+[<RequireQualifiedAccess>]
+type PInvokeCharBestFit  = 
+    | UseAssembly
+    | Enabled
+    | Disabled
+
+[<RequireQualifiedAccess>]
+type PInvokeThrowOnUnmappableChar =
+    | UseAssembly
+    | Enabled
+    | Disabled
+
+[<RequireQualifiedAccess>]
+type PInvokeCallingConvention =
+    | None
+    | Cdecl
+    | Stdcall
+    | Thiscall
+    | Fastcall
+    | WinApi
+
+[<RequireQualifiedAccess>]
+type PInvokeCharEncoding =
+    | None
+    | Ansi
+    | Unicode
+    | Auto
+
+type PInvokeMethod =
+    { pinvokeWhere: ILModuleRef;
+      pinvokeName: string;
+      pinvokeCallconv: PInvokeCallingConvention;
+      PInvokeCharEncoding: PInvokeCharEncoding;
+      pinvokeNoMangle: bool;
+      pinvokeLastErr: bool;
+      PInvokeThrowOnUnmappableChar: PInvokeThrowOnUnmappableChar;
+      PInvokeCharBestFit: PInvokeCharBestFit }
+    member x.Where = x.pinvokeWhere
+    member x.Name = x.pinvokeName
+    member x.CallingConv = x.pinvokeCallconv
+    member x.CharEncoding = x.PInvokeCharEncoding
+    member x.NoMangle = x.pinvokeNoMangle
+    member x.LastError = x.pinvokeLastErr
+    member x.ThrowOnUnmappableChar = x.PInvokeThrowOnUnmappableChar
+    member x.CharBestFit = x.PInvokeCharBestFit
+
+type ILParameter =
+    { paramName: string option;
+      paramType: ILType;
+      paramDefault: ILFieldInit option;  
+      paramMarshal: ILNativeType option; 
+      paramIn: bool;
+      paramOut: bool;
+      paramOptional: bool;
+      paramCustomAttrs: ILAttributes }
+    member x.Name = x.paramName
+    member x.Type = x.paramType
+    member x.Default = x.paramDefault
+    member x.Marshal = x.paramMarshal
+    member x.IsIn = x.paramIn
+    member x.IsOut = x.paramOut
+    member x.IsOptional = x.paramOptional
+    member x.CustomAttrs = x.paramCustomAttrs
+
+
+type ILReturnValue = 
+    { returnMarshal: ILNativeType option;
+      returnType: ILType; 
+      returnCustomAttrs: ILAttributes }
+    member x.Type =  x.returnType
+    member x.Marshal = x.returnMarshal
+    member x.CustomAttrs = x.returnCustomAttrs
+
+type OverridesSpec = 
+    | OverridesSpec of ILMethodRef * ILType
+    member x.MethodRef = let (OverridesSpec(mr,_ty)) = x in mr
+    member x.EnclosingType = let (OverridesSpec(_mr,ty)) = x in ty
+
+type ILMethodVirtualInfo = 
+    { virtFinal: bool; 
+      virtNewslot: bool; 
+      virtStrict: bool; (* mdCheckAccessOnOverride *)
+      virtAbstract: bool;
+    }
+    member x.IsFinal = x.virtFinal
+    member x.IsNewSlot = x.virtNewslot
+    member x.IsCheckAccessOnOverride = x.virtStrict
+    member x.IsAbstract = x.virtAbstract
+
+type MethodKind =
+    | MethodKind_static 
+    | MethodKind_cctor 
+    | MethodKind_ctor 
+    | MethodKind_nonvirtual 
+    | MethodKind_virtual of ILMethodVirtualInfo
+
+type MethodBody =
+    | MethodBody_il of ILMethodBody
+    | MethodBody_pinvoke of PInvokeMethod       (* platform invoke to native  *)
+    | MethodBody_abstract
+    | MethodBody_native
+
+type LazyMethodBody = LazyMethodBody of Lazy<MethodBody >
+
+type MethodCodeKind =
+    | MethodCodeKind_il
+    | MethodCodeKind_native
+    | MethodCodeKind_runtime
+
+let mk_mbody mb = LazyMethodBody (Lazy.CreateFromValue mb)
+let dest_mbody (LazyMethodBody mb) = mb.Force()
+let mk_lazy_mbody mb = LazyMethodBody mb
+
+let typs_of_params (ps:ILParameter list) = ps |> List.map (fun p -> p.Type) 
+
+[<StructuralEquality; StructuralComparison>]
+type ILGenericVariance = 
+    | NonVariant            
+    | CoVariant             
+    | ContraVariant         
+
+type ILGenericParameterDef =
+    { gpName: string;
+      gpConstraints: ILType list;
+      gpVariance: ILGenericVariance; 
+      gpReferenceTypeConstraint: bool;     
+      gpCustomAttrs : ILAttributes;
+      gpNotNullableValueTypeConstraint: bool;
+      gpDefaultConstructorConstraint: bool; }
+
+    member x.Name = x.gpName
+    member x.Constraints = x.gpConstraints
+    member x.Variance = x.gpVariance
+    member x.HasReferenceTypeConstraint = x.gpReferenceTypeConstraint
+    member x.HasNotNullableValueTypeConstraint = x.gpNotNullableValueTypeConstraint
+    member x.HasDefaultConstructorConstraint = x.gpDefaultConstructorConstraint
+    override x.ToString() = x.Name 
+
+type ILGenericParameterDefs = ILGenericParameterDef list
+
+type ILMethodDef = 
+    { mdName: string;
+      mdKind: MethodKind;
+      mdCallconv: ILCallingConv;
+      mdParams: ILParameter list;
+      mdReturn: ILReturnValue;
+      mdAccess: ILMemberAccess;
+      mdBody: LazyMethodBody;   
+      mdCodeKind: MethodCodeKind;   
+      mdInternalCall: bool;
+      mdManaged: bool;
+      mdForwardRef: bool;
+      mdSecurityDecls: ILPermissions;
+      mdHasSecurity: bool;
+      mdEntrypoint:bool;
+      mdReqSecObj: bool;
+      mdHideBySig: bool;
+      mdSpecialName: bool;
+      mdUnmanagedExport: bool;
+      mdSynchronized: bool;
+      mdPreserveSig: bool;
+      mdMustRun: bool; 
+      mdExport: (int32 * string option) option;
+      mdVtableEntry: (int32 * int32) option;
+     
+      mdGenericParams: ILGenericParameterDefs;
+      mdCustomAttrs: ILAttributes; }
+    member x.Name = x.mdName
+    member x.CallingConv = x.mdCallconv
+    member x.Parameters = x.mdParams
+    member x.ParameterTypes = typs_of_params x.mdParams
+    member x.Return = x.mdReturn
+    member x.Access = x.mdAccess
+    member x.IsInternalCall = x.mdInternalCall
+    member x.IsManaged = x.mdManaged
+    member x.IsForwardRef = x.mdForwardRef
+    member x.SecurityDecls = x.mdSecurityDecls
+    member x.HasSecurity = x.mdHasSecurity
+    member x.IsEntrypoint = x.mdEntrypoint
+    member x.IsReqSecObj = x.mdReqSecObj
+    member x.IsHideBySig = x.mdHideBySig
+    member x.IsUnmanagedExport = x.mdUnmanagedExport
+    member x.IsSynchronized = x.mdSynchronized
+    member x.IsPreserveSig = x.mdPreserveSig
+    // Whidbey feature: SafeHandle finalizer must be run 
+    member x.IsMustRun = x.mdMustRun
+    member x.GenericParams = x.mdGenericParams
+    member x.CustomAttrs = x.mdCustomAttrs
+    member md.Code = 
+          match dest_mbody md.mdBody with 
+          | MethodBody_il il-> Some il.ilCode
+          | _ -> None
+    member x.IsIL = match dest_mbody x.mdBody with | MethodBody_il _ -> true | _ -> false
+    member x.Locals = match dest_mbody x.mdBody with | MethodBody_il il -> il.ilLocals | _ -> []
+
+    member x.MethodBody = match dest_mbody x.mdBody with MethodBody_il il -> il | _ -> failwith "ilmbody_of_mdef: not IL"
+
+    member x.IsNoInline   = x.MethodBody.ilNoInlining  
+    member x.SourceMarker = x.MethodBody.ilSource
+    member x.MaxStack     = x.MethodBody.ilMaxStack  
+    member x.IsZeroInit   = x.MethodBody.ilZeroInit
+
+    member x.IsClassInitializer   = match x.mdKind with | MethodKind_cctor      -> true | _ -> false
+    member x.IsConstructor        = match x.mdKind with | MethodKind_ctor       -> true | _ -> false
+    member x.IsStatic             = match x.mdKind with | MethodKind_static     -> true | _ -> false
+    member x.IsNonVirtualInstance = match x.mdKind with | MethodKind_nonvirtual -> true | _ -> false
+    member x.IsVirtual            = match x.mdKind with | MethodKind_virtual _  -> true | _ -> false
+
+    member x.IsFinal                = match x.mdKind with | MethodKind_virtual v -> v.virtFinal    | _ -> invalidOp "ILMethodDef.IsFinal"
+    member x.IsNewSlot              = match x.mdKind with | MethodKind_virtual v -> v.virtNewslot  | _ -> invalidOp "ILMethodDef.IsNewSlot"
+    member x.IsCheckAccessOnOverride= match x.mdKind with | MethodKind_virtual v -> v.virtStrict   | _ -> invalidOp "ILMethodDef.IsCheckAccessOnOverride"
+    member x.IsAbstract             = match x.mdKind with | MethodKind_virtual v -> v.virtAbstract | _ -> invalidOp "ILMethodDef.IsAbstract"
+
+/// Index table by name and arity. 
+type MethodDefMap = Map<string, ILMethodDef list>
+
+[<NoEquality; NoComparison>]
+type ILMethodDefs = 
+    | Methods of Lazy<ILMethodDef list * MethodDefMap>
+    interface IEnumerable with 
+        member x.GetEnumerator() = ((x :> IEnumerable<ILMethodDef>).GetEnumerator() :> IEnumerator)
+    interface IEnumerable<ILMethodDef> with 
+        member x.GetEnumerator() = 
+            let (Methods(lms)) = x
+            let ms,_ = lms.Force()
+            (ms :> IEnumerable<ILMethodDef>).GetEnumerator()
+    member x.AsList = Seq.toList x
+
+type ILEventDef =
+    { eventType: ILType option; 
+      eventName: string;
+      eventRTSpecialName: bool;
+      eventSpecialName: bool;
+      eventAddOn: ILMethodRef; 
+      eventRemoveOn: ILMethodRef;
+      eventFire: ILMethodRef option;
+      eventOther: ILMethodRef list;
+      eventCustomAttrs: ILAttributes; }
+    member x.Type = x.eventType
+    member x.Name = x.eventName
+    member x.AddMethod = x.eventAddOn
+    member x.RemoveMethod = x.eventRemoveOn
+    member x.FireMethod = x.eventFire
+    member x.OtherMethods = x.eventOther
+    member x.CustomAttrs = x.eventCustomAttrs
+
+(* Index table by name. *)
+[<NoEquality; NoComparison>]
+type ILEventDefs = 
+    | Events of LazyOrderedMultiMap<string, ILEventDef>
+
+type ILPropertyDef = 
+    { propName: string;
+      propRTSpecialName: bool;
+      propSpecialName: bool;
+      propSet: ILMethodRef option;
+      propGet: ILMethodRef option;
+      propCallconv: ILThisConvention;
+      propType: ILType;
+      propInit: ILFieldInit option;
+      propArgs: ILType list;
+      propCustomAttrs: ILAttributes; }
+    member x.Name = x.propName
+    member x.SetMethod = x.propSet
+    member x.GetMethod = x.propGet
+    member x.CallingConv = x.propCallconv
+    member x.Type = x.propType
+    member x.Init = x.propInit
+    member x.Args = x.propArgs
+    member x.CustomAttrs = x.propCustomAttrs
+    
+// Index table by name.
+[<NoEquality; NoComparison>]
+type ILPropertyDefs = 
+    | Properties of LazyOrderedMultiMap<string, ILPropertyDef>
+
+type ILFieldDef = 
+    { fdName: string;
+      fdType: ILType;
+      fdStatic: bool;
+      fdAccess: ILMemberAccess;
+      fdData:  byte[] option;
+      fdInit:  ILFieldInit option;
+      fdOffset:  int32 option; (* -- the explicit offset in bytes *)
+      fdSpecialName: bool;
+      fdMarshal: ILNativeType option; 
+      fdNotSerialized: bool;
+      fdLiteral: bool ;
+      fdInitOnly: bool;
+      fdCustomAttrs: ILAttributes; }
+    member x.Name = x.fdName
+    member x.Type = x.fdType
+    member x.IsStatic = x.fdStatic
+    member x.Access = x.fdAccess
+    member x.Data = x.fdData
+    member x.LiteralValue = x.fdInit
+    /// The explicit offset in bytes when explicit layout is used.
+    member x.Offset = x.fdOffset
+    member x.Marshal = x.fdMarshal
+    member x.NotSerialized = x.fdNotSerialized
+    member x.IsLiteral = x.fdLiteral
+    member x.IsInitOnly = x.fdInitOnly
+    member x.CustomAttrs = x.fdCustomAttrs
+
+
+// Index table by name.  Keep a canonical list to make sure field order is not disturbed for binary manipulation.
+type ILFieldDefs = 
+    | Fields of LazyOrderedMultiMap<string, ILFieldDef>
+
+type ILMethodImplDef =
+    { mimplOverrides: OverridesSpec;
+      mimplOverrideBy: ILMethodSpec }
+
+// Index table by name and arity. 
+type ILMethodImplDefs = 
+    | MethodImpls of Lazy<MethodImplsMap>
+and MethodImplsMap = Map<string * int, ILMethodImplDef list>
+
+type ILTypeDefLayout =
+    | TypeLayout_auto
+    | TypeLayout_sequential of ILTypeDefLayoutInfo
+    | TypeLayout_explicit of ILTypeDefLayoutInfo 
+
+and ILTypeDefLayoutInfo =
+    { typeSize: int32 option;
+      typePack: uint16 option } 
+    member x.Size = x.typeSize
+    member x.Pack = x.typePack
+
+type ILTypeDefInitSemantics =
+    | TypeInit_beforefield
+    | TypeInit_onany
+
+[<RequireQualifiedAccess>]
+type ILDefaultPInvokeEncoding =
+    | Ansi
+    | Auto
+    | Unicode
+
+type ILTypeDefAccess =
+    | Public 
+    | Private
+    | Nested of ILMemberAccess 
+
+[<RequireQualifiedAccess>]
+type ILTypeDefKind =
+    | Class
+    | ValueType
+    | Interface
+    | Enum 
+    | Delegate
+    | Other of IlxExtensionTypeKind
+
+and IlxExtensionTypeKind = Ext_type_def_kind of obj
+
+
+type ILTypeDef =  
+    { tdKind: ILTypeDefKind;
+      tdName: string;  
+      tdGenericParams: ILGenericParameterDefs;   (* class is generic *)
+      tdAccess: ILTypeDefAccess;  
+      tdAbstract: bool;
+      tdSealed: bool; 
+      tdSerializable: bool; 
+      tdComInterop: bool; (* Class or interface generated for COM interop *) 
+      tdLayout: ILTypeDefLayout;
+      tdSpecialName: bool;
+      tdEncoding: ILDefaultPInvokeEncoding;
+      tdNested: ILTypeDefs;
+      tdImplements: ILType list;  
+      tdExtends: ILType option; 
+      tdMethodDefs: ILMethodDefs;
+      tdSecurityDecls: ILPermissions;
+      tdHasSecurity: bool;
+      tdFieldDefs: ILFieldDefs;
+      tdMethodImpls: ILMethodImplDefs;
+      tdInitSemantics: ILTypeDefInitSemantics;
+      tdEvents: ILEventDefs;
+      tdProperties: ILPropertyDefs;
+      tdCustomAttrs: ILAttributes; }
+    member x.IsClass=     (match x.tdKind with ILTypeDefKind.Class -> true | _ -> false)
+    member x.IsValueType= (match x.tdKind with ILTypeDefKind.ValueType -> true | _ -> false)
+    member x.IsInterface= (match x.tdKind with ILTypeDefKind.Interface -> true | _ -> false)
+    member x.IsEnum=      (match x.tdKind with ILTypeDefKind.Enum -> true | _ -> false)
+    member x.IsDelegate=  (match x.tdKind with ILTypeDefKind.Delegate -> true | _ -> false)
+    member x.Name = x.tdName
+    member x.GenericParams = x.tdGenericParams
+    member x.Access = x.tdAccess
+    member x.IsAbstract = x.tdAbstract
+    member x.IsSealed = x.tdSealed
+    member x.IsSerializable = x.tdSerializable
+    member x.IsComInterop = x.tdComInterop
+    member x.Layout = x.tdLayout
+    member x.IsSpecialName = x.tdSpecialName
+    member x.Encoding = x.tdEncoding
+    member x.NestedTypes = x.tdNested
+    member x.Implements = x.tdImplements
+    member x.Extends = x.tdExtends
+    member x.Methods = x.tdMethodDefs
+    member x.SecurityDecls = x.tdSecurityDecls
+    member x.HasSecurity = x.tdHasSecurity
+    member x.Fields = x.tdFieldDefs
+    member x.MethodImpls = x.tdMethodImpls
+    member x.InitSemantics = x.tdInitSemantics
+    member x.Events = x.tdEvents
+    member x.Properties = x.tdProperties
+    member x.CustomAttrs = x.tdCustomAttrs
+
+and ILTypeDefs = 
+    | TypeDefTable of Lazy<(string list * string * ILAttributes * Lazy<ILTypeDef>) array> * Lazy<TypeDefsMap>
+    interface IEnumerable with 
+        member x.GetEnumerator() = ((x :> IEnumerable<ILTypeDef>).GetEnumerator() :> IEnumerator)
+    interface IEnumerable<ILTypeDef> with 
+        member x.GetEnumerator() = 
+            let (TypeDefTable (larr,_tab)) = x
+            let tds = seq { for (_,_,_,td) in larr.Force() -> td.Force() }
+            tds.GetEnumerator()
+    member x.AsList = Seq.toList x
+        
+/// keyed first on namespace then on type name.  The namespace is often a unique key for a given type map.
+and TypeDefsMap = 
+     Map<string list,Dictionary<string,Lazy<ILTypeDef>>>
+
+and NamespaceAndTypename = string list * string
+
+type ILNestedExportedType =
+    { nestedExportedTypeName: string;
+      nestedExportedTypeAccess: ILMemberAccess;
+      nestedExportedTypeNested: ILNestedExportedTypes;
+      nestedExportedTypeCustomAttrs: ILAttributes } 
+
+and ILNestedExportedTypes = ILNestedExportedTypes of Lazy<NestedExportedTypesMap>
+and NestedExportedTypesMap = Map<string,ILNestedExportedType>
+
+and ILExportedType =
+    { exportedTypeScope: ILScopeRef;
+      exportedTypeName: string;
+      exportedTypeForwarder: bool;
+      exportedTypeAccess: ILTypeDefAccess;
+      exportedTypeNested: ILNestedExportedTypes;
+      exportedTypeCustomAttrs: ILAttributes } 
+    member x.ScopeRef = x.exportedTypeScope
+    member x.Name = x.exportedTypeName
+    member x.IsForwarder = x.exportedTypeForwarder
+    member x.Access = x.exportedTypeAccess
+    member x.Nested = x.exportedTypeNested
+    member x.CustomAttrs = x.exportedTypeCustomAttrs
+
+and ILExportedTypes = ILExportedTypes of Lazy<ExportedTypesMap>
+and ExportedTypesMap = Map<string,ILExportedType>
+
+[<RequireQualifiedAccess>]
+type ILResourceAccess = 
+    | Public 
+    | Private 
+
+[<RequireQualifiedAccess>]
+type ILResourceLocation =
+    | Local of (unit -> byte[])
+    | File of ILModuleRef * int32
+    | Assembly of ILAssemblyRef
+
+type ILResource =
+    { resourceName: string;
+      resourceWhere: ILResourceLocation;
+      resourceAccess: ILResourceAccess;
+      resourceCustomAttrs: ILAttributes }
+    member x.Name = x.resourceName
+    member x.Location = x.resourceWhere
+    member x.Access = x.resourceAccess
+    member x.CustomAttrs = x.resourceCustomAttrs
+
+type ILResources = ILResources of Lazy<ILResource list>
+
+// -------------------------------------------------------------------- 
+// One module in the "current" assembly
+// -------------------------------------------------------------------- 
+
+[<RequireQualifiedAccess>]
+type ILAssemblyLongevity =
+    | Unspecified
+    | Library
+    | PlatformAppDomain
+    | PlatformProcess
+    | PlatformSystem
+
+
+type ILAssemblyManifest = 
+    { manifestName: string;
+      manifestAuxModuleHashAlgorithm: int32;
+      manifestSecurityDecls: ILPermissions;
+      manifestPublicKey: byte[] option;
+      manifestVersion: ILVersionInfo option;
+      manifestLocale: Locale option;
+      manifestCustomAttrs: ILAttributes;
+
+      manifestLongevity: ILAssemblyLongevity; 
+      manifestDisableJitOptimizations: bool;
+      manifestJitTracking: bool;
+      manifestRetargetable: bool;
+
+      manifestExportedTypes: ILExportedTypes;
+               (* -- Records the types impemented by other modules. *)
+      manifestEntrypointElsewhere: ILModuleRef option; 
+               (* -- Records whether the entrypoint resides in another module. *)
+    } 
+    member x.Name = x.manifestName
+    member x.AuxModuleHashAlgorithm = x.manifestAuxModuleHashAlgorithm
+    member x.SecurityDecls = x.manifestSecurityDecls
+    member x.PublicKey = x.manifestPublicKey
+    member x.Version = x.manifestVersion
+    member x.Locale = x.manifestLocale
+    member x.CustomAttrs = x.manifestCustomAttrs
+    member x.AssemblyLongevity = x.manifestLongevity
+    member x.DisableJitOptimizations = x.manifestDisableJitOptimizations
+    member x.JitTracking = x.manifestJitTracking
+    member x.Retargetable = x.manifestRetargetable
+    member x.ExportedTypes = x.manifestExportedTypes
+    member x.EntrypointElsewhere = x.manifestEntrypointElsewhere
+
+type ILModuleDef = 
+    { modulManifest: ILAssemblyManifest option;
+      modulCustomAttrs: ILAttributes;
+      modulName: string;
+      modulTypeDefs: ILTypeDefs;
+      (* Random bits of relatively uninteresting data *)
+      modulSubSystem: int32;
+      modulDLL: bool;
+      modulILonly: bool;
+      modulPlatform: ILPlatform option; 
+      modulStackReserveSize: int32 option;
+      modul32bit: bool;
+      modul64bit: bool;
+      modulVirtAlignment: int32;
+      modulPhysAlignment: int32;
+      modulImageBase: int32;
+      modulMetadataVersion: string;
+      modulResources: ILResources;
+      modulNativeResources: list<Lazy<byte[]>>; (* e.g. win32 resources *)
+    }
+    member x.Manifest = x.modulManifest
+    member x.CustomAttrs = x.modulCustomAttrs
+    member x.Name = x.modulName
+    member x.TypeDefs = x.modulTypeDefs
+    member x.SubSystemFlags = x.modulSubSystem
+    member x.IsDLL = x.modulDLL
+    member x.IsILOnly = x.modulILonly
+    member x.Platform = x.modulPlatform
+    member x.Is32Bit = x.modul32bit
+    member x.Is64Bit = x.modul64bit
+    member x.VirtualAlignment = x.modulVirtAlignment
+    member x.PhysicalAlignment = x.modulPhysAlignment
+    member x.ImageBase = x.modulImageBase
+    member x.MetadataVersion = x.modulMetadataVersion
+    member x.Resources = x.modulResources
+    member x.NativeResources = x.modulNativeResources
+
+    member x.ManifestOfAssembly = 
+        match x.modulManifest with 
+        | Some m -> m
+        | None -> failwith "no manifest.  It is possible you are using an auxiliary module of an assembly in a context where the main module of an assembly is expected.  Typically the main module of an assembly must be specified first within a list of the modules in an assembly."
+
+
+
+// -------------------------------------------------------------------- 
+// Utilities: type names
+// -------------------------------------------------------------------- 
+
+let split_name_at nm idx = 
+    if idx < 0 then failwith "split_name_at: idx < 0";
+    let last = String.length nm - 1 
+    if idx > last then failwith "split_name_at: idx > last";
+    (nm.Substring(0,idx)),
+    (if idx < last then nm.Substring (idx+1,last - idx) else "")
+
+let rec split_namespace_aux (nm:string) = 
+    match nm.IndexOf '.' with 
+    | -1 -> [nm]
+    | idx -> 
+        let s1,s2 = split_name_at nm idx 
+        s1::split_namespace_aux s2 
+
+/// Global State. All namespace splits
+let memoize_namespace_tab = 
+    Dictionary<string,string list>(10)
+
+let split_namespace nm =
+    let mutable res = Unchecked.defaultof<_>
+    let ok = memoize_namespace_tab.TryGetValue(nm,&res)
+    if ok then res else
+    let x = split_namespace_aux nm
+    (memoize_namespace_tab.[nm] <- x; x)
+
+let split_type_name (nm:string) = 
+    match nm.LastIndexOf '.' with
+    | -1 -> [],nm
+    | idx -> 
+        let s1,s2 = split_name_at nm idx
+        split_namespace s1,s2
+
+
+let mk_empty_gparams = ([]: ILGenericParameterDefs)
+let mk_empty_gactuals = ([]: ILGenericArgs)
+
+
+type ILType with
+    member x.TypeSpec =
+      match x with 
+      | Type_boxed tr | Type_value tr -> tr
+      | _ -> failwith "tspec_of_typ"
+    member x.Boxity =
+      match x with 
+      | Type_boxed _ -> AsObject
+      | Type_value _ -> AsValue
+      | _ -> failwith "boxity_of_typ"
+    member x.TypeRef = 
+      match x with 
+      | Type_boxed tspec | Type_value tspec -> tspec.TypeRef
+      | _ -> failwith "tref_of_typ"
+    member x.IsNominal = 
+      match x with 
+      | Type_boxed _ | Type_value _ -> true
+      | _ -> false
+    member x.GenericArgs =
+      match x with 
+      | Type_boxed tspec | Type_value tspec -> tspec.GenericArgs
+      | _ -> mk_empty_gactuals
+    member x.IsTyvar =
+      match x with 
+      | Type_tyvar _ -> true | _ -> false
+
+// --------------------------------------------------------------------
+// Make ILTypeRefs etc.
+// -------------------------------------------------------------------- 
+
+let mk_tspec (tref,inst) =  ILTypeSpec.Create(tref, inst)
+let mk_typ boxed tspec = 
+  match boxed with AsObject -> Type_boxed tspec | _ -> Type_value tspec
+
+// -------------------------------------------------------------------- 
+// Rescoping
+// -------------------------------------------------------------------- 
+
+let qrescope_scoref scoref scoref_old = 
+  match scoref,scoref_old with 
+  | _,ScopeRef_local -> Some scoref
+  | ScopeRef_local,_ -> None
+  | _,ScopeRef_module _ -> Some scoref
+  | ScopeRef_module _,_ -> None
+  | _ -> None
+
+let rescope_scoref x y = match qrescope_scoref x y with Some x -> x | None -> y
diff --git a/src/FSharp.PowerPack.Metadata/pickle.fs b/src/FSharp.PowerPack.Metadata/pickle.fs
new file mode 100755
index 0000000..ae745ac
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/pickle.fs
@@ -0,0 +1,1369 @@
+// (c) Microsoft Corporation. All rights reserved
+
+
+module internal Microsoft.FSharp.Metadata.Reader.Internal.Pickle
+
+open System.Collections.Generic 
+open Microsoft.FSharp.Metadata.Reader.Internal
+open Microsoft.FSharp.Metadata.Reader.Internal.AbstractIL.IL
+open Microsoft.FSharp.Metadata.Reader.Internal.Tast
+open Microsoft.FSharp.Metadata.Reader.Internal.Prelude
+
+let ffailwith fileName str = 
+    let msg = FSComp.SR.pickleErrorReadingWritingMetadata(fileName, str)
+    System.Diagnostics.Debug.Assert(false, msg)
+    failwith msg
+    
+
+// Fixup pickled data w.r.t. a set of CCU thunks indexed by name
+[<NoEquality; NoComparison>]
+type PickledDataWithReferences<'rawData> = 
+    { /// The data that uses a collection of CcuThunks internally
+      RawData: 'rawData; 
+      /// The assumptions that need to be fixed up
+      FixupThunks: list<CcuThunk> } 
+
+    member x.Fixup loader =
+        x.FixupThunks |> List.iter (fun reqd -> reqd.Fixup(loader reqd.AssemblyName)) ;
+        x.RawData
+
+    /// Like Fixup but loader may return None, in which case there is no fixup.
+    member x.OptionalFixup loader =
+        x.FixupThunks 
+        |> List.iter(fun reqd->
+            match loader reqd.AssemblyName with 
+            | Some(loaded) -> reqd.Fixup(loaded)
+            | None -> reqd.FixupOrphaned() );
+        x.RawData
+    
+
+//---------------------------------------------------------------------------
+// Basic pickle/unpickle state
+//---------------------------------------------------------------------------
+
+[<NoEquality; NoComparison>]
+type Table<'T> = 
+    { name: string;
+      tbl: Dictionary<'T, int>;
+      mutable rows: ResizeArray<'T>;
+      mutable count: int }
+
+let inline new_tbl n = 
+  { name = n;
+    tbl = new System.Collections.Generic.Dictionary<_,_>(1000, HashIdentity.Structural);
+    rows= new ResizeArray<_>(1000);
+    count=0; }
+
+let get_tbl tbl = Seq.toArray tbl.rows
+let tbl_size tbl = tbl.rows.Count
+
+let add_entry tbl x =
+    let n = tbl.count
+    tbl.count <- tbl.count + 1;
+    tbl.tbl.[x] <- n;
+    tbl.rows.Add(x);
+    n
+
+let find_or_add_entry tbl x =
+    let mutable res = Unchecked.defaultof<_>
+    let ok = tbl.tbl.TryGetValue(x,&res)
+    if ok then res else add_entry tbl x
+
+[<NoEquality; NoComparison>]
+type InputTable<'T> = 
+    { itbl_name: string;
+      itbl_rows: 'T array }
+
+let new_itbl n r = { itbl_name=n; itbl_rows=r }
+
+[<NoEquality; NoComparison>]
+type ObservableNodeInMap<'Data,'Node> = 
+    | ObservableNodeInMap of ('Node -> 'Data -> unit) * ('Node -> bool) * string * 'Node array 
+    member x.Get(n:int) = let (ObservableNodeInMap(_,_,_,arr)) = x in arr.[n]
+
+let new_osgn_inmap mk lnk isLinked nm n = ObservableNodeInMap (lnk,isLinked,nm, Array.init n (fun _i -> mk() ))
+
+[<NoEquality; NoComparison>]
+type ReaderState = 
+  { is: ByteStream; 
+    iilscope: ILScopeRef;
+    iccus: InputTable<CcuThunk>; 
+    itycons: ObservableNodeInMap<EntityData,Tycon>;  
+    itypars: ObservableNodeInMap<TyparData,Typar>; 
+    ivals: ObservableNodeInMap<ValData,Val>;
+    istrings: InputTable<string>;
+    ipubpaths: InputTable<PublicPath>; 
+    inlerefs: InputTable<NonLocalEntityRef>; 
+    isimpletyps: InputTable<typ>;
+    ifile: string;
+  }
+
+let ufailwith st str = ffailwith st.ifile str
+
+//---------------------------------------------------------------------------
+// Basic pickle/unpickle operations
+//---------------------------------------------------------------------------
+ 
+let u_byte st = Bytestream.read_byte st.is
+
+type unpickler<'T> = ReaderState -> 'T
+
+let u_bool st = let b = u_byte st in (b = 1) 
+
+
+
+let prim_u_int32 st = 
+    let b0 =  (u_byte st)
+    let b1 =  (u_byte st)
+    let b2 =  (u_byte st)
+    let b3 =  (u_byte st)
+    b0 ||| (b1 <<< 8) ||| (b2 <<< 16) ||| (b3 <<< 24)
+
+let u_int32 st = 
+    let b0 = u_byte st
+    if b0 <= 0x7F then b0 
+    else if b0 <= 0xbf then 
+        let b0 = b0 &&& 0x7F
+        let b1 = (u_byte st)
+        (b0 <<< 8) ||| b1
+    else  
+        assert(b0 = 0xFF);
+        prim_u_int32 st
+
+let u_bytes st = 
+    let n =  (u_int32 st)
+    Bytestream.read_bytes st.is n
+
+let u_prim_string st = 
+    let len =  (u_int32 st)
+    Bytestream.read_utf8_bytes_as_string st.is len
+
+let u_int st = u_int32 st
+let u_int8 st = sbyte (u_int32 st)
+let u_uint8 st = byte (u_byte st)
+let u_int16 st = int16 (u_int32 st)
+let u_uint16 st = uint16 (u_int32 st)
+let u_uint32 st = uint32 (u_int32 st)
+let u_int64 st = 
+    let b1 = (int64 (u_int32 st)) &&& 0xFFFFFFFFL
+    let b2 = int64 (u_int32 st)
+    b1 ||| (b2 <<< 32)
+
+let u_uint64 st = uint64 (u_int64 st)
+let float32_of_bits (x:int32) = System.BitConverter.ToSingle(System.BitConverter.GetBytes(x),0)
+let float_of_bits (x:int64) = System.BitConverter.Int64BitsToDouble(x)
+
+let u_single st = float32_of_bits (u_int32 st)
+let u_double st = float_of_bits (u_int64 st)
+
+let u_ieee64 st = float_of_bits (u_int64 st)
+
+let u_char st = char (int32 (u_uint16 st))
+let u_space n st = 
+    for i = 0 to n - 1 do 
+        u_byte st |> ignore
+        
+
+
+let inline  u_tup2 p1 p2 (st:ReaderState) = let a = p1 st in let b = p2 st in (a,b)
+let inline  u_tup3 p1 p2 p3 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in (a,b,c)
+let inline u_tup4 p1 p2 p3 p4 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in (a,b,c,d)
+let inline u_tup5 p1 p2 p3 p4 p5 (st:ReaderState) =
+  let a = p1 st 
+  let b = p2 st 
+  let c = p3 st 
+  let d = p4 st 
+  let e = p5 st 
+  (a,b,c,d,e)
+let inline u_tup6 p1 p2 p3 p4 p5 p6 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in (a,b,c,d,e,f)
+let inline u_tup7 p1 p2 p3 p4 p5 p6 p7 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in (a,b,c,d,e,f,x7)
+let inline u_tup8 p1 p2 p3 p4 p5 p6 p7 p8 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in  (a,b,c,d,e,f,x7,x8)
+let inline u_tup9 p1 p2 p3 p4 p5 p6 p7 p8 p9 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in let x9 = p9 st in (a,b,c,d,e,f,x7,x8,x9)
+let inline u_tup10 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in
+  let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in
+  let x9 = p9 st in let x10 = p10 st in (a,b,c,d,e,f,x7,x8,x9,x10)
+let inline u_tup11 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in
+  let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in
+  let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in (a,b,c,d,e,f,x7,x8,x9,x10,x11)
+let inline u_tup12 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in
+  let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in
+  let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in
+  (a,b,c,d,e,f,x7,x8,x9,x10,x11,x12)
+let inline u_tup13 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in
+  let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in
+  let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in
+  (a,b,c,d,e,f,x7,x8,x9,x10,x11,x12,x13)
+let inline u_tup14 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in
+  let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in
+  let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in
+  let x14 = p14 st in
+  (a,b,c,d,e,f,x7,x8,x9,x10,x11,x12,x13,x14)
+let inline u_tup15 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in
+  let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in
+  let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in
+  let x14 = p14 st in let x15 = p15 st in
+  (a,b,c,d,e,f,x7,x8,x9,x10,x11,x12,x13,x14,x15)
+
+let inline u_tup16 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in
+  let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in
+  let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in
+  let x14 = p14 st in let x15 = p15 st in let x16 = p16 st in
+  (a,b,c,d,e,f,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16)
+
+let inline u_tup17 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 (st:ReaderState) =
+  let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in
+  let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in
+  let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in
+  let x14 = p14 st in let x15 = p15 st in let x16 = p16 st in let x17 = p17 st in
+  (a,b,c,d,e,f,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17)
+
+
+//---------------------------------------------------------------------------
+// Pickle/unpickle operations for observably shared graph nodes
+//---------------------------------------------------------------------------
+
+// exception Nope
+
+// ctxt is for debugging
+
+let u_osgn_ref (ObservableNodeInMap(_lnk,_isLinked,nm,arr)) st = 
+    let n = u_int st
+    if n < 0 || n >= Array.length arr then ufailwith st ("u_osgn_ref: out of range, table = "+nm+", n = "+string n); 
+    arr.[n]
+
+let u_osgn_decl (ObservableNodeInMap(lnk,_isLinked,_nm,arr)) u st = 
+    let idx,data = u_tup2 u_int u st
+    //   dprintf "unpickling osgn %d in table %s\n" idx nm; 
+    let res = arr.[idx]
+    lnk res data;
+    res
+
+//---------------------------------------------------------------------------
+// Pickle/unpickle operations for interned nodes 
+//---------------------------------------------------------------------------
+
+let encode_uniq tbl key = find_or_add_entry tbl key
+let lookup_uniq st tbl n = 
+    let arr = tbl.itbl_rows
+    if n < 0 || n >= Array.length arr then ufailwith st ("lookup_uniq in table "+tbl.itbl_name+" out of range, n = "+string n+ ", sizeof(tab) = " + string (Array.length arr)); 
+    arr.[n]
+
+//---------------------------------------------------------------------------
+// Pickle/unpickle arrays and lists. For lists use the same binary format as arrays so we can switch
+// between internal representations relatively easily
+//------------------------------------------------------------------------- 
+ 
+let u_array f st =
+    let n = u_int st
+    let res = Array.zeroCreate n
+    for i = 0 to n-1 do
+        res.[i] <- f st
+    res
+
+let u_list f st = Array.toList (u_array f st)
+
+let u_FlatList f st = u_list f st // new FlatList<_> (u_array f st)
+
+let u_array_revi f st =
+    let n = u_int st
+    let res = Array.zeroCreate n
+    for i = 0 to n-1 do
+        res.[i] <- f st (n-1-i) 
+    res
+
+// Mark up default constraints with a priority in reverse order: last gets 0 etc. See comment on TTyparDefaultsToType 
+let u_list_revi f st = Array.toList (u_array_revi f st)
+ 
+ 
+let u_wrap (f: 'U -> 'T) (u : 'U unpickler) : 'T unpickler = (fun st -> f (u st))
+
+let u_option f st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> None
+    | 1 -> Some (f st)
+    | n -> ufailwith st ("u_option: found number " + string n)
+
+let u_lazy u st = 
+
+    // Read the number of bytes in the record
+    let len         = prim_u_int32 st // fixupPos1
+    // These are the ranges of OSGN nodes defined within the lazily read portion of the graph
+    let otyconsIdx1 = prim_u_int32 st // fixupPos2
+    let otyconsIdx2 = prim_u_int32 st // fixupPos3
+    let otyparsIdx1 = prim_u_int32 st // fixupPos4
+    let otyparsIdx2 = prim_u_int32 st // fixupPos5
+    let ovalsIdx1   = prim_u_int32 st // fixupPos6
+    let ovalsIdx2   = prim_u_int32 st // fixupPos7
+
+    ignore (len, otyconsIdx1, otyconsIdx2, otyparsIdx1, otyparsIdx2, ovalsIdx1, ovalsIdx2)
+    Lazy.CreateFromValue(u st)
+
+let u_hole () = 
+    let h = ref (None : 'T unpickler option)
+    (fun f -> h := Some f),(fun st -> match !h with Some f -> f st | None -> ufailwith st "u_hole: unfilled hole")
+
+//---------------------------------------------------------------------------
+// Pickle/unpickle F# interface data 
+//---------------------------------------------------------------------------
+
+// Strings 
+// A huge number of these occur in pickled F# data, so make them unique 
+let encode_string stringTab x = encode_uniq stringTab x
+let decode_string x = x
+let lookup_string st stringTab x = lookup_uniq st stringTab x
+let u_encoded_string = u_prim_string
+let u_string st   = lookup_uniq st st.istrings (u_int st)
+let u_strings = u_list u_string
+let u_ints = u_list u_int
+
+// CCU References 
+// A huge number of these occur in pickled F# data, so make them unique 
+let encode_ccuref ccuTab (x:CcuThunk) = encode_uniq ccuTab x.AssemblyName 
+let decode_ccuref x = x
+let lookup_ccuref st ccuTab x = lookup_uniq st ccuTab x
+let u_encoded_ccuref st = 
+    match u_byte st with 
+    | 0 -> u_prim_string st
+    | n -> ufailwith st ("u_encoded_ccuref: found number " + string n)
+let u_ccuref st   = lookup_uniq st st.iccus (u_int st)
+
+// References to public items in this module 
+// A huge number of these occur in pickled F# data, so make them unique 
+let decode_pubpath st stringTab a = PubPath(Array.map (lookup_string st stringTab) a)
+let lookup_pubpath st pubpathTab x = lookup_uniq st pubpathTab x
+let u_encoded_pubpath = u_array u_int
+let u_pubpath st = lookup_uniq st st.ipubpaths (u_int st)
+
+// References to other modules 
+// A huge number of these occur in pickled F# data, so make them unique 
+let decode_nleref st ccuTab stringTab (a,b) = mk_nleref (lookup_ccuref st ccuTab a) (Array.map (lookup_string st stringTab) b)
+let lookup_nleref st nlerefTab x = lookup_uniq st nlerefTab x
+let u_encoded_nleref = u_tup2 u_int (u_array u_int)
+let u_nleref st = lookup_uniq st st.inlerefs (u_int st)
+
+// Simple types are types like "int", represented as TType(Ref_nonlocal(...,"int"),[]). 
+// A huge number of these occur in pickled F# data, so make them unique. 
+let decode_simpletyp st _ccuTab _stringTab nlerefTab a = TType_app(ERef_nonlocal (lookup_nleref st nlerefTab a),[])
+let lookup_simpletyp st simpletypTab x = lookup_uniq st simpletypTab x
+let u_encoded_simpletyp st = u_int  st
+let u_simpletyp st = lookup_uniq st st.isimpletyps (u_int st)
+
+type sizes = int * int * int 
+    
+let unpickle_obj_with_dangling_ccus file ilscope u (phase2bytes:byte[]) =
+    let st2 = 
+       { is = Bytestream.of_bytes phase2bytes 0 phase2bytes.Length; 
+         iilscope= ilscope;
+         iccus= new_itbl "iccus (fake)" [| |]; 
+         itycons= new_osgn_inmap Tycon.NewUnlinked (fun osgn tg -> osgn.Link(tg)) (fun osgn -> osgn.IsLinked) "itycons" 0; 
+         itypars= new_osgn_inmap Typar.NewUnlinked (fun osgn tg -> osgn.Link(tg)) (fun osgn -> osgn.IsLinked) "itypars" 0; 
+         ivals  = new_osgn_inmap Val.NewUnlinked   (fun osgn tg -> osgn.Link(tg)) (fun osgn -> osgn.IsLinked) "ivals" 0;
+         istrings = new_itbl "istrings (fake)" [| |]; 
+         inlerefs = new_itbl "inlerefs (fake)" [| |]; 
+         ipubpaths = new_itbl "ipubpaths (fake)" [| |]; 
+         isimpletyps = new_itbl "isimpletyps (fake)" [| |]; 
+         ifile=file }
+    let phase2data = 
+        u_tup7
+           (u_array u_encoded_ccuref) 
+           (u_tup3 u_int u_int u_int) 
+           (u_array u_encoded_string) 
+           (u_array u_encoded_pubpath) 
+           (u_array u_encoded_nleref) 
+           (u_array u_encoded_simpletyp) 
+           u_bytes st2
+    let ccuNameTab,sizes,stringTab,pubpathTab,nlerefTab,simpletypTab,phase1bytes = phase2data
+    let ccuTab       = new_itbl "iccus"       (Array.map (CcuThunk.CreateDelayed) ccuNameTab)
+    let stringTab    = new_itbl "istrings"    (Array.map decode_string stringTab)
+    let pubpathTab   = new_itbl "ipubpaths"   (Array.map (decode_pubpath st2 stringTab) pubpathTab)
+    let nlerefTab    = new_itbl "inlerefs"    (Array.map (decode_nleref st2 ccuTab stringTab) nlerefTab)
+    let simpletypTab = new_itbl "isimpletyps" (Array.map (decode_simpletyp st2 ccuTab stringTab nlerefTab) simpletypTab)
+    let ((ntycons,ntypars,nvals) : sizes) = sizes
+    let data = 
+        let st1 = 
+           { is = Bytestream.of_bytes phase1bytes 0 phase1bytes.Length; 
+             iccus=  ccuTab; 
+             iilscope= ilscope;
+             itycons= new_osgn_inmap Tycon.NewUnlinked (fun osgn tg -> osgn.Link(tg)) (fun osgn -> osgn.IsLinked)  "itycons" ntycons; 
+             itypars= new_osgn_inmap Typar.NewUnlinked (fun osgn tg -> osgn.Link(tg)) (fun osgn -> osgn.IsLinked) "itypars" ntypars; 
+             ivals=   new_osgn_inmap Val.NewUnlinked   (fun osgn tg -> osgn.Link(tg)) (fun osgn -> osgn.IsLinked) "ivals" nvals;
+             istrings = stringTab;
+             ipubpaths = pubpathTab;
+             inlerefs = nlerefTab;
+             isimpletyps = simpletypTab;
+             ifile=file }
+        let res = u st1
+        res
+
+    {RawData=data; FixupThunks=Array.toList ccuTab.itbl_rows }
+    
+
+//=========================================================================
+// PART II *)
+//=========================================================================
+
+//---------------------------------------------------------------------------
+// Pickle/unpickle for Abstract IL data, up to IL instructions 
+//---------------------------------------------------------------------------
+
+let u_ILPublicKey st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_bytes st |> PublicKey 
+    | 1 -> u_bytes st |> PublicKeyToken 
+    | _ -> ufailwith st "u_ILPublicKey"
+
+let u_ILVersion st = u_tup4 u_uint16 u_uint16 u_uint16 u_uint16 st
+
+let u_ILModuleRef st = 
+    let (a,b,c) = u_tup3 u_string u_bool (u_option u_bytes) st
+    ILModuleRef.Create(a, b, c)
+
+let u_ILAssemblyRef st =
+    let tag = u_byte st
+    match tag with
+    | 0 -> 
+        let a,b,c,d,e,f = u_tup6 u_string (u_option u_bytes) (u_option u_ILPublicKey) u_bool (u_option u_ILVersion) (u_option u_string) st
+        ILAssemblyRef.Create(a, b, c, d, e, f)
+    | _ -> ufailwith st "u_ILAssemblyRef"
+
+// IL scope references are rescoped as they are unpickled.  This means 
+// the pickler accepts IL fragments containing ScopeRef_local and adjusts them 
+// to be absolute scope references.
+let u_ILScopeRef st = 
+    let res = 
+        let tag = u_byte st
+        match tag with
+        | 0 -> ScopeRef_local
+        | 1 -> u_ILModuleRef st |> ScopeRef_module 
+        | 2 -> u_ILAssemblyRef st |> ScopeRef_assembly 
+        | _ -> ufailwith st "u_ILScopeRef"  
+    let res = rescope_scoref st.iilscope res 
+    res
+
+let u_ILBasicCallConv st = 
+    match u_byte st with 
+    | 0 -> CC_default 
+    | 1 -> CC_cdecl  
+    | 2 -> CC_stdcall 
+    | 3 -> CC_thiscall 
+    | 4 -> CC_fastcall 
+    | 5 -> CC_vararg
+    | _ -> ufailwith st "u_ILBasicCallConv"
+
+let u_ILHasThis st = 
+    match u_byte st with 
+    | 0 -> CC_instance 
+    | 1 -> CC_instance_explicit 
+    | 2 -> CC_static 
+    | _ -> ufailwith st "u_ILHasThis"
+
+let u_ILCallConv st = let a,b = u_tup2 u_ILHasThis u_ILBasicCallConv st in Callconv(a,b)
+let u_ILTypeRef st = let a,b,c = u_tup3 u_ILScopeRef u_strings u_string st in ILTypeRef.Create(a, b, c) 
+let u_ILArrayShape = u_wrap (fun x -> ILArrayShape x) (u_list (u_tup2 (u_option u_int32) (u_option u_int32)))
+
+
+let rec u_ILType st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> Type_void
+    | 1 -> u_tup2 u_ILArrayShape u_ILType  st     |> Type_array 
+    | 2 -> u_ILTypeSpec st                        |> Type_value 
+    | 3 -> u_ILTypeSpec st                        |> Type_boxed 
+    | 4 -> u_ILType st                            |> Type_ptr 
+    | 5 -> u_ILType st                            |> Type_byref
+    | 6 -> u_ILCallSig st                         |> Type_fptr 
+    | 7 -> u_uint16 st                            |> Type_tyvar 
+    | 8 -> u_tup3 u_bool u_ILTypeRef u_ILType  st |> Type_modified 
+    | _ -> ufailwith st "u_ILType"
+and u_ILTypes st = u_list u_ILType st
+and u_ILCallSig = u_wrap (fun (a,b,c) -> {callsigCallconv=a; callsigArgs=b; callsigReturn=c}) (u_tup3 u_ILCallConv u_ILTypes u_ILType)
+and u_ILTypeSpec st = let a,b = u_tup2 u_ILTypeRef u_ILTypes st in ILTypeSpec.Create(a,b)
+
+
+
+let u_ILMethodRef st = 
+    let x1,x2,x3,x4,x5,x6 = u_tup6 u_ILTypeRef u_ILCallConv u_int u_string u_ILTypes u_ILType st
+    ILMethodRef.Create(x1,x2,x4,x3,x5,x6)
+
+let u_ILFieldRef st = 
+    let x1,x2,x3 = u_tup3 u_ILTypeRef u_string u_ILType st 
+    {frefParent=x1;frefName=x2;frefType=x3}
+
+let u_ILMethodSpec st = 
+    let x1,x2,x3 = u_tup3 u_ILMethodRef u_ILType u_ILTypes st 
+    ILMethodSpec.Create(x2,x1,x3)
+
+let u_ILFieldSpec st = 
+    let x1,x2 = u_tup2 u_ILFieldRef u_ILType st 
+    {fspecFieldRef=x1;fspecEnclosingType=x2}
+
+let u_ILBasicType st = 
+    match u_int st with  
+    | 0 -> DT_R 
+    | 1 -> DT_I1 
+    | 2 -> DT_U1 
+    | 3 -> DT_I2 
+    | 4 -> DT_U2 
+    | 5 -> DT_I4 
+    | 6 -> DT_U4 
+    | 7 -> DT_I8 
+    | 8 -> DT_U8 
+    | 9 -> DT_R4 
+    | 10 -> DT_R8 
+    | 11 -> DT_I 
+    | 12 -> DT_U 
+    | 13 -> DT_REF 
+    | _ -> ufailwith st "u_ILBasicType"
+    
+let u_ILVolatility st = (match u_int st with  0 -> Volatile | 1 -> Nonvolatile | _ -> ufailwith st "u_ILVolatility" )
+let u_ILReadonly   st = (match u_int st with  0 -> ReadonlyAddress | 1 -> NormalAddress | _ -> ufailwith st "u_ILReadonly" )
+  
+let itag_nop           = 0 
+let itag_ldarg         = 1
+let itag_ldnull        = 2 
+let itag_ilzero        = 3
+let itag_call          = 4 
+let itag_add           = 5
+let itag_sub           = 6 
+let itag_mul           = 7
+let itag_div           = 8 
+let itag_div_un        = 9 
+let itag_rem           = 10 
+let itag_rem_un        = 11 
+let itag_and           = 12 
+let itag_or            = 13 
+let itag_xor           = 14 
+let itag_shl           = 15 
+let itag_shr           = 16 
+let itag_shr_un        = 17 
+let itag_neg           = 18 
+let itag_not           = 19 
+let itag_conv          = 20
+let itag_conv_un       = 21 
+let itag_conv_ovf      = 22
+let itag_conv_ovf_un   = 23
+let itag_callvirt      = 24 
+let itag_ldobj         = 25 
+let itag_ldstr         = 26 
+let itag_castclass     = 27 
+let itag_isinst        = 28 
+let itag_unbox         = 29 
+let itag_throw         = 30 
+let itag_ldfld         = 31 
+let itag_ldflda        = 32 
+let itag_stfld         = 33 
+let itag_ldsfld        = 34 
+let itag_ldsflda       = 35 
+let itag_stsfld        = 36 
+let itag_stobj         = 37 
+let itag_box           = 38 
+let itag_newarr        = 39 
+let itag_ldlen         = 40 
+let itag_ldelema       = 41 
+let itag_ckfinite      = 42 
+let itag_ldtoken       = 43 
+let itag_add_ovf       = 44 
+let itag_add_ovf_un    = 45 
+let itag_mul_ovf       = 46 
+let itag_mul_ovf_un    = 47 
+let itag_sub_ovf       = 48 
+let itag_sub_ovf_un    = 49 
+let itag_ceq           = 50
+let itag_cgt           = 51
+let itag_cgt_un        = 52
+let itag_clt           = 53
+let itag_clt_un        = 54
+let itag_ldvirtftn     = 55 
+let itag_localloc      = 56 
+let itag_rethrow       = 57 
+let itag_sizeof        = 58
+let itag_ldelem_any    = 59
+let itag_stelem_any    = 60
+let itag_unbox_any     = 61
+let itag_ldlen_multi   = 62
+
+let simple_instrs = 
+    [ itag_add,        I_arith AI_add;
+      itag_add_ovf,    I_arith AI_add_ovf;
+      itag_add_ovf_un, I_arith AI_add_ovf_un;
+      itag_and,        I_arith AI_and;  
+      itag_div,        I_arith AI_div; 
+      itag_div_un,     I_arith AI_div_un;
+      itag_ceq,        I_arith AI_ceq;  
+      itag_cgt,        I_arith AI_cgt ;
+      itag_cgt_un,     I_arith AI_cgt_un;
+      itag_clt,        I_arith AI_clt;
+      itag_clt_un,     I_arith AI_clt_un;
+      itag_mul,        I_arith AI_mul  ;
+      itag_mul_ovf,    I_arith AI_mul_ovf;
+      itag_mul_ovf_un, I_arith AI_mul_ovf_un;
+      itag_rem,        I_arith AI_rem  ;
+      itag_rem_un,     I_arith AI_rem_un ; 
+      itag_shl,        I_arith AI_shl ; 
+      itag_shr,        I_arith AI_shr ; 
+      itag_shr_un,     I_arith AI_shr_un;
+      itag_sub,        I_arith AI_sub  ;
+      itag_sub_ovf,    I_arith AI_sub_ovf;
+      itag_sub_ovf_un, I_arith AI_sub_ovf_un; 
+      itag_xor,        I_arith AI_xor;  
+      itag_or,         I_arith AI_or;     
+      itag_neg,        I_arith AI_neg;     
+      itag_not,        I_arith AI_not;     
+      itag_ldnull,     I_arith AI_ldnull;   
+      itag_ckfinite,   I_arith AI_ckfinite;
+      itag_nop,        I_arith AI_nop;
+      itag_localloc,   I_localloc;
+      itag_throw,      I_throw;
+      itag_ldlen,      I_ldlen;
+      itag_rethrow,    I_rethrow;    ]
+
+let encode_table = Dictionary<_,_>(300, HashIdentity.Structural)
+let _ = List.iter (fun (icode,i) -> encode_table.[i] <- icode) simple_instrs
+let encode_instr si = encode_table.[si]
+let is_noarg_instr s = encode_table.ContainsKey s
+
+let decoders = 
+   [ itag_ldarg,       u_uint16                            >> I_ldarg;
+     itag_call,        u_ILMethodSpec                      >> (fun a -> I_call (Normalcall,a,None));
+     itag_callvirt,    u_ILMethodSpec                      >> (fun a -> I_callvirt (Normalcall,a,None));
+     itag_ldvirtftn,   u_ILMethodSpec                      >> I_ldvirtftn;
+     itag_conv,        u_ILBasicType                       >> (fun a -> I_arith (AI_conv a));
+     itag_conv_ovf,    u_ILBasicType                       >> (fun a -> I_arith (AI_conv_ovf a));
+     itag_conv_ovf_un, u_ILBasicType                       >> (fun a -> I_arith (AI_conv_ovf_un a));
+     itag_ldfld,       u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (b,c) -> I_ldfld (Aligned,b,c));
+     itag_ldflda,      u_ILFieldSpec                       >> I_ldflda;
+     itag_ldsfld,      u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (a,b) -> I_ldsfld (a,b));
+     itag_ldsflda,     u_ILFieldSpec                       >> I_ldsflda;
+     itag_stfld,       u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (b,c) -> I_stfld (Aligned,b,c));
+     itag_stsfld,      u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (a,b) -> I_stsfld (a,b));
+     itag_ldtoken,     u_ILType                            >> (fun a -> I_ldtoken (Token_type a));
+     itag_ldstr,       u_string                            >> I_ldstr;
+     itag_box,         u_ILType                            >> I_box;
+     itag_unbox,       u_ILType                            >> I_unbox;
+     itag_unbox_any,   u_ILType                            >> I_unbox_any;
+     itag_newarr,      u_tup2 u_ILArrayShape u_ILType      >> (fun (a,b) -> I_newarr(a,b));
+     itag_stelem_any,  u_tup2 u_ILArrayShape u_ILType      >> (fun (a,b) -> I_stelem_any(a,b));
+     itag_ldelem_any,  u_tup2 u_ILArrayShape u_ILType      >> (fun (a,b) -> I_ldelem_any(a,b));
+     itag_ldelema,     u_tup3 u_ILReadonly u_ILArrayShape u_ILType >> (fun (a,b,c) -> I_ldelema(a,b,c));
+     itag_castclass,   u_ILType                            >> I_castclass;
+     itag_isinst,      u_ILType                            >> I_isinst;
+     itag_ldobj,       u_ILType                            >> (fun c -> I_ldobj (Aligned,Nonvolatile,c));
+     itag_stobj,       u_ILType                            >> (fun c -> I_stobj (Aligned,Nonvolatile,c));
+     itag_sizeof,      u_ILType                            >> I_sizeof;
+     itag_ldlen_multi, u_tup2 u_int32 u_int32              >> (fun (a,b) -> EI_ldlen_multi (a,b));
+     itag_ilzero,      u_ILType                            >> EI_ilzero; ] 
+
+let decode_tab = 
+    let tab = Array.init 256 (fun n -> (fun st -> ufailwith st ("no decoder for instruction "+string n)))
+    let add_instr (icode,f) =  tab.[icode] <- f
+    List.iter add_instr decoders;
+    List.iter (fun (icode,mk) -> add_instr (icode,(fun _ -> mk))) simple_instrs;
+    tab
+
+
+let u_ILInstr st = 
+    let n = u_byte st
+    decode_tab.[n] st
+
+//---------------------------------------------------------------------------
+// Pickle/unpickle for F# types and module signatures
+//---------------------------------------------------------------------------
+
+let u_qlist uv = u_wrap QueueList.ofList (u_list uv)
+
+let u_pos st = let a = u_int st in let b = u_int st in mk_pos a b
+let u_range st = let a = u_string st in let b = u_pos st in let c = u_pos st in mk_range a b c
+
+// Most ranges (e.g. on optimization expressions) can be elided from stored data 
+let u_dummy_range : range unpickler = fun _st -> range0
+let u_ident st = let a = u_string st in let b = u_range st in ident(a,b)
+let u_xmldoc st = XmlDoc (u_array u_string st)
+
+let u_local_item_ref tab st = u_osgn_ref tab st
+
+let u_tcref st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_local_item_ref st.itycons  st |> ERef_local 
+    | 1 -> u_nleref                     st |> ERef_nonlocal 
+    | _ -> ufailwith st "u_item_ref"
+    
+let u_ucref st  = let a,b = u_tup2 u_tcref u_string st in UCRef(a,b)
+
+let u_rfref st = let a,b = u_tup2 u_tcref u_string st in RFRef(a,b)
+
+let u_tpref st = u_local_item_ref st.itypars st
+let fill_u_typ,u_typ = u_hole()
+let u_typs = (u_list u_typ)
+let fill_u_attribs,u_attribs = u_hole()
+
+let u_nonlocal_val_ref st = 
+    let a = u_tcref st 
+    let b1 = u_option u_string st
+    let b2 = u_bool st
+    let b3 = u_string st
+    let c = u_int st
+    let d = u_option u_typ st
+    {EnclosingEntity = a; ItemKey=ValLinkageFullKey({ MemberParentMangledName=b1; MemberIsOverride=b2;LogicalName=b3; TotalArgCount=c }, d) }
+  
+let u_vref st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_local_item_ref st.ivals st |> (fun x -> VRef_local x)
+    | 1 -> u_nonlocal_val_ref st |> (fun x -> VRef_nonlocal x)
+    | _ -> ufailwith st "u_item_ref"
+    
+let u_vrefs = u_list u_vref 
+
+
+
+let u_kind st =
+    match u_byte st with
+    | 0 -> KindType
+    | 1 -> KindMeasure
+    | _ -> ufailwith st "u_kind"
+
+let u_member_kind st = 
+    match u_byte st with 
+    | 0 -> MemberKindMember 
+    | 1 -> MemberKindPropertyGet  
+    | 2 -> MemberKindPropertySet 
+    | 3 -> MemberKindConstructor
+    | 4 -> MemberKindClassConstructor
+    | _ -> ufailwith st "u_member_kind"
+
+let u_MemberFlags st = 
+    let x2,_x3UnusedBoolInFormat,x4,x5,x6,x7 = u_tup6 u_bool u_bool u_bool u_bool u_bool u_member_kind st
+    { MemberIsInstance=x2;
+      MemberIsDispatchSlot=x4;
+      MemberIsOverrideOrExplicitImpl=x5;
+      MemberIsFinal=x6;
+      MemberKind=x7}
+
+// We have to store trait solutions since they can occur in optimization data
+let u_trait_sln st = 
+    let tag = u_byte st
+    match tag with 
+    | 0 -> 
+        let (a,b,c,d) = u_tup4 u_typ (u_option u_ILTypeRef) u_ILMethodRef u_typs st
+        ILMethSln(a,b,c,d) 
+    | 1 -> 
+        let (a,b,c) = u_tup3 u_typ u_vref u_typs st
+        FSMethSln(a,b,c)
+    | 2 -> 
+        BuiltInSln
+    | _ -> ufailwith st "u_trait_sln" 
+
+let u_trait st = 
+    let a,b,c,d,e,f = u_tup6 u_typs u_string u_MemberFlags u_typs (u_option u_typ) (u_option u_trait_sln) st
+    TTrait (a,b,c,d,e,ref f)
+
+let rec u_measure_expr st =
+    let tag = u_byte st
+    match tag with
+    | 0 -> let a = u_tcref st in MeasureCon a
+    | 1 -> let a = u_measure_expr st in MeasureInv a
+    | 2 -> let a,b = u_tup2 u_measure_expr u_measure_expr st in MeasureProd (a,b)
+    | 3 -> let a = u_tpref st in MeasureVar a
+    | 4 -> MeasureOne
+    | _ -> ufailwith st "u_measure_expr"
+
+let u_typar_constraint st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_typ  st             |> (fun a     _ -> TTyparCoercesToType (a,range0) )
+    | 1 -> u_trait st            |> (fun a     _ -> TTyparMayResolveMemberConstraint(a,range0))
+    | 2 -> u_typ st              |> (fun a  ridx -> TTyparDefaultsToType(ridx,a,range0))
+    | 3 ->                          (fun       _ -> TTyparSupportsNull range0)
+    | 4 ->                          (fun       _ -> TTyparIsNotNullableValueType range0)
+    | 5 ->                          (fun       _ -> TTyparIsReferenceType range0)
+    | 6 ->                          (fun       _ -> TTyparRequiresDefaultConstructor range0)
+    | 7 -> u_typs st             |> (fun a     _ -> TTyparSimpleChoice(a,range0))
+    | 8 -> u_typ  st             |> (fun a     _ -> TTyparIsEnum(a,range0))
+    | 9 -> u_tup2 u_typ u_typ st |> (fun (a,b) _ -> TTyparIsDelegate(a,b,range0))
+    | 10 ->                         (fun       _ -> TTyparSupportsComparison range0)
+    | 11 ->                         (fun       _ -> TTyparSupportsEquality range0)
+    | 12 ->                         (fun       _ -> TTyparIsUnmanaged range0)
+    | _ -> ufailwith st "u_typar_constraint" 
+
+
+let u_typar_constraints = (u_list_revi u_typar_constraint)
+
+
+let u_typar_spec_data st = 
+    let a,c,d,e,g = u_tup5 u_ident u_attribs u_int64 u_typar_constraints u_xmldoc st
+    { typar_id=a; 
+      typar_il_name=None;
+      typar_stamp=newStamp();
+      typar_attribs=c;
+      typar_flags=TyparFlags(int32 d);
+      typar_constraints=e;
+      typar_solution=None;
+      typar_xmldoc=g }
+
+let u_typar_spec st = 
+    u_osgn_decl st.itypars u_typar_spec_data st 
+
+let u_typar_specs = (u_list u_typar_spec)
+
+
+let _ = fill_u_typ (fun st ->
+    let tag = u_byte st
+    match tag with
+    | 0 -> let l = u_typs st                               in TType_tuple l
+    | 1 -> u_simpletyp st 
+    | 2 -> let tc = u_tcref st in let tinst = u_typs st    in TType_app (tc,tinst)
+    | 3 -> let d = u_typ st    in let r = u_typ st         in TType_fun (d,r)
+    | 4 -> let r = u_tpref st                              in r.AsType
+    | 5 -> let tps = u_typar_specs st in let r = u_typ st  in TType_forall (tps,r)
+    | 6 -> let unt = u_measure_expr st                     in TType_measure unt
+    | 7 -> let uc = u_ucref st in let tinst = u_typs st    in TType_ucase (uc,tinst)
+    | _ -> ufailwith st "u_typ")
+  
+
+let fill_u_binds,u_binds = u_hole()
+let fill_u_targets,u_targets = u_hole()
+let fill_u_Exprs,u_Exprs = u_hole()
+let fill_u_FlatExprs,u_FlatExprs = u_hole()
+let fill_u_constraints,u_constraints = u_hole()
+let fill_u_Vals,u_Vals = u_hole()
+let fill_u_FlatVals,u_FlatVals = u_hole()
+
+let u_TopArgInfo st = 
+    let a = u_attribs st 
+    let b = u_option u_ident st 
+    match a,b with 
+    | [],None -> TopValInfo.unnamedTopArg1 
+    | _ -> { Attribs = a; Name = b } 
+
+let u_TopTyparInfo st = 
+    let a = u_ident st
+    let b = u_kind st 
+    TopTyparInfo(a,b)
+
+let u_ValTopReprInfo st = 
+    let a = u_list u_TopTyparInfo st
+    let b = u_list (u_list u_TopArgInfo) st
+    let c = u_TopArgInfo st
+    TopValInfo (a,b,c)
+
+let u_ranges st = u_option (u_tup2 u_range u_range) st
+
+let u_istype st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> FSharpModuleWithSuffix 
+    | 1 -> FSharpModule  
+    | 2 -> Namespace 
+    | _ -> ufailwith st "u_istype"
+
+let u_cpath  st = let a,b = u_tup2 u_ILScopeRef (u_list (u_tup2 u_string u_istype)) st in (CompPath(a,b))
+
+
+let rec dummy x = x
+and u_tycon_repr st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_rfield_table            st |> TRecdRepr 
+    | 1 -> u_list u_unioncase_spec   st |> MakeUnionRepr
+    | 2 -> u_ILType                  st |> TAsmRepr
+    | 3 -> u_tycon_objmodel_data     st |> TFsObjModelRepr
+    | 4 -> u_typ                     st |> TMeasureableRepr 
+    | _ -> ufailwith st "u_tycon_repr"
+  
+and u_tycon_objmodel_data st = 
+    let x1,x2,x3 = u_tup3 u_tycon_objmodel_kind u_vrefs u_rfield_table st
+    {fsobjmodel_kind=x1; fsobjmodel_vslots=x2; fsobjmodel_rfields=x3 }
+  
+and u_unioncase_spec st = 
+    let a,b,c,d,e,f,i = u_tup7 u_rfield_table u_typ u_string u_ident u_attribs u_string u_access st
+    {ucase_rfields=a; ucase_rty=b; ucase_il_name=c; ucase_id=d; ucase_attribs=e;ucase_xmldoc=emptyXmlDoc;ucase_xmldocsig=f;ucase_access=i }
+    
+and u_exnc_spec_data st = u_entity_spec_data st 
+
+and u_exnc_repr st =
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_tcref        st |> TExnAbbrevRepr
+    | 1 -> u_ILTypeRef    st |> TExnAsmRepr
+    | 2 -> u_rfield_table st |> TExnFresh
+    | 3 -> TExnNone
+    | _ -> ufailwith st "u_exnc_repr"
+  
+and u_exnc_spec st = u_tycon_spec st
+
+and u_access st = 
+    match u_list u_cpath st with 
+    | [] -> taccessPublic // save unnecessary allocations 
+    | res -> TAccess res
+
+and u_recdfield_spec st = 
+    let a,b,c1,c2,c2b,c3,d,e1,e2,f,g = 
+        u_tup11 
+            u_bool 
+            u_bool 
+            u_typ 
+            u_bool 
+            u_bool 
+            (u_option u_const) 
+            u_ident 
+            u_attribs 
+            u_attribs 
+            u_string
+            u_access 
+            st
+    { rfield_mutable=a;  
+      rfield_volatile=b;  
+      rfield_type=c1; 
+      rfield_static=c2; 
+      rfield_secret=c2b; 
+      rfield_const=c3; 
+      rfield_id=d; 
+      rfield_pattribs=e1;
+      rfield_fattribs=e2;
+      rfield_xmldoc=emptyXmlDoc;
+      rfield_xmldocsig=f; 
+      rfield_access=g }
+
+and u_rfield_table st = MakeRecdFieldsTable (u_list u_recdfield_spec st)
+
+and u_entity_spec_data st = 
+    let x1,x2a,x2b,x2c,x3,(x4a,x4b),x6,x7,x8,x9,x10,x10b,x11,x12,x13,x14,_space = 
+       u_tup17
+          u_typar_specs
+          u_string
+          (u_option u_string)
+          u_range
+          (u_option u_pubpath)
+          (u_tup2 u_access u_access)
+          u_attribs
+          (u_option u_tycon_repr)
+          (u_option u_typ) 
+          u_tcaug 
+          u_string 
+          u_kind
+          u_int64
+          (u_option u_cpath )
+          (u_lazy u_modul_typ) 
+          u_exnc_repr 
+          (u_space 1)
+          st
+    { entity_typars=LazyWithContext<_,_>.NotLazy x1;
+      entity_stamp=newStamp();
+      entity_logical_name=x2a;
+      entity_compiled_name=x2b;
+      entity_range=x2c;
+      entity_pubpath=x3;
+      entity_accessiblity=x4a;
+      entity_tycon_repr_accessibility=x4b;
+      entity_attribs=x6;
+      entity_tycon_repr=x7;
+      entity_tycon_abbrev=x8;
+      entity_tycon_tcaug=x9;
+      entity_xmldoc=emptyXmlDoc;
+      entity_xmldocsig=x10;
+      entity_kind=x10b;
+      entity_flags=EntityFlags(x11);
+      entity_cpath=x12;
+      entity_modul_contents= x13;
+      entity_exn_info=x14;
+      entity_il_repr_cache=newCache();  } 
+
+and u_tcaug st = 
+    let a1,a2,a3,b2,c,d,e,g,_space = 
+      u_tup9
+        (u_option (u_tup2 u_vref u_vref))
+        (u_option u_vref)
+        (u_option (u_tup3 u_vref u_vref u_vref))
+        (u_option (u_tup2 u_vref u_vref))
+        (u_list (u_tup2 u_string u_vref))
+        (u_list (u_tup3 u_typ u_bool u_dummy_range)) 
+        (u_option u_typ)
+        u_bool 
+        (u_space 1)
+        st 
+    {tcaug_compare=a1; 
+     tcaug_compare_withc=a2; 
+     tcaug_hash_and_equals_withc=a3; 
+     tcaug_equals=b2; 
+     // only used for code generation and checking - hence don't care about the values when reading back in
+     tcaug_hasObjectGetHashCode=false; 
+     tcaug_adhoc_list= new ResizeArray<_> (List.map snd c); 
+     tcaug_adhoc=NameMultiMap.ofList c; 
+     tcaug_interfaces=d;
+     tcaug_super=e;
+     // pickled type definitions are always closed (i.e. no more intrinsic members allowed)
+     tcaug_closed=true; 
+     tcaug_abstract=g}
+ 
+and u_tycon_spec st = 
+    u_osgn_decl st.itycons u_entity_spec_data st 
+
+and u_parentref st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> ParentNone
+    | 1 -> u_tcref st |> Parent 
+    | _ -> ufailwith st "u_attribkind" 
+
+and u_attribkind st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_ILMethodRef st |> ILAttrib 
+    | 1 -> u_vref        st |> FSAttrib 
+    | _ -> ufailwith st "u_attribkind" 
+
+and u_attrib st : Attrib = 
+    let a,b,c,d,e,f = u_tup6 u_tcref u_attribkind (u_list u_attrib_expr) (u_list u_attrib_arg) u_bool u_dummy_range st
+    Attrib(a,b,c,d,e,f)
+
+and u_attrib_expr st = 
+    let a,b = u_tup2 u_expr u_expr st 
+    AttribExpr(a,b)
+
+and u_attrib_arg st  = 
+    let a,b,c,d = u_tup4 u_string u_typ u_bool u_attrib_expr st 
+    AttribNamedArg(a,b,c,d)
+
+and u_member_info st = 
+    let x2,x3,x4,x5 = u_tup4 u_tcref u_MemberFlags (u_list u_slotsig) u_bool st
+    { ApparentParent=x2;
+      MemberFlags=x3;
+      ImplementedSlotSigs=x4;
+      IsImplemented=x5  }
+
+and u_tycon_objmodel_kind st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> TTyconClass 
+    | 1 -> TTyconInterface  
+    | 2 -> TTyconStruct 
+    | 3 -> u_slotsig st |> TTyconDelegate
+    | 4 -> TTyconEnum 
+    | _ -> ufailwith st "u_tycon_objmodel_kind"
+
+and u_mustinline st = 
+    match u_byte st with 
+    | 0 -> PseudoValue 
+    | 1 -> AlwaysInline  
+    | 2 -> OptionalInline 
+    | 3 -> NeverInline 
+    | _ -> ufailwith st "u_mustinline"
+
+and u_basethis st = 
+    match u_byte st with 
+    | 0 -> BaseVal 
+    | 1 -> CtorThisVal  
+    | 2 -> NormalVal 
+    | 3 -> MemberThisVal
+    | _ -> ufailwith st "u_basethis"
+
+and u_vrefFlags st = 
+    match u_byte st with 
+    | 0 -> NormalValUse 
+    | 1 -> CtorValUsedAsSuperInit
+    | 2 -> CtorValUsedAsSelfInit
+    | 3 -> PossibleConstrainedCall (u_typ st)
+    | 4 -> VSlotDirectCall
+    | _ -> ufailwith st "u_vrefFlags"
+
+and u_ValData st =
+    let x1,x1z,x1a,x2,x4,x8,x9,x10,x12,x13,x13b,x14,_space = 
+      u_tup13
+        u_string
+        (u_option u_string)
+        u_ranges
+        u_typ 
+        u_int64
+        (u_option u_member_info) 
+        u_attribs 
+        (u_option u_ValTopReprInfo)
+        u_string
+        u_access
+        u_parentref
+        (u_option u_const) 
+        (u_space 1) st
+    { val_logical_name=x1;
+      val_compiled_name=x1z;
+      val_range=(match x1a with None -> range0 | Some(a,_) -> a);
+      val_defn_range=(match x1a with None -> range0 | Some(_,b) -> b);
+      val_type=x2;
+      val_stamp=newStamp();
+      val_flags=ValFlags(x4);
+      val_defn = None;
+      val_member_info=x8;
+      val_attribs=x9;
+      val_top_repr_info=x10;
+      val_xmldoc=emptyXmlDoc;
+      val_xmldocsig=x12;
+      val_access=x13;
+      val_actual_parent=x13b;
+      val_const=x14;
+    }
+
+and u_Val st = u_osgn_decl st.ivals u_ValData st 
+
+
+and u_modul_typ st = 
+    let x1,x3,x5 = 
+        u_tup3
+          u_istype
+          (u_qlist u_Val)
+          (u_qlist u_tycon_spec) st
+    ModuleOrNamespaceType(x1,x3,x5)
+
+
+//---------------------------------------------------------------------------
+// Pickle/unpickle for F# expressions (for optimization data)
+//---------------------------------------------------------------------------
+
+and u_const st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_bool st           |> TConst_bool  
+    | 1 -> u_int8 st           |> TConst_sbyte 
+    | 2 -> u_uint8 st          |> TConst_byte 
+    | 3 -> u_int16 st          |> TConst_int16 
+    | 4 -> u_uint16 st         |> TConst_uint16 
+    | 5 -> u_int32 st          |> TConst_int32 
+    | 6 -> u_uint32 st         |> TConst_uint32 
+    | 7 -> u_int64 st          |> TConst_int64
+    | 8 -> u_uint64 st         |> TConst_uint64
+    | 9 -> u_int64 st          |> TConst_nativeint
+    | 10 -> u_uint64 st        |> TConst_unativeint
+    | 11 -> u_single st        |> TConst_float32
+    | 12 -> u_int64 st         |> float_of_bits |> TConst_float
+    | 13 -> u_char st          |> TConst_char 
+    | 14 -> u_string st        |> TConst_string
+    | 15 -> TConst_unit
+    | 16 -> TConst_zero
+    | 17 -> u_array u_int32 st |> (fun bits -> TConst_decimal (new System.Decimal(bits)))
+    | _ -> ufailwith st "u_const" 
+
+
+and u_dtree st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_tup4 u_expr (u_list u_dtree_case) (u_option u_dtree) u_dummy_range st |> TDSwitch 
+    | 1 -> u_tup2 u_FlatExprs u_int                                             st |> TDSuccess
+    | 2 -> u_tup2 u_bind u_dtree                                                st |> TDBind
+    | _ -> ufailwith st "u_dtree" 
+
+and u_dtree_case st = let a,b = u_tup2 u_dtree_discrim u_dtree st in (TCase(a,b)) 
+
+and u_dtree_discrim st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_tup2 u_ucref u_typs st |> TTest_unionconstr 
+    | 1 -> u_const st               |> TTest_const 
+    | 2 ->                             TTest_isnull 
+    | 3 -> u_tup2 u_typ u_typ st    |> TTest_isinst
+    | 4 -> u_tup2 u_int u_typ st    |> TTest_array_length
+    | _ -> ufailwith st "u_dtree_discrim" 
+
+and u_target st = let a,b = u_tup2 u_FlatVals u_expr st in (TTarget(a,b,SuppressSequencePointAtTarget)) 
+
+and u_bind st = let a = u_Val st in let b = u_expr st in TBind(a,b,NoSequencePointAtStickyBinding)
+
+and u_lval_op_kind st =
+    match u_byte st with 
+    | 0 -> LGetAddr 
+    | 1 -> LByrefGet 
+    | 2 -> LSet 
+    | 3 -> LByrefSet 
+    | _ -> ufailwith st "uval_op_kind"
+
+  
+and u_op st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> let a = u_ucref st
+           TOp_ucase a
+    | 1 -> let a = u_tcref st
+           TOp_exnconstr a
+    | 2 -> TOp_tuple 
+    | 3 -> let b = u_tcref st
+           TOp_recd (RecdExpr,b) 
+    | 4 -> let a = u_rfref st
+           TOp_rfield_set a 
+    | 5 -> let a = u_rfref st
+           TOp_rfield_get a 
+    | 6 -> let a = u_tcref st
+           TOp_ucase_tag_get a 
+    | 7 -> let a = u_ucref st
+           let b = u_int st
+           TOp_ucase_field_get (a,b) 
+    | 8 -> let a = u_ucref st
+           let b = u_int st
+           TOp_ucase_field_set (a,b) 
+    | 9 -> let a = u_tcref st
+           let b = u_int st
+           TOp_exnconstr_field_get (a,b) 
+    | 10 -> let a = u_tcref st
+            let b = u_int st
+            TOp_exnconstr_field_set (a,b) 
+    | 11 -> let a = u_int st
+            TOp_tuple_field_get a 
+    | 12 -> let a = (u_list u_ILInstr) st
+            let b = u_typs st
+            TOp_asm (a,b) 
+    | 13 -> TOp_get_ref_lval 
+    | 14 -> let a = u_ucref st
+            TOp_ucase_proof a 
+    | 15 -> TOp_coerce
+    | 16 -> let a = u_trait st
+            TOp_trait_call a
+    | 17 -> let a = u_lval_op_kind st
+            let b = u_vref st
+            TOp_lval_op (a,b) 
+    | 18 -> let (a1,a2,a3,a4,a5,a7,a8,a9) = (u_tup8 u_bool u_bool u_bool u_bool u_vrefFlags u_bool u_bool  u_ILMethodRef) st
+            let b = u_typs st
+            let c = u_typs st
+            let d = u_typs st
+            TOp_ilcall (a1,a2,a3,a4,a5,a7,a8,a9,b,c,d) 
+    | 19 -> TOp_array
+    | 20 -> TOp_while (NoSequencePointAtWhileLoop, NoSpecialWhileLoopMarker)
+    | 21 -> let dir = match u_int st with 0 -> FSharpForLoopUp | 1 -> CSharpForLoopUp | 2 -> FSharpForLoopDown | _ -> failwith "unknown for loop"
+            TOp_for (NoSequencePointAtForLoop, dir)
+    | 22 -> TOp_bytes (u_bytes st)
+    | 23 -> TOp_try_catch(NoSequencePointAtTry,NoSequencePointAtWith)
+    | 24 -> TOp_try_finally(NoSequencePointAtTry,NoSequencePointAtFinally)
+    | 25 -> let a = u_rfref st
+            TOp_field_get_addr a
+    | 26 -> TOp_uint16s (u_array u_uint16 st)
+    | 27 -> TOp_reraise
+    | _ -> ufailwith st "u_op" 
+
+and u_expr st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> let a = u_const st
+           let b = u_dummy_range st
+           let c = u_typ st
+           TExpr_const (a,b,c) 
+    | 1 -> let a = u_vref st
+           let b = u_vrefFlags st
+           let c = u_dummy_range st
+           TExpr_val (a,b,c) 
+    | 2 -> let a = u_op st
+           let b = u_typs st
+           let c = u_Exprs st
+           let d = u_dummy_range st
+           TExpr_op (a,b,c,d)
+    | 3 -> let a = u_expr st
+           let b = u_expr st
+           let c = u_int st
+           let d = u_dummy_range  st
+           TExpr_seq (a,b,(match c with 0 -> NormalSeq | 1 -> ThenDoSeq | _ -> ufailwith st "specialSeqFlag"),SuppressSequencePointOnExprOfSequential,d) 
+    | 4 -> let a0 = u_option u_Val st
+           let b0 = u_option u_Val st
+           let b1 = u_Vals st
+           let c = u_expr st
+           let d = u_dummy_range st
+           let e = u_typ st
+           TExpr_lambda (newUnique(),a0,b0,b1,c,d,e,SkipFreeVarsCache()) 
+    | 5  -> let b = u_typar_specs st
+            let c = u_expr st
+            let d = u_dummy_range st
+            let e = u_typ st
+            TExpr_tlambda (newUnique(),b,c,d,e,SkipFreeVarsCache()) 
+    | 6 ->  let a1 = u_expr st
+            let a2 = u_typ st
+            let b = u_typs st
+            let c = u_Exprs st
+            let d = u_dummy_range st
+            TExpr_app (a1,a2,b,c,d) 
+    | 7 ->  let a = u_binds st
+            let b = u_expr st
+            let c = u_dummy_range st
+            TExpr_letrec (a,b,c,NewFreeVarsCache()) 
+    | 8 ->  let a = u_bind st
+            let b = u_expr st
+            let c = u_dummy_range st
+            TExpr_let (a,b,c,NewFreeVarsCache()) 
+    | 9 ->  let a = u_dummy_range st
+            let b = u_dtree st
+            let c = u_targets st
+            let d = u_dummy_range st
+            let e = u_typ st
+            TExpr_match (NoSequencePointAtStickyBinding,a,b,c,d,e,SkipFreeVarsCache()) 
+    | 10 -> let b = u_typ st
+            let c = (u_option u_Val) st
+            let d = u_expr st
+            let e = u_methods st
+            let f = u_intfs st
+            let g = u_dummy_range st
+            TExpr_obj (newUnique(),b,c,d,e,f,g,SkipFreeVarsCache())
+    | 11 -> let a = u_constraints st
+            let b = u_expr st
+            let c = u_expr st
+            let d = u_dummy_range st
+            TExpr_static_optimization (a,b,c,d)
+    | 12 -> let a = u_typar_specs st
+            let b = u_expr st
+            let c = u_dummy_range st
+            TExpr_tchoose (a,b,c)
+    | 13 -> let b = u_expr st
+            let c = u_dummy_range st
+            let d = u_typ st
+            TExpr_quote (b,ref None,c,d)
+    | _ -> ufailwith st "u_expr" 
+
+and u_static_optimization_constraint st = 
+    let tag = u_byte st
+    match tag with
+    | 0 -> u_tup2 u_typ u_typ st |> TTyconEqualsTycon
+    | 1 -> u_typ              st |> TTyconIsStruct
+    | _ -> ufailwith st "u_static_optimization_constraint" 
+
+and u_slotparam st = 
+    let a,b,c,d,e,f = u_tup6 (u_option u_string) u_typ u_bool u_bool u_bool u_attribs st 
+    TSlotParam(a,b,c,d,e,f)
+
+and u_slotsig st = 
+    let a,b,c,d,e,f = u_tup6 u_string u_typ u_typar_specs u_typar_specs (u_list (u_list u_slotparam)) (u_option u_typ) st
+    TSlotSig(a,b,c,d,e,f)
+
+and u_method st = 
+    let a,b,c,d,e,f = u_tup6 u_slotsig u_attribs u_typar_specs (u_list u_Vals) u_expr u_dummy_range st 
+    TObjExprMethod(a,b,c,d,e,f)
+
+and u_methods st = u_list u_method st
+
+and u_intf st = u_tup2 u_typ u_methods st
+
+and u_intfs st = u_list u_intf st
+
+let _ = fill_u_binds (u_FlatList u_bind)
+let _ = fill_u_targets (u_array u_target)
+let _ = fill_u_constraints (u_list u_static_optimization_constraint)
+let _ = fill_u_Exprs (u_list u_expr)
+let _ = fill_u_FlatExprs (u_FlatList u_expr)
+let _ = fill_u_attribs (u_list u_attrib)
+let _ = fill_u_Vals (u_list u_Val)
+let _ = fill_u_FlatVals (u_FlatList u_Val)
+
+//---------------------------------------------------------------------------
+// Pickle/unpickle F# interface data 
+//---------------------------------------------------------------------------
+
+let unpickle_modul_spec st = u_tycon_spec st 
+  
+let unpickleModuleInfo st = 
+    let a,b,c,_space = u_tup4 unpickle_modul_spec u_string u_bool (u_space 3) st 
+    { mspec=a; compileTimeWorkingDir=b; usesQuotations=c }
diff --git a/src/FSharp.PowerPack.Metadata/tast.fs b/src/FSharp.PowerPack.Metadata/tast.fs
new file mode 100755
index 0000000..4a73a12
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/tast.fs
@@ -0,0 +1,2694 @@
+// (c) Microsoft Corporation. All rights reserved
+  
+module internal Microsoft.FSharp.Metadata.Reader.Internal.Tast
+
+open System.Collections.Generic 
+open Microsoft.FSharp.Metadata.Reader.Internal.AbstractIL.IL
+open Microsoft.FSharp.Metadata.Reader.Internal.PrettyNaming
+open Microsoft.FSharp.Metadata.Reader.Internal.Prelude
+
+/// Unique name generator for stamps attached to lambdas and object expressions
+type uniq = int64
+let newUnique = let i = ref 0L in fun () -> i := !i + 1L; !i
+type stamp = int64
+
+/// Unique name generator for stamps attached to to val_specs, tycon_specs etc.
+let newStamp = let i = ref 0L in fun () -> i := !i + 1L; !i
+
+type StampMap<'T> = Map<stamp,'T>
+
+//-------------------------------------------------------------------------
+// Flags
+
+type ValInlineInfo =
+    /// Indicates the value must always be inlined 
+    | PseudoValue 
+    /// Indictes the value is inlined but the code for the function still exists, e.g. to satisfy interfaces on objects, but that it is also always inlined 
+    | AlwaysInline 
+    | OptionalInline
+    | NeverInline
+
+let mustinline = function PseudoValue | AlwaysInline -> true | OptionalInline | NeverInline -> false
+
+type ValRecursiveScopeInfo =
+    /// Set while the value is within its recursive scope. The flag indicates if the value has been eagerly generalized and accepts generic-recursive calls 
+    | ValInRecScope of bool
+    /// The normal value for this flag when the value is not within its recursive scope 
+    | ValNotInRecScope
+
+type ValMutability   = 
+    | Immutable 
+    | Mutable
+
+type TyparDynamicReq = 
+    /// Indicates the type parameter is not needed at runtime and may be eliminated
+    | NoDynamicReq 
+    /// Indicates the type parameter is needed at runtime and may not be eliminated
+    | DynamicReq
+
+type ValBaseOrThisInfo = 
+    /// Indicates a ref-cell holding 'this' or the implicit 'this' used throughout an 
+    /// implicit constructor to access and set values
+    | CtorThisVal 
+    /// Indicates the value called 'base' available for calling base class members
+    | BaseVal 
+    /// Indicates a normal value
+    | NormalVal 
+    /// Indicates the 'this' value specified in a memberm e.g. 'x' in 'member x.M() = 1'
+    | MemberThisVal
+
+//---------------------------------------------------------------------------
+// Flags on values
+//---------------------------------------------------------------------------
+
+[<Struct>]
+type ValFlags(flags:int64) = 
+
+    new (recValInfo, baseOrThis, isCompGen, inlineInfo, isMutable, isModuleOrMemberBinding, isExtensionMember, isIncrClassSpecialMember, isTyFunc, allowTypeInst) =
+        let flags = 
+                     (match baseOrThis with
+                                        | BaseVal ->           0b000000000000000000L
+                                        | CtorThisVal ->       0b000000000000000010L
+                                        | NormalVal ->         0b000000000000000100L
+                                        | MemberThisVal ->     0b000000000000000110L) |||
+                     (if isCompGen then                        0b000000000000001000L 
+                      else                                     0b000000000000000000L) |||
+                     (match inlineInfo with
+                                        | PseudoValue ->       0b000000000000000000L
+                                        | AlwaysInline ->      0b000000000000010000L
+                                        | OptionalInline ->    0b000000000000100000L
+                                        | NeverInline ->       0b000000000000110000L) |||
+                     (match isMutable with
+                                        | Immutable ->         0b000000000000000000L
+                                        | Mutable   ->         0b000000000001000000L) |||
+
+                     (match isModuleOrMemberBinding with
+                                        | false     ->         0b000000000000000000L
+                                        | true      ->         0b000000000010000000L) |||
+                     (match isExtensionMember with
+                                        | false     ->         0b000000000000000000L
+                                        | true      ->         0b000000000100000000L) |||
+                     (match isIncrClassSpecialMember with
+                                        | false     ->         0b000000000000000000L
+                                        | true      ->         0b000000001000000000L) |||
+                     (match isTyFunc with
+                                        | false     ->         0b000000000000000000L
+                                        | true      ->         0b000000010000000000L) |||
+
+                     (match recValInfo with
+                                     | ValNotInRecScope     -> 0b000000000000000000L
+                                     | ValInRecScope(true)  -> 0b000000100000000000L
+                                     | ValInRecScope(false) -> 0b000001000000000000L) |||
+
+                     (match allowTypeInst with
+                                        | false     ->         0b000000000000000000L
+                                        | true      ->         0b000100000000000000L)
+
+        ValFlags(flags)
+
+    member x.BaseOrThisInfo = 
+                                  match (flags       &&&       0b000000000000000110L) with 
+                                                             | 0b000000000000000000L -> BaseVal
+                                                             | 0b000000000000000010L -> CtorThisVal
+                                                             | 0b000000000000000100L -> NormalVal
+                                                             | 0b000000000000000110L -> MemberThisVal
+                                                             | _          -> failwith "unreachable"
+
+
+
+    member x.IsCompilerGenerated =      (flags       &&&       0b000000000000001000L) <> 0x0L
+
+    member x.SetIsCompilerGenerated(isCompGen) = 
+            let flags =                 (flags       &&&    ~~~0b000000000000001000L) |||
+                                        (match isCompGen with
+                                          | false           -> 0b000000000000000000L
+                                          | true            -> 0b000000000000001000L)
+            ValFlags(flags)
+
+    member x.InlineInfo = 
+                                  match (flags       &&&       0b000000000000110000L) with 
+                                                             | 0b000000000000000000L -> PseudoValue
+                                                             | 0b000000000000010000L -> AlwaysInline
+                                                             | 0b000000000000100000L -> OptionalInline
+                                                             | 0b000000000000110000L -> NeverInline
+                                                             | _          -> failwith "unreachable"
+
+    member x.MutabilityInfo = 
+                                  match (flags       &&&       0b000000000001000000L) with 
+                                                             | 0b000000000000000000L -> Immutable
+                                                             | 0b000000000001000000L -> Mutable
+                                                             | _          -> failwith "unreachable"
+
+
+    member x.IsMemberOrModuleBinding = 
+                                  match (flags       &&&       0b000000000010000000L) with 
+                                                             | 0b000000000000000000L -> false
+                                                             | 0b000000000010000000L -> true
+                                                             | _          -> failwith "unreachable"
+
+
+    member x.SetIsMemberOrModuleBinding = ValFlags(flags |||   0b000000000010000000L)
+
+
+    member x.IsExtensionMember        = (flags       &&&       0b000000000100000000L) <> 0L
+    member x.IsIncrClassSpecialMember = (flags       &&&       0b000000001000000000L) <> 0L
+    member x.IsTypeFunction           = (flags       &&&       0b000000010000000000L) <> 0L
+
+    member x.RecursiveValInfo =   match (flags       &&&       0b000001100000000000L) with 
+                                                             | 0b000000000000000000L -> ValNotInRecScope
+                                                             | 0b000000100000000000L -> ValInRecScope(true)
+                                                             | 0b000001000000000000L -> ValInRecScope(false)
+                                                             | _                   -> failwith "unreachable"
+
+    member x.SetRecursiveValInfo(recValInfo) = 
+            let flags = 
+                     (flags       &&&                       ~~~0b000001100000000000L) |||
+                     (match recValInfo with
+                                     | ValNotInRecScope     -> 0b000000000000000000L
+                                     | ValInRecScope(true)  -> 0b000000100000000000L
+                                     | ValInRecScope(false) -> 0b000001000000000000L) 
+            ValFlags(flags)
+
+    member x.MakesNoCriticalTailcalls         = (flags &&&     0b000010000000000000L) <> 0L
+
+    member x.SetMakesNoCriticalTailcalls = ValFlags(flags |||  0b000010000000000000L)
+
+    member x.PermitsExplicitTypeInstantiation = (flags &&&     0b000100000000000000L) <> 0L
+    member x.HasBeenReferenced                = (flags &&&     0b001000000000000000L) <> 0L
+
+    member x.SetHasBeenReferenced        = ValFlags(flags |||  0b001000000000000000L)
+
+    member x.IsCompiledAsStaticPropertyWithoutField       = (flags &&&     0b010000000000000000L) <> 0L
+
+    member x.SetIsCompiledAsStaticPropertyWithoutField   = ValFlags(flags |||  0b010000000000000000L)
+    /// Get the flags as included in the F# binary metadata
+    member x.PickledBits = 
+        // Clear the RecursiveValInfo, only used during inference and irrelevant across assembly boundaries
+        // Clear the IsCompiledAsStaticPropertyWithoutField, only used to determine whether to use a true field for a value, and to eliminate the optimization info for observable bindings
+        // Clear the HasBeenReferenced, only used to report "unreferenced variable" warnings and to help collect 'it' values in FSI.EXE
+                                        (flags       &&&    ~~~0b011001100000000000L) 
+
+type TyparKind = 
+    | KindType 
+    | KindMeasure
+    member x.AttrName =
+      match x with
+      | KindType -> None
+      | KindMeasure -> Some "Measure"
+    override x.ToString() = 
+      match x with
+      | KindType -> "type"
+      | KindMeasure -> "measure"
+
+
+type TyparRigidity = 
+    /// Indicates the type parameter can't be solved
+    | TyparRigid 
+    /// Indicates the type parameter can't be solved, but the variable is not set to "rigid" until after inference is complete
+    | TyparWillBeRigid 
+    /// Indicates we give a warning if the type parameter is ever solved
+    | TyparWarnIfNotRigid 
+    /// Indicates the type parameter is an inference variable may be solved
+    | TyparFlexible
+    /// Indicates the type parameter derives from an '_' anonymous type
+    /// For units-of-measure, we give a warning if this gets solved to '1'
+    | TyparAnon
+    member x.ErrorIfUnified = match x with TyparRigid -> true | _ -> false
+    member x.WarnIfUnified = match x with TyparWillBeRigid | TyparWarnIfNotRigid -> true | _ -> false
+    member x.WarnIfMissingConstraint = match x with TyparWillBeRigid -> true | _ -> false
+
+
+/// Encode typar flags into a bit field  
+[<Struct>]
+type TyparFlags(flags:int32) =
+
+    new (kind:TyparKind, rigidity:TyparRigidity, isFromError:bool, isCompGen:bool, staticReq:TyparStaticReq, dynamicReq:TyparDynamicReq, equalityDependsOn: bool, comparisonDependsOn: bool) = 
+        TyparFlags((if isFromError then       0b000000000010 else 0) |||
+                   (if isCompGen   then       0b000000000100 else 0) |||
+                   (match staticReq with
+                     | NoStaticReq         -> 0b000000000000
+                     | HeadTypeStaticReq   -> 0b000000001000) |||
+                   (match rigidity with
+                     | TyparRigid          -> 0b000000000000
+                     | TyparWillBeRigid    -> 0b000000100000
+                     | TyparWarnIfNotRigid -> 0b000001000000
+                     | TyparFlexible       -> 0b000001100000
+                     | TyparAnon           -> 0b000010000000) |||
+                   (match kind with
+                     | KindType            -> 0b000000000000
+                     | KindMeasure         -> 0b000100000000) |||
+                   (if comparisonDependsOn then 
+                                              0b001000000000 else 0) |||
+                   (match dynamicReq with
+                     | NoDynamicReq        -> 0b000000000000
+                     | DynamicReq          -> 0b010000000000) |||
+                   (if equalityDependsOn then 
+                                              0b100000000000 else 0))
+
+    member x.IsFromError         = (flags &&& 0b000000000010) <> 0x0
+    member x.IsCompilerGenerated = (flags &&& 0b000000000100) <> 0x0
+    member x.StaticReq           = 
+                             match (flags &&& 0b000000001000) with 
+                                            | 0b000000000000 -> NoStaticReq
+                                            | 0b000000001000 -> HeadTypeStaticReq
+                                            | _             -> failwith "unreachable"
+
+    member x.Rigidity = 
+                             match (flags &&& 0b000011100000) with 
+                                            | 0b000000000000 -> TyparRigid
+                                            | 0b000000100000 -> TyparWillBeRigid
+                                            | 0b000001000000 -> TyparWarnIfNotRigid
+                                            | 0b000001100000 -> TyparFlexible
+                                            | 0b000010000000 -> TyparAnon
+                                            | _          -> failwith "unreachable"
+
+    member x.Kind           = 
+                             match (flags &&& 0b000100000000) with 
+                                            | 0b000000000000 -> KindType
+                                            | 0b000100000000 -> KindMeasure
+                                            | _             -> failwith "unreachable"
+
+
+    member x.ComparisonConditionalOn =
+                                   (flags &&& 0b001000000000) <> 0x0
+    member x.DynamicReq     = 
+                             match (flags &&& 0b010000000000) with 
+                                            | 0b000000000000 -> NoDynamicReq
+                                            | 0b010000000000 -> DynamicReq
+                                            | _             -> failwith "unreachable"
+    member x.EqualityConditionalOn = 
+                                   (flags &&& 0b100000000000) <> 0x0
+
+
+    /// Get the flags as included in the F# binary metadata. We pickle this as int64 to allow for future expansion
+    member x.PickledBits =         flags       
+
+/// Encode entity flags into a bit field. We leave lots of space to allow for future expansion.
+[<Struct>]
+type EntityFlags(flags:int64) =
+
+    new (usesPrefixDisplay, isModuleOrNamespace, preEstablishedHasDefaultCtor, hasSelfReferentialCtor) = 
+        EntityFlags((if isModuleOrNamespace then                        0b00000000001L else 0L) |||
+                    (if usesPrefixDisplay   then                        0b00000000010L else 0L) |||
+                    (if preEstablishedHasDefaultCtor then               0b00000000100L else 0L) |||
+                    (if hasSelfReferentialCtor then                     0b00000001000L else 0L)) 
+
+    member x.IsModuleOrNamespace                 = (flags       &&&     0b00000000001L) <> 0x0L
+    member x.IsPrefixDisplay                     = (flags       &&&     0b00000000010L) <> 0x0L
+    
+    // This bit is not pickled, only used while establishing a type constructor. It is needed because the type constructor
+    // is known to satisfy the default constructor constraint even before any of its members have been established.
+    member x.PreEstablishedHasDefaultConstructor = (flags       &&&     0b00000000100L) <> 0x0L
+
+    // This bit represents an F# specific condition where a type has at least one constructor that may access
+    // the 'this' pointer prior to successful initialization of the partial contents of the object. In this
+    // case sub-classes must protect themselves against early access to their contents.
+    member x.HasSelfReferentialConstructor       = (flags       &&&     0b00000001000L) <> 0x0L
+
+    /// Get the flags as included in the F# binary metadata
+    member x.PickledBits =                         (flags       &&&  ~~~0b00000000100L)
+
+
+#if DEBUG
+assert (sizeof<ValFlags> = 8)
+assert (sizeof<EntityFlags> = 8)
+assert (sizeof<TyparFlags> = 4)
+#endif
+
+
+let unassignedTyparName = "?"
+
+exception UndefinedName of int * (* error func that expects identifier name *)(string -> string) * ident * string list
+exception InternalUndefinedItemRef of (string * string * string -> int * string) * string * string * string
+
+let addTyconsByDemangledNameAndArity nm (typars:'a list) x tab = 
+    let nm = demangleGenericTypeName nm 
+    Map.add (NameArityPair(nm, typars.Length)) x tab
+
+let addTyconsByAccessNames nm x tab = 
+    if isMangledGenericName nm then 
+        let dnm = demangleGenericTypeName nm 
+        let res = NameMultiMap.add nm x tab 
+        NameMultiMap.add dnm x res
+    else
+        NameMultiMap.add nm x tab 
+       
+
+// Type definitions, exception definitions, module definitions and
+// namespace definitions are all 'entities'. These have too much in common to make it 
+// worth factoring them out as separate types.
+//
+// Tycons, exncs and moduls are all modelled via tycon_specs, 
+// they have different name-resolution logic. 
+// For example, an excon ABC really correspond to a type called 
+// ABCException with a union case ABC. At the moment they are 
+// simply indexed in the excon table as the discriminator constructor ABC. 
+type Entity = 
+    { mutable Data: EntityData; }
+    member x.LogicalName = x.Data.entity_logical_name
+    member x.CompiledName = match x.Data.entity_compiled_name with None -> x.LogicalName | Some s -> s
+    member x.DisplayName = demangleGenericTypeName x.Data.entity_logical_name
+    member x.DisplayNameWithUnderscoreTypars = 
+        match x.Typars(x.Range) with 
+        | [] -> x.DisplayName
+        | tps -> x.DisplayName + "<" + String.concat "," (Array.create tps.Length "_") + ">"
+    
+    member x.Range = x.Data.entity_range
+    member x.Stamp = x.Data.entity_stamp
+    member x.Attribs = x.Data.entity_attribs
+    member x.XmlDoc = x.Data.entity_xmldoc
+    member x.XmlDocSig 
+        with get() = x.Data.entity_xmldocsig
+        and set(v) = x.Data.entity_xmldocsig <- v
+    member x.ModuleOrNamespaceType = x.Data.entity_modul_contents.Force()
+    
+    member x.TypeContents = x.Data.entity_tycon_tcaug
+    member x.TypeOrMeasureKind = x.Data.entity_kind
+    member x.Id = ident(x.LogicalName, x.Range)
+    member x.TypeReprInfo = x.Data.entity_tycon_repr
+    member x.ExceptionInfo = x.Data.entity_exn_info
+    member x.IsExceptionDecl = match x.ExceptionInfo with TExnNone -> false | _ -> true
+
+    static member DemangleEntityName nm k =  
+        match k with 
+        | FSharpModuleWithSuffix -> String.dropSuffix nm fsharpModuleSuffix
+        | _ -> nm
+
+    member x.DemangledModuleOrNamespaceName =  
+          Entity.DemangleEntityName x.LogicalName x.ModuleOrNamespaceType.ModuleOrNamespaceKind
+    
+    member x.Typars(m) = x.Data.entity_typars.Force(m) // lazy because it may read metadata, must provide a context "range" in case error occurs reading metadata
+    member x.TyparsNoRange = x.Typars(x.Range)
+    member x.TypeAbbrev = x.Data.entity_tycon_abbrev
+    member x.IsTypeAbbrev = x.TypeAbbrev.IsSome
+    member x.TypeReprAccessibility = x.Data.entity_tycon_repr_accessibility
+    member x.CompiledReprCache = x.Data.entity_il_repr_cache
+    member x.PublicPath = x.Data.entity_pubpath
+    member x.Accessibility = x.Data.entity_accessiblity
+    /// Indicates the type prefers the "tycon<a,b>" syntax for display etc. 
+    member x.IsPrefixDisplay = x.Data.entity_flags.IsPrefixDisplay
+    /// Indicates the "tycon blob" is actually a module 
+    member x.IsModuleOrNamespace = x.Data.entity_flags.IsModuleOrNamespace
+    
+    member x.IsNamespace = x.IsModuleOrNamespace && (match x.ModuleOrNamespaceType.ModuleOrNamespaceKind with Namespace -> true | _ -> false)
+    member x.IsModule = x.IsModuleOrNamespace && (match x.ModuleOrNamespaceType.ModuleOrNamespaceKind with Namespace -> false | _ -> true)
+    member x.CompilationPathOpt = x.Data.entity_cpath 
+    member x.CompilationPath = 
+        match x.CompilationPathOpt with 
+        | Some cpath -> cpath 
+        | None -> error(Error(FSComp.SR.tastTypeOrModuleNotConcrete(x.LogicalName),x.Range))
+    
+    member x.AllFieldTable = 
+        match x.TypeReprInfo with 
+        | Some (TRecdRepr x | TFsObjModelRepr {fsobjmodel_rfields=x}) -> x
+        |  _ -> 
+        match x.ExceptionInfo with 
+        | TExnFresh x -> x
+        | _ -> 
+        { rfields_by_index = [| |]; 
+          rfields_by_name = NameMap.empty }
+
+    member x.AllFieldsArray = x.AllFieldTable.rfields_by_index
+    member x.AllFieldsAsList = x.AllFieldsArray |> Array.toList
+
+    // NOTE: This method is over-used...
+    member x.AllInstanceFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsStatic)
+    member x.TrueFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsCompilerGenerated)
+    member x.TrueInstanceFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsStatic && not f.IsCompilerGenerated)
+
+    member x.GetFieldByIndex(n) = x.AllFieldTable.FieldByIndex(n)
+    member x.GetFieldByName(n) = x.AllFieldTable.FieldByName(n)
+
+    member x.UnionTypeInfo = 
+        match x.Data.entity_tycon_repr with 
+        | Some (TFiniteUnionRepr x) -> Some x 
+        |  _ -> None
+
+    member x.UnionCasesArray = 
+        match x.UnionTypeInfo with 
+        | Some x -> x.funion_ucases.ucases_by_index 
+        | None -> [| |] 
+
+    member x.UnionCasesAsList = x.UnionCasesArray |> Array.toList
+
+    member x.GetUnionCaseByName(n) =
+        match x.UnionTypeInfo with 
+        | Some x  -> NameMap.tryFind n x.funion_ucases.ucases_by_name
+        | None -> None
+
+    
+    // OSGN support
+    static member NewUnlinked() : Entity = { Data = Unchecked.defaultof<_> }
+    static member New reason data : Entity  = 
+        { Data = data }
+    member x.Link(tg) = x.Data <- tg
+    member x.IsLinked = match box x.Data with null -> false | _ -> true 
+
+    override x.ToString() = x.LogicalName
+
+    member x.FSharpObjectModelTypeInfo = 
+         match x.Data.entity_tycon_repr with 
+         | Some (TFsObjModelRepr x) -> x 
+         |  _ -> failwith "not an F# object model type definition"
+
+    member x.IsILTycon = match x.TypeReprInfo with | Some (TILObjModelRepr _) -> true |  _ -> false
+    member x.ILTyconInfo = match x.TypeReprInfo with | Some (TILObjModelRepr (a,b,c)) -> (a,b,c) |  _ -> failwith "not a .NET type definition"
+    member x.ILTyconRawMetadata = let _,_,td = x.ILTyconInfo in td
+
+    member x.IsUnionTycon = match x.TypeReprInfo with | Some (TFiniteUnionRepr _) -> true |  _ -> false
+    member x.UnionInfo = match x.TypeReprInfo with | Some (TFiniteUnionRepr x) -> Some x |  _ -> None
+
+    member x.IsRecordTycon = match x.TypeReprInfo with | Some (TRecdRepr _) -> true |  _ -> false
+    member x.IsFSharpObjectModelTycon = match x.TypeReprInfo with | Some (TFsObjModelRepr _) -> true |  _ -> false
+    member x.IsAsmReprTycon = match x.TypeReprInfo with | Some (TAsmRepr _) -> true |  _ -> false
+    member x.IsMeasureableReprTycon = match x.TypeReprInfo with | Some (TMeasureableRepr _) -> true |  _ -> false
+    member x.IsHiddenReprTycon = match x.TypeAbbrev,x.TypeReprInfo with | None,None -> true |  _ -> false
+
+    member x.IsFSharpInterfaceTycon = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TTyconInterface -> true | _ -> false
+    member x.IsFSharpDelegateTycon  = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TTyconDelegate _ -> true | _ -> false
+    member x.IsFSharpEnumTycon      = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TTyconEnum -> true | _ -> false
+    member x.IsFSharpClassTycon     = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TTyconClass -> true | _ -> false
+    member x.IsILEnumTycon          = x.IsILTycon && x.ILTyconRawMetadata.IsEnum
+    member x.IsEnumTycon            = x.IsILEnumTycon || x.IsFSharpEnumTycon
+
+
+    member x.IsFSharpStructOrEnumTycon =
+        x.IsFSharpObjectModelTycon &&
+        match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with 
+        | TTyconClass | TTyconInterface   | TTyconDelegate _ -> false
+        | TTyconStruct | TTyconEnum -> true
+
+    member x.IsILStructTycon =
+        x.IsILTycon && 
+        match x.ILTyconRawMetadata.tdKind with
+        | ILTypeDefKind.ValueType | ILTypeDefKind.Enum -> true
+        | _ -> false
+
+    member x.IsStructOrEnumTycon = 
+        x.IsILStructTycon || x.IsFSharpStructOrEnumTycon
+
+    member x.InterfacesOfFSharpTycon =
+        x.TypeContents.tcaug_interfaces
+
+    member x.InterfaceTypesOfFSharpTycon =
+        x.InterfacesOfFSharpTycon |> List.map (fun (x,_,_) -> x)
+
+    /// Note: result is alphabetically sorted, then for each name the results are in declaration order
+    member x.MembersOfFSharpTyconSorted =
+        x.TypeContents.tcaug_adhoc 
+        |> NameMultiMap.rangeReversingEachBucket 
+        |> List.filter (fun v -> not v.IsCompilerGenerated)
+
+    /// Note: result is a indexed table, and for each name the results are in reverse declaration order
+    member x.MembersOfFSharpTyconByName =
+        x.TypeContents.tcaug_adhoc 
+
+    member x.GeneratedHashAndEqualsWithComparerValues = x.TypeContents.tcaug_hash_and_equals_withc 
+    member x.GeneratedCompareToWithComparerValues = x.TypeContents.tcaug_compare_withc
+    member x.GeneratedCompareToValues = x.TypeContents.tcaug_compare
+    member x.GeneratedHashAndEqualsValues = x.TypeContents.tcaug_equals
+    member x.AllGeneratedValues = 
+        [ match x.GeneratedCompareToValues with 
+          | None -> ()
+          | Some (v1,v2) -> yield v1; yield v2
+          match x.GeneratedCompareToWithComparerValues with
+          | None -> ()
+          | Some v -> yield v
+          match x.GeneratedHashAndEqualsValues with
+          | None -> ()
+          | Some (v1,v2) -> yield v1; yield v2
+          match x.GeneratedHashAndEqualsWithComparerValues with
+          | None -> ()
+          | Some (v1,v2,v3) -> yield v1; yield v2; yield v3 ]
+    
+
+    /// From TAST TyconRef to IL ILTypeRef
+    member x.CompiledRepresentation =
+
+        let ilTypeRefForCompilationPath (CompPath(sref,p)) item = 
+            let rec top racc  p = 
+                match p with 
+                | [] -> ILTypeRef.Create(sref,[],text_of_path  (List.rev (item::racc)))
+                | (h,istype)::t -> 
+                    match istype with 
+                    | FSharpModuleWithSuffix | FSharpModule -> 
+                        let outerTypeName = (text_of_path (List.rev (h::racc)))
+                        ILTypeRef.Create(sref, (outerTypeName :: List.map (fun (nm,_) -> nm) t),item)
+                    | _ -> 
+                      top (h::racc) t
+            top [] p 
+
+
+        cached x.CompiledReprCache (fun () -> 
+            match x.ExceptionInfo with 
+            | TExnAbbrevRepr ecref2 -> ecref2.CompiledRepresentation
+            | TExnAsmRepr tref -> TyrepNamed(tref, AsObject, Some (mk_typ AsObject (mk_tspec (tref,[]))))
+            | _ -> 
+            match x.TypeReprInfo with 
+            | Some (TAsmRepr typ) -> TyrepOpen typ
+            | _ -> 
+                let boxity = if x.IsStructOrEnumTycon then AsValue else AsObject
+                let ilTypeRef = ilTypeRefForCompilationPath x.CompilationPath x.CompiledName
+                let ilTypeOpt = 
+                    match x.TyparsNoRange with 
+                    | [] -> Some (mk_typ boxity (mk_tspec (ilTypeRef,[]))) 
+                    | _ -> None 
+                TyrepNamed (ilTypeRef, boxity, ilTypeOpt))
+
+
+    member x.CompiledRepresentationForTyrepNamed =
+        match x.CompiledRepresentation with 
+        | TyrepNamed(tref, _, _) -> tref
+        | TyrepOpen _ -> invalidOp (FSComp.SR.tastTypeHasAssemblyCodeRepresentation(x.DisplayNameWithUnderscoreTypars))
+
+
+    member x.PreEstablishedHasDefaultConstructor = x.Data.entity_flags.PreEstablishedHasDefaultConstructor
+    member x.HasSelfReferentialConstructor = x.Data.entity_flags.HasSelfReferentialConstructor
+
+and 
+    [<NoEquality; NoComparison>]
+    EntityData =
+    { /// The declared type parameters of the type  
+      mutable entity_typars: LazyWithContext<Typars, range>;        
+
+      mutable entity_kind : TyparKind;
+      
+      mutable entity_flags : EntityFlags;
+      
+      /// The unique stamp of the "tycon blob". Note the same tycon in signature and implementation get different stamps 
+      entity_stamp: stamp;
+
+      /// The name of the type, possibly with `n mangling 
+      entity_logical_name: string;
+
+      /// The name of the type, possibly with `n mangling 
+      mutable entity_compiled_name: string option;
+
+      /// The declaration location for the type constructor 
+      entity_range: range;
+      
+      /// The declared accessibility of the representation, not taking signatures into account 
+      entity_tycon_repr_accessibility: Accessibility;
+      
+      /// The declared attributes for the type 
+      mutable entity_attribs: Attribs;     
+                
+      /// The declared representation of the type, i.e. record, union, class etc. 
+      mutable entity_tycon_repr: TyconRepresentation option;   
+
+      /// If non-None, indicates the type is an abbreviation for another type. 
+      mutable entity_tycon_abbrev: typ option;             
+      
+      /// The methods and properties of the type 
+      mutable entity_tycon_tcaug: TyconAugmentation;      
+      
+      /// Field used when the 'tycon' is really an exception definition 
+      mutable entity_exn_info: ExceptionInfo;     
+      
+      /// This field is used when the 'tycon' is really a module definition. It holds statically nested type definitions and nested modules 
+      mutable entity_modul_contents: Lazy<ModuleOrNamespaceType>;     
+
+      /// The declared documentation for the type or module 
+      entity_xmldoc : XmlDoc;
+      
+      /// The XML document signature for this entity
+      mutable entity_xmldocsig : string;
+
+      /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 
+      entity_pubpath : PublicPath option; 
+
+      mutable entity_accessiblity: Accessibility; (*   how visible is this? *) 
+ 
+      /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 
+      entity_cpath : CompilationPath option; 
+
+      /// Used during codegen to hold the ILX representation indicating how to access the type 
+      entity_il_repr_cache : CompiledTypeRepr cache;  
+
+    }
+
+and ParentRef = 
+    | Parent of TyconRef
+    | ParentNone
+    
+and 
+    [<NoEquality; NoComparison>]
+    TyconAugmentation = 
+    { /// This is the value implementing the auto-generated comparison 
+      /// semantics if any. It is not present if the type defines its own implementation 
+      /// of IComparable or if the type doesn't implement IComparable implicitly. 
+      mutable tcaug_compare        : (ValRef * ValRef) option;
+      
+      /// This is the value implementing the auto-generated comparison
+      /// semantics if any. It is not present if the type defines its own implementation
+      /// of IStructuralComparable or if the type doesn't implement IComparable implicitly.
+      mutable tcaug_compare_withc : ValRef option;                      
+
+      /// This is the value implementing the auto-generated equality 
+      /// semantics if any. It is not present if the type defines its own implementation 
+      /// of Object.Equals or if the type doesn't override Object.Equals implicitly. 
+      mutable tcaug_equals        : (ValRef * ValRef) option;
+
+      /// This is the value implementing the auto-generated comparison
+      /// semantics if any. It is not present if the type defines its own implementation
+      /// of IStructuralEquatable or if the type doesn't implement IComparable implicitly.
+      mutable tcaug_hash_and_equals_withc : (ValRef * ValRef * ValRef) option;                                    
+
+      /// True if the type defined an Object.GetHashCode method. In this 
+      /// case we give a warning if we auto-generate a hash method since the semantics may not match up
+      mutable tcaug_hasObjectGetHashCode : bool;             
+      
+      /// Properties, methods etc. in declaration order
+      tcaug_adhoc_list     : ResizeArray<ValRef> ;
+      
+      /// Properties, methods etc. as lookup table
+      mutable tcaug_adhoc          : NameMultiMap<ValRef>;
+      
+      /// Interface implementations - boolean indicates compiler-generated 
+      mutable tcaug_interfaces     : (typ * bool * range) list;  
+      
+      /// Super type, if any 
+      mutable tcaug_super          : typ option;                 
+      
+      /// Set to true at the end of the scope where proper augmentations are allowed 
+      mutable tcaug_closed         : bool;                       
+
+      /// Set to true if the type is determined to be abstract 
+      mutable tcaug_abstract : bool;                       
+    }
+   
+and 
+    [<NoEquality; NoComparison>]
+    TyconRepresentation = 
+    /// Indicates the type is a class, struct, enum, delegate or interface 
+    | TFsObjModelRepr    of TyconObjModelData
+    /// Indicates the type is a record 
+    | TRecdRepr          of TyconRecdFields
+    /// Indicates the type is a discriminated union 
+    | TFiniteUnionRepr   of TyconUnionData 
+    /// Indicates the type is a .NET type 
+    | TILObjModelRepr    of 
+          // scope: 
+          ILScopeRef * 
+          // nesting:   
+          ILTypeDef list * 
+          // definition: 
+          ILTypeDef 
+    /// Indicates the type is implemented as IL assembly code using the given closed Abstract IL type 
+    | TAsmRepr           of ILType
+    /// Indicates the type is parameterized on a measure (e.g. float<_>) but erases to some other type (e.g. float)
+    | TMeasureableRepr   of typ
+
+
+and 
+  TyconObjModelKind = 
+    /// Indicates the type is a class (also used for units-of-measure)
+    | TTyconClass 
+    /// Indicates the type is an interface 
+    | TTyconInterface 
+    /// Indicates the type is a struct 
+    | TTyconStruct 
+    /// Indicates the type is a delegate with the given Invoke signature 
+    | TTyconDelegate of SlotSig 
+    /// Indicates the type is an enumeration 
+    | TTyconEnum
+    
+and 
+    [<NoEquality; NoComparison>]
+    TyconObjModelData = 
+    { /// Indicates whether the type declaration is a class, interface, enum, delegate or struct 
+      fsobjmodel_kind: TyconObjModelKind;
+      /// The declared abstract slots of the class, interface or struct 
+      fsobjmodel_vslots: ValRef list; 
+      /// The fields of the class, struct or enum 
+      fsobjmodel_rfields: TyconRecdFields }
+
+and 
+    [<NoEquality; NoComparison>]
+    TyconRecdFields = 
+    { /// The fields of the record, in declaration order. 
+      rfields_by_index: RecdField array;
+      
+      /// The fields of the record, indexed by name. 
+      rfields_by_name : RecdField NameMap  }
+
+    member x.FieldByIndex(n) = 
+        if n >= 0 && n < Array.length x.rfields_by_index then x.rfields_by_index.[n] 
+        else failwith "FieldByIndex"
+
+    member x.FieldByName(n) = x.rfields_by_name.TryFind(n)
+
+    member x.AllFieldsAsList = x.rfields_by_index |> Array.toList
+    member x.TrueFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsCompilerGenerated)   
+    member x.TrueInstanceFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsStatic && not f.IsCompilerGenerated)   
+
+and 
+    [<NoEquality; NoComparison>]
+    TyconUnionCases = 
+    { /// The cases of the discriminated union, in declaration order. 
+      ucases_by_index: UnionCase array;
+      /// The cases of the discriminated union, indexed by name. 
+      ucases_by_name : UnionCase NameMap 
+    }
+    member x.GetUnionCaseByIndex(n) = 
+        if n >= 0 && n < x.ucases_by_index.Length then x.ucases_by_index.[n] 
+        else invalidArg "n" "GetUnionCaseByIndex"
+
+    member x.UnionCasesAsList = x.ucases_by_index |> Array.toList
+
+and 
+    [<NoEquality; NoComparison>]
+    TyconUnionData =
+    { /// The cases contained in the discriminated union. 
+      funion_ucases: TyconUnionCases;
+      /// The ILX data structure representing the discriminated union. 
+    }
+    member x.UnionCasesAsList = x.funion_ucases.ucases_by_index |> Array.toList
+
+and 
+    [<NoEquality; NoComparison>]
+    [<StructuredFormatDisplay("{DisplayName}")>]
+    UnionCase =
+    { /// Data carried by the case. 
+      ucase_rfields: TyconRecdFields;
+      /// Return type constructed by the case. Normally exactly the type of the enclosing type, sometimes an abbreviation of it 
+      ucase_rty: typ;
+      /// Name of the case in generated IL code 
+      ucase_il_name: string;
+      /// Documentation for the case 
+      ucase_xmldoc : XmlDoc;
+      /// XML documentation signature for the case
+      mutable ucase_xmldocsig : string;
+      /// Name/range of the case 
+      ucase_id: ident; 
+      ///  Indicates the declared visibility of the union constructor, not taking signatures into account 
+      ucase_access: Accessibility; 
+      /// Attributes, attached to the generated static method to make instances of the case 
+      mutable ucase_attribs: Attribs; }
+
+    member uc.Attribs = uc.ucase_attribs
+    member uc.Range = uc.ucase_id.idRange
+    member uc.Id = uc.ucase_id
+    member uc.Accessibility = uc.ucase_access
+    member uc.DisplayName = uc.Id.idText
+    member uc.RecdFieldsArray = uc.ucase_rfields.rfields_by_index 
+    member uc.RecdFields = uc.ucase_rfields.rfields_by_index |> Array.toList
+    member uc.GetFieldByName nm = uc.ucase_rfields.FieldByName nm
+    member uc.IsNullary = (uc.ucase_rfields.rfields_by_index.Length = 0)
+    member uc.XmlDoc = uc.ucase_xmldoc
+    member uc.XmlDocSig 
+        with get() = uc.ucase_xmldocsig
+        and set(v) = uc.ucase_xmldocsig <- v
+    member uc.ReturnType = uc.ucase_rty
+
+and 
+    /// This may represent a "field" in either a struct, class, record or union
+    /// It is normally compiled to a property.
+    [<NoEquality; NoComparison>]
+    RecdField =
+    { /// Is the field declared mutable in F#? 
+      rfield_mutable: bool;
+      /// Documentation for the field 
+      rfield_xmldoc : XmlDoc;
+      /// XML Documentation signature for the field
+      mutable rfield_xmldocsig : string;
+      /// The type of the field, w.r.t. the generic parameters of the enclosing type constructor 
+      rfield_type: typ;
+      /// Indicates a static field 
+      rfield_static: bool;
+      /// Indicates a volatile field 
+      rfield_volatile: bool;
+      /// Indicates a compiler generated field, not visible to Intellisense or name resolution 
+      rfield_secret: bool;
+      /// The default initialization info, for static literals 
+      rfield_const: Constant option; 
+      ///  Indicates the declared visibility of the field, not taking signatures into account 
+      rfield_access: Accessibility; 
+      /// Attributes attached to generated property 
+      mutable rfield_pattribs: Attribs; 
+      /// Attributes attached to generated field 
+      mutable rfield_fattribs: Attribs; 
+      /// Name/declaration-location of the field 
+      rfield_id: ident; }
+    member v.Accessibility = v.rfield_access
+    member v.PropertyAttribs = v.rfield_pattribs
+    member v.FieldAttribs = v.rfield_fattribs
+    member v.Range = v.rfield_id.idRange
+    member v.Id = v.rfield_id
+    member v.Name = v.rfield_id.idText
+    member v.IsCompilerGenerated = v.rfield_secret
+    member v.IsMutable = v.rfield_mutable
+    member v.IsStatic = v.rfield_static
+    member v.IsVolatile = v.rfield_volatile
+    member v.FormalType = v.rfield_type
+    member v.XmlDoc = v.rfield_xmldoc
+    member v.XmlDocSig
+        with get() = v.rfield_xmldocsig
+        and set(x) = v.rfield_xmldocsig <- x
+
+    member v.LiteralValue = 
+        match v.rfield_const  with 
+        | None -> None
+        | Some(TConst_zero) -> None
+        | Some(k) -> Some(k)
+
+    member v.IsZeroInit = 
+        match v.rfield_const  with 
+        | None -> false 
+        | Some(TConst_zero) -> true 
+        | _ -> false
+
+and ExceptionInfo =
+    /// Indicates that an exception is an abbreviation for the given exception 
+    | TExnAbbrevRepr of TyconRef 
+    /// Indicates that an exception is shorthand for the given .NET exception type 
+    | TExnAsmRepr of ILTypeRef
+    /// Indicates that an exception carries the given record of values 
+    | TExnFresh of TyconRecdFields
+    /// Indicates that an exception is abstract, i.e. is in a signature file, and we do not know the representation 
+    | TExnNone
+
+and ModuleOrNamespaceKind = 
+    /// Indicates that a module is compiled to a class with the "Module" suffix added. 
+    | FSharpModuleWithSuffix 
+    /// Indicates that a module is compiled to a class with the same name as the original module 
+    | FSharpModule 
+    /// Indicates that a 'module' is really a namespace 
+    | Namespace
+
+and 
+    [<Sealed>]
+    ModuleOrNamespaceType(kind: ModuleOrNamespaceKind, vals: QueueList<Val>, entities: QueueList<Entity>) = 
+
+      /// Mutation used during compilation of FSharp.Core.dll
+      let mutable entities = entities 
+      
+      // Lookup tables keyed the way various clients expect them to be keyed.
+      // We attach them here so we don't need to store lookup tables via any other technique.
+      //
+      // The type option ref is used because there are a few functions that treat these as first class values.
+      // We should probably change to 'mutable'.
+      //
+      // We do not need to lock this mutable state this it is only ever accessed from the compiler thread.
+      let apref_cache                        : NameMap<ActivePatternElemRef> option ref = ref None
+      let modulesByDemangledName_cache       : NameMap<ModuleOrNamespace>    option ref = ref None
+      let exconsByDemangledName_cache        : NameMap<Tycon>                option ref = ref None
+      let tyconsByDemangledNameAndArity_cache: Map<NameArityPair, Tycon>     option ref = ref None
+      let tyconsByAccessNames_cache          : NameMultiMap<Tycon>           option ref = ref None
+      let tyconsByMangledName_cache          : NameMap<Tycon>                option ref = ref None
+      let allEntitiesByMangledName_cache     : NameMap<Entity>               option ref = ref None
+      let allValsAndMembersByPartialLinkageKey_cache : MultiMap<ValLinkagePartialKey, Val>    option ref = ref None
+      let allValsByLogicalName_cache         : NameMap<Val>               option ref = ref None
+  
+      /// Namespace or module-compiled-as-type? 
+      member mtyp.ModuleOrNamespaceKind = kind 
+              
+      /// Values, including members in F# types in this module-or-namespace-fragment. 
+      member mtyp.AllValsAndMembers = vals
+
+      /// Type, mapping mangled name to Tycon, e.g. 
+      ////     "Dictionary`2" --> Tycon 
+      ////     "ListModule" --> Tycon with module info
+      ////     "FooException" --> Tycon with exception info
+      member mtyp.AllEntities = entities
+
+      /// Mutation used during compilation of FSharp.Core.dll
+      member mtyp.AddModuleOrNamespaceByMutation(modul:ModuleOrNamespace) =
+          entities <- QueueList.appendOne entities modul
+          modulesByDemangledName_cache := None          
+          allEntitiesByMangledName_cache := None          
+          
+      member mtyp.AddEntity(tycon:Tycon) = 
+          ModuleOrNamespaceType(kind, vals, entities.AppendOne tycon)
+          
+      member mtyp.AddVal(vspec:Val) = 
+          ModuleOrNamespaceType(kind, vals.AppendOne vspec, entities)
+          
+      member mtyp.ActivePatternsLookupTable               = apref_cache
+  
+      member mtyp.TypeDefinitions               = entities |> Seq.filter (fun x -> not x.IsExceptionDecl && not x.IsModuleOrNamespace) |> Seq.toList
+      member mtyp.ExceptionDefinitions          = entities |> Seq.filter (fun x -> x.IsExceptionDecl) |> Seq.toList
+      member mtyp.ModuleAndNamespaceDefinitions = entities |> Seq.filter (fun x -> x.IsModuleOrNamespace) |> Seq.toList
+      member mtyp.TypeAndExceptionDefinitions   = entities |> Seq.filter (fun x -> not x.IsModuleOrNamespace) |> Seq.toList
+
+      member mtyp.TypesByDemangledNameAndArity(m) = 
+        cacheOptRef tyconsByDemangledNameAndArity_cache (fun () -> 
+           List.foldBack (fun (tc:Tycon) acc -> addTyconsByDemangledNameAndArity tc.LogicalName (tc.Typars(m)) tc acc) mtyp.TypeAndExceptionDefinitions  Map.empty)
+
+      member mtyp.TypesByAccessNames = 
+          cacheOptRef tyconsByAccessNames_cache (fun () -> 
+             List.foldBack (fun (tc:Tycon) acc -> addTyconsByAccessNames tc.LogicalName tc acc) mtyp.TypeAndExceptionDefinitions  Map.empty)
+
+      member mtyp.TypesByMangledName = 
+          let addTyconByMangledName (x:Tycon) tab = NameMap.add x.LogicalName x tab 
+          cacheOptRef tyconsByMangledName_cache (fun () -> 
+             List.foldBack addTyconByMangledName mtyp.TypeAndExceptionDefinitions  Map.empty)
+
+      member mtyp.AllEntitiesByCompiledAndLogicalMangledNames : NameMap<Entity> = 
+          let addEntityByMangledName (x:Entity) tab = 
+              let name1 = x.LogicalName
+              let name2 = x.CompiledName
+              let tab = NameMap.add name1 x tab 
+              if name1 = name2 then tab
+              else NameMap.add name2 x tab 
+          
+          cacheOptRef allEntitiesByMangledName_cache (fun () -> 
+             QueueList.foldBack addEntityByMangledName entities  Map.empty)
+
+      member mtyp.AllEntitiesByLogicalMangledName : NameMap<Entity> = 
+          let addEntityByMangledName (x:Entity) tab = NameMap.add x.LogicalName x tab 
+          QueueList.foldBack addEntityByMangledName entities  Map.empty
+
+      member mtyp.AllValsAndMembersByPartialLinkageKey = 
+          let addValByMangledName (x:Val) tab = 
+             if x.IsCompiledAsTopLevel then
+                 MultiMap.add x.LinkagePartialKey x tab 
+             else
+                 tab
+          cacheOptRef allValsAndMembersByPartialLinkageKey_cache (fun () -> 
+             QueueList.foldBack addValByMangledName vals MultiMap.empty)
+
+      member mtyp.TryLinkVal(ccu:CcuThunk,key:ValLinkageFullKey) = 
+          mtyp.AllValsAndMembersByPartialLinkageKey
+            |> MultiMap.find key.PartialKey
+            |> List.tryFind (fun v -> match key.TypeForLinkage with 
+                                      | None -> true
+                                      | Some keyTy -> ccu.MemberSignatureEquality(keyTy,v.Type))
+
+      member mtyp.AllValsByLogicalName = 
+          let addValByName (x:Val) tab = 
+             // Note: names may occur twice prior to raising errors about this in PostTypecheckSemanticChecks
+             // Earlier ones take precedence sice we report errors about the later ones
+             if not x.IsMember && not x.IsCompilerGenerated then 
+                 NameMap.add x.LogicalName x tab 
+             else
+                 tab
+          cacheOptRef allValsByLogicalName_cache (fun () -> 
+             QueueList.foldBack addValByName vals Map.empty)
+
+      member mtyp.AllValsAndMembersByLogicalNameUncached = 
+          let addValByName (x:Val) tab = 
+             if not x.IsCompilerGenerated then 
+                 MultiMap.add x.LogicalName x tab 
+             else
+                 tab
+          QueueList.foldBack addValByName vals MultiMap.empty
+
+      member mtyp.ExceptionDefinitionsByDemangledName = 
+          let addExconByDemangledName (tycon:Tycon) acc = NameMap.add tycon.LogicalName tycon acc
+          cacheOptRef exconsByDemangledName_cache (fun () -> 
+             List.foldBack addExconByDemangledName mtyp.ExceptionDefinitions  Map.empty)
+
+      member mtyp.ModulesAndNamespacesByDemangledName = 
+          let add_moduleByDemangledName (entity:Entity) acc = 
+              if entity.IsModuleOrNamespace then 
+                  NameMap.add entity.DemangledModuleOrNamespaceName entity acc
+              else acc
+          cacheOptRef modulesByDemangledName_cache (fun () -> 
+             QueueList.foldBack add_moduleByDemangledName entities  Map.empty)
+
+and ModuleOrNamespace = Entity 
+and Tycon = Entity 
+
+and Accessibility = 
+    /// Indicates the construct can only be accessed from any code in the given type constructor, module or assembly. [] indicates global scope. 
+    | TAccess of CompilationPath list
+    
+and 
+    [<NoEquality; NoComparison>]
+    TyparData = 
+    { mutable typar_id: ident; 
+       
+      mutable typar_il_name: string option;
+       
+      mutable typar_flags: TyparFlags;
+       
+       /// The unique stamp of the typar blob. 
+      typar_stamp: stamp; 
+       
+       /// The documentation for the type parameter. Empty for type inference variables.
+      typar_xmldoc : XmlDoc;
+       
+       /// The declared attributes of the type parameter. Empty for type inference variables. 
+      mutable typar_attribs: Attribs;                      
+       
+       /// An inferred equivalence for a type inference variable. 
+      mutable typar_solution: typ option;
+       
+       /// The inferred constraints for the type inference variable 
+      mutable typar_constraints: TyparConstraint list; 
+    } 
+
+and 
+    [<NoEquality; NoComparison>]
+    [<StructuredFormatDisplay("{Name}")>]
+    Typar = 
+    { mutable Data: TyparData;
+      mutable AsType: typ }
+    member x.Name                = x.Data.typar_id.idText
+    member x.Range               = x.Data.typar_id.idRange
+    member x.Id                  = x.Data.typar_id
+    member x.Stamp               = x.Data.typar_stamp
+    member x.Solution            = x.Data.typar_solution
+    member x.Constraints         = x.Data.typar_constraints
+    member x.IsCompilerGenerated = x.Data.typar_flags.IsCompilerGenerated
+    member x.Rigidity            = x.Data.typar_flags.Rigidity
+    member x.DynamicReq          = x.Data.typar_flags.DynamicReq
+    member x.EqualityConditionalOn = x.Data.typar_flags.EqualityConditionalOn
+    member x.ComparisonConditionalOn = x.Data.typar_flags.ComparisonConditionalOn
+    member x.StaticReq           = x.Data.typar_flags.StaticReq
+    member x.IsFromError         = x.Data.typar_flags.IsFromError
+    member x.Kind                = x.Data.typar_flags.Kind
+    member x.IsErased            = match x.Kind with KindType -> false | _ -> true
+    member x.Attribs             = x.Data.typar_attribs
+    member x.DisplayName = let nm = x.Name in if nm = "?" then "?"+string x.Stamp else nm
+
+    // OSGN support
+    static member NewUnlinked() : Typar  = 
+        let res = { Data = Unchecked.defaultof<_>; AsType=Unchecked.defaultof<_> }
+        res.AsType <- TType_var res
+        res
+    static member New(data) : Typar = 
+        let res = { Data = data; AsType=Unchecked.defaultof<_> }
+        res.AsType <- TType_var res
+        res
+    member x.Link(tg) = x.Data <- tg
+    member x.IsLinked = match box x.Data with null -> false | _ -> true 
+
+    override x.ToString() = x.Name
+
+and
+    [<NoEquality; NoComparison>]
+    TyparConstraint = 
+    /// Indicates a constraint that a type is a subtype of the given type 
+    | TTyparCoercesToType              of typ * range
+
+    /// Indicates a default value for an inference type variable should it be netiher generalized nor solved 
+    | TTyparDefaultsToType             of int * typ * range 
+    
+    /// Indicates a constraint that a type has a 'null' value 
+    | TTyparSupportsNull               of range 
+    
+    /// Indicates a constraint that a type has a member with the given signature 
+    | TTyparMayResolveMemberConstraint of TraitConstraintInfo * range 
+    
+    /// Indicates a constraint that a type is a non-Nullable value type 
+    /// These are part of .NET's model of generic constraints, and in order to 
+    /// generate verifiable code we must attach them to F# generalzied type variables as well. 
+    | TTyparIsNotNullableValueType     of range 
+    
+    /// Indicates a constraint that a type is a reference type 
+    | TTyparIsReferenceType            of range 
+
+    /// Indicates a constraint that a type is a simple choice between one of the given ground types. See format.fs 
+    | TTyparSimpleChoice               of typ list * range 
+
+    /// Indicates a constraint that a type has a parameterless constructor 
+    | TTyparRequiresDefaultConstructor of range 
+
+    /// Indicates a constraint that a type is an enum with the given underlying 
+    | TTyparIsEnum                     of typ * range 
+    
+    /// Indicates a constraint that a type implements IComparable, with special rules for some known structural container types
+    | TTyparSupportsComparison               of range 
+    
+    /// Indicates a constraint that a type does not have the Equality(false) attribute, or is not a structural type with this attribute, with special rules for some known structural container types
+    | TTyparSupportsEquality                of range 
+    
+    /// Indicates a constraint that a type is a delegate from the given tuple of args to the given return type
+    | TTyparIsDelegate                 of typ * typ * range 
+    
+    /// Indicates a constraint that a type is .NET unmanaged type
+    | TTyparIsUnmanaged                 of range
+    
+/// The specification of a member constraint that must be solved 
+and 
+    [<NoEquality; NoComparison>]
+    TraitConstraintInfo = 
+    /// Indicates the signature of a member constraint. Contains a mutable solution cell
+    /// to store the inferred solution of the constraint.
+    | TTrait of typ list * string * MemberFlags * typ list * typ option * (* solution: *) TraitConstraintSln option ref 
+    member x.MemberName = (let (TTrait(_,nm,_,_,_,_)) = x in nm)
+    member x.ReturnType = (let (TTrait(_,_,_,_,ty,_)) = x in ty)
+    member x.Solution 
+        with get() = (let (TTrait(_,_,_,_,_,sln)) = x in sln.Value)
+        and set(v) = (let (TTrait(_,_,_,_,_,sln)) = x in sln.Value <- v)
+    
+and 
+    [<NoEquality; NoComparison>]
+    TraitConstraintSln = 
+    | FSMethSln of 
+         typ * // the type and its instantiation
+         ValRef  *   // the method
+         tinst // the generic method instantiation 
+    | ILMethSln of
+         typ * 
+         ILTypeRef option (* extension? *) * 
+         ILMethodRef * 
+         // typars * // the uninstantiated generic method args 
+         tinst    // the generic method instantiation 
+    | BuiltInSln
+
+and ValLinkagePartialKey = 
+   { MemberParentMangledName : string option; 
+     MemberIsOverride: bool; 
+     LogicalName: string; 
+     TotalArgCount: int } 
+
+and ValLinkageFullKey(partialKey: ValLinkagePartialKey,  typeForLinkage:typ option) =
+   member x.PartialKey = partialKey
+   member x.TypeForLinkage = typeForLinkage
+
+
+and 
+    [<StructuredFormatDisplay("{LogicalName}")>]
+    Val = 
+    { mutable Data: ValData; }
+    /// The place where the value was defined. 
+    member x.Range = x.Data.val_range
+    /// A unique stamp within the context of this invocation of the compiler process 
+    member x.Stamp = x.Data.val_stamp
+    /// The type of the value. 
+    /// May be a Type_forall for a generic value. 
+    /// May be a type variable or type containing type variables during type inference. 
+
+    // Mutability used in inference by adjustAllUsesOfRecValue.  
+    // This replaces the recursively inferred type with a schema. 
+    member x.Type                       = x.Data.val_type
+    member x.Accessibility              = x.Data.val_access
+    /// Range of the definition (implementation) of the value, used by Visual Studio 
+    /// Updated by mutation when the implementation is matched against the signature. 
+    member x.DefinitionRange            = x.Data.val_defn_range
+    /// The value of a value or member marked with [<LiteralAttribute>] 
+    member x.LiteralValue               = x.Data.val_const
+    member x.TopValInfo : ValTopReprInfo option = x.Data.val_top_repr_info
+    member x.Id                         = ident(x.LogicalName,x.Range)
+    /// Is this represented as a "top level" static binding (i.e. a static field, static member,
+    /// instance member), rather than an "inner" binding that may result in a closure.
+    ///
+    /// This is implied by IsMemberOrModuleBinding, however not vice versa, for two reasons.
+    /// Some optimizations mutate this value when they decide to change the representation of a 
+    /// binding to be IsCompiledAsTopLevel. Second, even immediately after type checking we expect
+    /// some non-module, non-member bindings to be marked IsCompiledAsTopLevel, e.g. 'y' in 
+    /// 'let x = let y = 1 in y + y' (NOTE: check this, don't take it as gospel)
+    member x.IsCompiledAsTopLevel       = x.TopValInfo.IsSome 
+
+
+    member x.LinkagePartialKey : ValLinkagePartialKey = 
+        assert x.IsCompiledAsTopLevel
+        { LogicalName = x.LogicalName; 
+          MemberParentMangledName = (if x.IsMember then Some x.MemberApparentParent.LogicalName else None);
+          MemberIsOverride = x.IsOverrideOrExplicitImpl;
+          TotalArgCount = if x.IsMember then List.sum x.TopValInfo.Value.AritiesOfArgs else 0 }
+
+    member x.LinkageFullKey : ValLinkageFullKey = 
+        assert x.IsCompiledAsTopLevel
+        ValLinkageFullKey(x.LinkagePartialKey, (if x.IsMember then Some x.Type else None))
+
+
+    /// Is this a member definition or module definition?
+    member x.IsMemberOrModuleBinding    = x.Data.val_flags.IsMemberOrModuleBinding
+    member x.IsExtensionMember          = x.Data.val_flags.IsExtensionMember
+
+    member x.ReflectedDefinition        = x.Data.val_defn
+
+    /// Is this a member, if so some more data about the member.
+    ///
+    /// Note, the value may still be (a) an extension member or (b) and abtract slot without
+    /// a true body. These cases are often causes of bugs in the compiler.
+    member x.MemberInfo                 = x.Data.val_member_info
+
+    /// Is this a member, if so some more data about the member.
+    ///
+    /// Note, the value may still be (a) an extension member or (b) and abtract slot without
+    /// a true body. These cases are often causes of bugs in the compiler.
+    member x.IsMember                   = x.MemberInfo.IsSome
+
+    /// Is this a member, excluding extension members
+    member x.IsIntrinsicMember          = x.IsMember && not x.IsExtensionMember
+
+    /// Is this a value in a module, or an extension member, but excluding compiler generated bindings from optimizations
+    member x.IsModuleBinding            = x.IsMemberOrModuleBinding && not x.IsMember 
+
+    /// Is this something compiled into a module, i.e. a user-defined value, an extension member or a compiler-generated value
+    member x.IsCompiledIntoModule       = x.IsExtensionMember || x.IsModuleBinding
+
+    /// Is this an instance member. 
+    ///
+    /// Note, the value may still be (a) an extension member or (b) and abtract slot without
+    /// a true body. These cases are often causes of bugs in the compiler.
+    member x.IsInstanceMember = x.IsMember && x.MemberInfo.Value.MemberFlags.MemberIsInstance
+
+    /// Is this a 'new' constructor member
+    member x.IsConstructor              =
+        match x.MemberInfo with 
+        | Some(memberInfo) when not x.IsExtensionMember && (memberInfo.MemberFlags.MemberKind = MemberKindConstructor) -> true
+        | _ -> false
+
+    /// Is this a compiler-generated class constructor member
+    member x.IsClassConstructor              =
+        match x.MemberInfo with 
+        | Some(memberInfo) when not x.IsExtensionMember && (memberInfo.MemberFlags.MemberKind = MemberKindClassConstructor) -> true
+        | _ -> false
+
+    /// Was this member declared 'override' or is it an implementation of an interface slot
+    member x.IsOverrideOrExplicitImpl                 =
+        match x.MemberInfo with 
+        | Some(memberInfo) when memberInfo.MemberFlags.MemberIsOverrideOrExplicitImpl -> true
+        | _ -> false
+            
+    /// Was the value declared 'mutable'
+    member x.IsMutable                  = (match x.Data.val_flags.MutabilityInfo with Immutable -> false | Mutable -> true)
+
+    /// Was the value inferred to be a method or function that definitely makes no critical tailcalls?
+    member x.MakesNoCriticalTailcalls = x.Data.val_flags.MakesNoCriticalTailcalls
+    
+    /// Was the value ever referenced?
+    member x.HasBeenReferenced = x.Data.val_flags.HasBeenReferenced
+
+    /// Was the value ever referenced?
+    member x.IsCompiledAsStaticPropertyWithoutField = x.Data.val_flags.IsCompiledAsStaticPropertyWithoutField
+
+    /// Does the value allow the use of an explicit type instantiation (i.e. does it itself have explciti type arguments,
+    /// or does it have a signature?)
+    member x.PermitsExplicitTypeInstantiation = x.Data.val_flags.PermitsExplicitTypeInstantiation
+
+    /// Is this a member generated from the de-sugaring of 'let' function bindings in the implicit class syntax?
+    member x.IsIncrClassGeneratedMember     = x.IsCompilerGenerated && x.Data.val_flags.IsIncrClassSpecialMember
+
+    /// Is this a constructor member generated from the de-sugaring of implicit constructor for a class type?
+    member x.IsIncrClassConstructor = x.IsConstructor && x.Data.val_flags.IsIncrClassSpecialMember
+
+    /// Get the information about the value used during type inference
+    member x.RecursiveValInfo           = x.Data.val_flags.RecursiveValInfo
+
+    /// Is this a 'base' or 'this' value?
+    member x.BaseOrThisInfo             = x.Data.val_flags.BaseOrThisInfo
+
+    //  Was this value declared to be a type function, e.g. "let f<'a> = typeof<'a>"
+    member x.IsTypeFunction             = x.Data.val_flags.IsTypeFunction
+
+    /// Get the inline declaration on the value
+    member x.InlineInfo                 = x.Data.val_flags.InlineInfo
+
+    /// Does the inline declaration for the value indicate that the value must be inlined?
+    member x.MustInline                 = mustinline(x.InlineInfo)
+
+    /// Was the value generated by the compiler?
+    ///
+    /// Note: this is true for the overrides generated by hash/compare augmentations
+    member x.IsCompilerGenerated        = x.Data.val_flags.IsCompilerGenerated
+    
+    /// Get the declared attributes for the value
+    member x.Attribs                    = x.Data.val_attribs
+
+    /// Get the declared documentation for the value
+    member x.XmlDoc                     = x.Data.val_xmldoc
+    
+    ///Get the signature for the value's XML documentation
+    member x.XmlDocSig 
+        with get() = x.Data.val_xmldocsig
+        and set(v) = x.Data.val_xmldocsig <- v
+
+    /// The parent type or module, if any (None for expression bindings and parameters)
+    member x.ActualParent               = x.Data.val_actual_parent
+
+    /// Get the actual parent entity for the value (a module or a type), i.e. the entity under which the
+    /// value will appear in compiled code. For extension members this is the module where the extension member
+    /// is declared.
+    member x.TopValActualParent = 
+        match x.ActualParent  with 
+        | Parent tcref -> tcref
+        | ParentNone -> error(InternalError("TopValActualParent: does not have a parent",x.Range))
+            
+    /// Get the apparent parent entity for a member
+    member x.MemberApparentParent : TyconRef = 
+        match x.MemberInfo with 
+        | Some membInfo -> membInfo.ApparentParent
+        | None -> error(InternalError("MemberApparentParent",x.Range))
+
+    /// Get the apparent parent entity for the value, i.e. the entity under with which the
+    /// value is associated. For extension members this is the nominal type the member extends.
+    /// For other values it is just the actual parent.
+    member x.ApparentParent = 
+        match x.MemberInfo with 
+        | Some membInfo -> Parent(membInfo.ApparentParent)
+        | None -> x.ActualParent
+
+    /// Get the public path to the value, if any? Should be set if and only if
+    /// IsMemberOrModuleBinding is set.
+    //
+    // We use it here:
+    //   - in opt.fs   : when compiling fslib, we bind an entry for the value in a global table (see bind_escaping_local_vspec)
+    //   - in ilxgen.fs: when compiling fslib, we bind an entry for the value in a global table (see bind_escaping_local_vspec)
+    //   - in opt.fs   : (full_display_text_of_vref) for error reporting of non-inlinable values
+    //   - in service.fs (boutput_item_description): to display the full text of a value's binding location
+    //   - in check.fs: as a boolean to detect public values for saving quotations 
+    //   - in ilxgen.fs: as a boolean to detect public values for saving quotations 
+    //   - in MakeExportRemapping, to build non-local references for values
+    member x.PublicPath                 = 
+        match x.ActualParent  with 
+        | Parent eref -> 
+            match eref.PublicPath with 
+            | None -> None
+            | Some p -> Some(ValPubPath(p,x.LinkageFullKey))
+        | ParentNone -> 
+            None
+
+
+    member x.IsDispatchSlot = 
+        match x.MemberInfo with 
+        | Some(membInfo) -> membInfo.MemberFlags.MemberIsDispatchSlot 
+        | _ -> false
+
+    /// Get the type of the value including any generic type parameters
+    member x.TypeScheme = 
+        match x.Type with 
+        | TType_forall(tps,tau) -> tps,tau
+        | ty -> [],ty
+
+    /// Get the type of the value after removing any generic type parameters
+    member x.TauType = 
+        match x.Type with 
+        | TType_forall(_,tau) -> tau
+        | ty -> ty
+
+    /// Get the generic type parameters for the value
+    member x.Typars = 
+        match x.Type with 
+        | TType_forall(tps,_) -> tps
+        | _ -> []
+
+    /// The name of the method. 
+    ///   - If this is a property then this is 'get_Foo' or 'set_Foo'
+    ///   - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot
+    ///   - If this is an extension member then this will be the simple name
+    member x.LogicalName = 
+        match x.MemberInfo with 
+        | None -> x.Data.val_logical_name
+        | Some membInfo -> 
+            match membInfo.ImplementedSlotSigs with 
+            | slotsig :: _ -> slotsig.Name
+            | _ -> x.Data.val_logical_name
+
+    /// The name of the method in compiled code (with some exceptions where ilxgen.fs decides not to use a method impl)
+    ///   - If this is a property then this is 'get_Foo' or 'set_Foo'
+    ///   - If this is an implementation of an abstract slot then this may be a mangled name
+    ///   - If this is an extension member then this will be a mangled name
+    ///   - If this is an operator then this is 'op_Addition'
+    member x.CompiledName =
+        let givenName = 
+            match x.Data.val_compiled_name with 
+            | Some n -> n
+            | None -> x.LogicalName 
+        givenName
+
+    ///   - If this is a property then this is 'Foo' 
+    ///   - If this is an implementation of an abstract slot then this is the name of the property implemented by the abstract slot
+    member x.PropertyName = 
+        let logicalName =  x.LogicalName
+        chopPropertyName logicalName
+
+
+    /// The name of the method. 
+    ///   - If this is a property then this is 'Foo' 
+    ///   - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot
+    ///   - If this is an operator then this is 'op_Addition'
+    member x.CoreDisplayName = 
+        match x.MemberInfo with 
+        | Some membInfo -> 
+            match membInfo.MemberFlags.MemberKind with 
+            | MemberKindClassConstructor 
+            | MemberKindConstructor 
+            | MemberKindMember -> x.LogicalName
+            | MemberKindPropertyGetSet 
+            | MemberKindPropertySet
+            | MemberKindPropertyGet -> x.PropertyName
+        | None -> x.LogicalName
+
+    ///   - If this is a property then this is 'Foo' 
+    ///   - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot
+    ///   - If this is an operator then this is '(+)'
+    member x.DisplayName = 
+        demangleOperatorName x.CoreDisplayName
+
+
+    // OSGN support
+    static member NewUnlinked() : Val  = { Data = Unchecked.defaultof<_> }
+    static member New(data) : Val = { Data = data }
+    member x.Link(tg) = x.Data <- tg
+    member x.IsLinked = match box x.Data with null -> false | _ -> true 
+
+    override x.ToString() = x.LogicalName
+    
+    
+and 
+    [<NoEquality; NoComparison>]
+    [<StructuredFormatDisplay("{val_logical_name}")>]
+    ValData =
+    { val_logical_name: string;
+      val_compiled_name: string option;
+      val_range: range;
+      mutable val_defn_range: range; 
+      mutable val_type: typ;
+      val_stamp: stamp; 
+      /// See vflags section further below for encoding/decodings here 
+      mutable val_flags: ValFlags;
+      mutable val_const: Constant option;
+      
+      /// What is the original, unoptimized, closed-term definition, if any? 
+      /// Used to implement [<ReflectedDefinition>]
+      mutable val_defn: expr option; 
+
+      /// How visible is this? 
+      val_access: Accessibility; 
+
+      /// Is the value actually an instance method/property/event that augments 
+      /// a type, and if so what name does it take in the IL?
+      val_member_info: ValMemberInfo option;
+
+      /// Custom attributes attached to the value. These contain references to other values (i.e. constructors in types). Mutable to fixup  
+      /// these value references after copying a colelction of values. 
+      val_attribs: Attribs;
+
+      /// Top level values have an arity inferred and/or specified
+      /// signatures.  The arity records the number of arguments preferred 
+      /// in each position for a curried functions. The currying is based 
+      /// on the number of lambdas, and in each position the elements are 
+      /// based on attempting to deconstruct the type of the argument as a 
+      /// tuple-type.  The field is mutable because arities for recursive 
+      /// values are only inferred after the r.h.s. is analyzed, but the 
+      /// value itself is created before the r.h.s. is analyzed. 
+      ///
+      /// TLR also sets this for inner bindings that it wants to 
+      /// represent as "top level" bindings.
+     
+      mutable val_top_repr_info: ValTopReprInfo option;
+
+
+      // The fresh temporary should just be created with the right parent
+      mutable val_actual_parent: ParentRef;
+
+      /// XML documentation attached to a value.
+      val_xmldoc : XmlDoc; 
+      
+      /// XML documentation signature for the value
+      mutable val_xmldocsig : string;
+  } 
+
+and 
+    [<NoEquality; NoComparison>]
+    ValMemberInfo = 
+    { /// The parent type. For an extension member this is the type being extended 
+      ApparentParent: TyconRef;  
+
+      /// Gets updated with full slotsig after interface implementation relation is checked 
+      mutable ImplementedSlotSigs: SlotSig list; 
+
+      /// Gets updated with 'true' if an abstract slot is implemented in the file being typechecked.  Internal only. 
+      mutable IsImplemented: bool;                      
+
+      MemberFlags: MemberFlags }
+
+
+and 
+    [<StructuredFormatDisplay("{Display}")>]
+    NonLocalValOrMemberRef = 
+    { /// A reference to the entity containing the value or member. THis will always be a non-local reference
+      EnclosingEntity : EntityRef; 
+      /// The name of the value, or the full signature of the member
+      ItemKey: ValLinkageFullKey; }
+
+    member x.Ccu = x.EnclosingEntity.nlr.Ccu
+    member x.AssemblyName = x.EnclosingEntity.nlr.AssemblyName
+    member x.Display = x.ToString()
+    override x.ToString() = x.EnclosingEntity.nlr.ToString() + "::" + x.ItemKey.PartialKey.LogicalName
+      
+/// A public path records where a construct lives within the global namespace
+/// of a CCU.
+and PublicPath      = 
+    | PubPath of string[] 
+    member x.EnclosingPath = 
+        let (PubPath(pp)) = x 
+        assert (pp.Length >= 1)
+        pp.[0..pp.Length-2]
+
+and ValPublicPath      = 
+    | ValPubPath of PublicPath * ValLinkageFullKey
+
+/// The information ILXGEN needs about the location of an item
+and CompilationPath = 
+    | CompPath of ILScopeRef * (string * ModuleOrNamespaceKind) list
+    member x.ILScopeRef = (let (CompPath(scoref,_)) = x in scoref)
+    member x.AccessPath = (let (CompPath(_,p)) = x in p)
+
+/// Index into the namespace/module structure of a particular CCU 
+and NonLocalEntityRef    = 
+    | NonLocalEntityRef of CcuThunk * string[]
+        
+    member nleref.TryDeref = 
+        let (NonLocalEntityRef(ccu,p)) = nleref 
+        if ccu.IsUnresolvedReference then None else
+        let rec loop (entity:Entity)  i = 
+            if i >= p.Length then Some entity
+            else 
+                let next = entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryFind(p.[i])
+                match next with 
+                | Some res -> loop res (i+1)
+                | None -> None
+
+        match loop ccu.Contents 0 with
+        | Some _ as r -> r
+        | None ->
+            // OK, the lookup failed. Check if we can redirect through a type forwarder on this assembly.
+            // Look for a forwarder for each prefix-path
+            let rec tryForwardPrefixPath i = 
+                if i < p.Length then 
+                    match ccu.TryForward(p.[0..i-1],p.[i]) with
+                    | Some tcref -> 
+                       // OK, found a forwarder, now continue with the lookup to find the nested type
+                       loop tcref.Deref (i+1)
+                    | None -> tryForwardPrefixPath (i+1)
+                else
+                    None
+            tryForwardPrefixPath 0
+        
+    member nleref.Ccu =
+        let (NonLocalEntityRef(ccu,_)) = nleref 
+        ccu
+    member nleref.Path =
+        let (NonLocalEntityRef(_,p)) = nleref 
+        p
+
+    member nleref.DisplayName =
+        String.concat "." nleref.Path
+
+    member nleref.LastItemMangledName = 
+        let p = nleref.Path
+        p.[p.Length-1]
+    member nleref.EnclosingMangledPath =  
+        let p = nleref.Path
+        p.[0..p.Length-2]
+        
+    member nleref.AssemblyName = nleref.Ccu.AssemblyName
+
+    member nleref.Deref = 
+        match nleref.TryDeref with 
+        | Some res -> res
+        | None -> 
+              errorR (InternalUndefinedItemRef (FSComp.SR.tastUndefinedItemRefModuleNamespace, nleref.DisplayName, nleref.AssemblyName, "<some module on this path>")); 
+              raise (KeyNotFoundException())
+        
+    member nleref.TryModuleOrNamespaceType = 
+        nleref.TryDeref |> Option.map (fun v -> v.ModuleOrNamespaceType) 
+
+    member nleref.ModuleOrNamespaceType = 
+        nleref.Deref.ModuleOrNamespaceType
+
+    override x.ToString() = x.DisplayName
+        
+and 
+    [<StructuredFormatDisplay("{LogicalName}")>]
+    [<NoEquality; NoComparison>]
+    EntityRef = 
+    { /// Indicates a reference to something bound in this CCU 
+      mutable binding: Entity 
+      /// Indicates a reference to something bound in another CCU 
+      nlr: NonLocalEntityRef }
+    member x.IsLocalRef = match box x.nlr with null -> true | _ -> false
+    member x.IsResolved = match box x.binding with null -> false | _ -> true
+    member x.PrivateTarget = x.binding
+    member x.ResolvedTarget = x.binding
+
+    member private tcr.Resolve() = 
+        let res = tcr.nlr.TryDeref
+        match res with 
+        | Some r -> 
+             tcr.binding <- r; 
+        | None -> 
+             ()
+
+    // Dereference the TyconRef to a Tycon. Amortize the cost of doing this.
+    // This path should not allocate in the amortized case
+    member tcr.Deref = 
+        match box tcr.binding with 
+        | null ->
+            tcr.Resolve()
+            match box tcr.binding with 
+            | null -> error (InternalUndefinedItemRef (FSComp.SR.tastUndefinedItemRefModuleNamespaceType, tcr.nlr.DisplayName, tcr.nlr.AssemblyName, tcr.nlr.LastItemMangledName))
+            | _ -> tcr.binding
+        | _ -> 
+            tcr.binding
+
+    // Dereference the TyconRef to a Tycon option.
+    member tcr.TryDeref = 
+        match box tcr.binding with 
+        | null -> 
+            tcr.Resolve()
+            match box tcr.binding with 
+            | null -> None
+            | _ -> Some tcr.binding
+
+        | _ -> 
+            Some tcr.binding
+
+    /// Is the destination assembly available?
+    member tcr.CanDeref = tcr.TryDeref.IsSome
+
+    override x.ToString() = 
+       if x.IsLocalRef then 
+           x.ResolvedTarget.DisplayName 
+       else 
+           x.nlr.DisplayName 
+
+
+    member x.CompiledRepresentation = x.Deref.CompiledRepresentation
+    member x.CompiledRepresentationForTyrepNamed = x.Deref.CompiledRepresentationForTyrepNamed
+    member x.LogicalName = x.Deref.LogicalName
+    member x.CompiledName = x.Deref.CompiledName
+    member x.DisplayName = x.Deref.DisplayName
+    member x.DisplayNameWithUnderscoreTypars = x.Deref.DisplayNameWithUnderscoreTypars
+    member x.Range = x.Deref.Range
+    member x.Stamp = x.Deref.Stamp
+    member x.Attribs = x.Deref.Attribs
+    member x.XmlDoc = x.Deref.XmlDoc
+    member x.XmlDocSig = x.Deref.XmlDocSig
+    member x.ModuleOrNamespaceType = x.Deref.ModuleOrNamespaceType
+    
+    member x.DemangledModuleOrNamespaceName = x.Deref.DemangledModuleOrNamespaceName
+
+    member x.TypeContents = x.Deref.TypeContents
+    member x.TypeOrMeasureKind = x.Deref.TypeOrMeasureKind
+    member x.Id = x.Deref.Id
+    member x.TypeReprInfo = x.Deref.TypeReprInfo
+    member x.ExceptionInfo = x.Deref.ExceptionInfo
+    member x.IsExceptionDecl = x.Deref.IsExceptionDecl
+    
+    member x.Typars(m) = x.Deref.Typars(m)
+    member x.TyparsNoRange = x.Deref.TyparsNoRange
+    member x.TypeAbbrev = x.Deref.TypeAbbrev
+    member x.IsTypeAbbrev = x.Deref.IsTypeAbbrev
+    member x.TypeReprAccessibility = x.Deref.TypeReprAccessibility
+    member x.CompiledReprCache = x.Deref.CompiledReprCache
+    member x.PublicPath : PublicPath option = x.Deref.PublicPath
+    member x.Accessibility = x.Deref.Accessibility
+    member x.IsPrefixDisplay = x.Deref.IsPrefixDisplay
+    member x.IsModuleOrNamespace  = x.Deref.IsModuleOrNamespace
+    member x.IsNamespace          = x.Deref.IsNamespace
+    member x.IsModule             = x.Deref.IsModule
+    member x.CompilationPathOpt   = x.Deref.CompilationPathOpt
+    member x.CompilationPath      = x.Deref.CompilationPath
+    member x.AllFieldTable        = x.Deref.AllFieldTable
+    member x.AllFieldsArray       = x.Deref.AllFieldsArray
+    member x.AllFieldsAsList = x.Deref.AllFieldsAsList
+    member x.TrueFieldsAsList = x.Deref.TrueFieldsAsList
+    member x.TrueInstanceFieldsAsList = x.Deref.TrueInstanceFieldsAsList
+    member x.AllInstanceFieldsAsList = x.Deref.AllInstanceFieldsAsList
+    member x.GetFieldByIndex(n)        = x.Deref.GetFieldByIndex(n)
+    member x.GetFieldByName(n)         = x.Deref.GetFieldByName(n)
+    member x.UnionTypeInfo             = x.Deref.UnionTypeInfo
+    member x.UnionCasesArray           = x.Deref.UnionCasesArray
+    member x.UnionCasesAsList     = x.Deref.UnionCasesAsList
+    member x.GetUnionCaseByName(n)     = x.Deref.GetUnionCaseByName(n)
+    member x.FSharpObjectModelTypeInfo = x.Deref.FSharpObjectModelTypeInfo
+    member x.InterfacesOfFSharpTycon = x.Deref.InterfacesOfFSharpTycon
+    member x.InterfaceTypesOfFSharpTycon = x.Deref.InterfaceTypesOfFSharpTycon
+    member x.MembersOfFSharpTyconSorted = x.Deref.MembersOfFSharpTyconSorted
+    member x.MembersOfFSharpTyconByName = x.Deref.MembersOfFSharpTyconByName
+    member x.IsStructOrEnumTycon             = x.Deref.IsStructOrEnumTycon
+    member x.IsAsmReprTycon            = x.Deref.IsAsmReprTycon
+    member x.IsMeasureableReprTycon    = x.Deref.IsMeasureableReprTycon
+    
+
+    member x.GeneratedHashAndEqualsWithComparerValues = x.Deref.GeneratedHashAndEqualsWithComparerValues
+    member x.GeneratedCompareToWithComparerValues = x.Deref.GeneratedCompareToWithComparerValues
+    member x.GeneratedCompareToValues = x.Deref.GeneratedCompareToValues
+    member x.GeneratedHashAndEqualsValues = x.Deref.GeneratedHashAndEqualsValues
+    
+    member x.IsILTycon                = x.Deref.IsILTycon
+    member x.ILTyconInfo              = x.Deref.ILTyconInfo
+    member x.ILTyconRawMetadata       = x.Deref.ILTyconRawMetadata
+    member x.IsUnionTycon             = x.Deref.IsUnionTycon
+    member x.UnionInfo                = x.Deref.UnionInfo
+    member x.IsRecordTycon            = x.Deref.IsRecordTycon
+    member x.IsFSharpObjectModelTycon = x.Deref.IsFSharpObjectModelTycon
+    member x.IsHiddenReprTycon        = x.Deref.IsHiddenReprTycon
+
+    member x.IsFSharpInterfaceTycon   = x.Deref.IsFSharpInterfaceTycon
+    member x.IsFSharpDelegateTycon    = x.Deref.IsFSharpDelegateTycon
+    member x.IsFSharpEnumTycon        = x.Deref.IsFSharpEnumTycon
+    member x.IsILEnumTycon            = x.Deref.IsILEnumTycon
+    member x.IsEnumTycon              = x.Deref.IsEnumTycon
+
+    member x.IsFSharpStructOrEnumTycon      = x.Deref.IsFSharpStructOrEnumTycon
+
+    member x.IsILStructTycon          = x.Deref.IsILStructTycon
+    member x.PreEstablishedHasDefaultConstructor = x.Deref.PreEstablishedHasDefaultConstructor
+    member x.HasSelfReferentialConstructor = x.Deref.HasSelfReferentialConstructor
+
+
+/// note: ModuleOrNamespaceRef and TyconRef are type equivalent 
+and ModuleOrNamespaceRef       = EntityRef
+and TyconRef       = EntityRef
+
+/// References are either local or nonlocal
+and 
+    [<NoEquality; NoComparison>]
+    [<StructuredFormatDisplay("{LogicalName}")>]
+    ValRef = 
+    { /// Indicates a reference to something bound in this CCU 
+      mutable binding: Val 
+      /// Indicates a reference to something bound in another CCU 
+      nlr: NonLocalValOrMemberRef }
+    member x.IsLocalRef = match box x.nlr with null -> true | _ -> false
+    member x.IsResolved = match box x.binding with null -> false | _ -> true
+    member x.PrivateTarget = x.binding
+    member x.ResolvedTarget = x.binding
+
+    member vr.Deref = 
+        match box vr.binding with 
+        | null ->
+            let res = 
+                let nlr = vr.nlr 
+                let e =  nlr.EnclosingEntity.Deref 
+                let possible = e.ModuleOrNamespaceType.TryLinkVal(nlr.EnclosingEntity.nlr.Ccu, nlr.ItemKey)
+                match possible with 
+                | None -> error (InternalUndefinedItemRef (FSComp.SR.tastUndefinedItemRefVal, e.DisplayName, nlr.AssemblyName, sprintf "%+A" nlr.ItemKey.PartialKey))
+                | Some h -> h
+            vr.binding <- res; 
+            res 
+        | _ -> vr.binding
+
+    member vr.TryDeref = 
+        match box vr.binding with 
+        | null -> 
+            let resOpt = 
+                vr.nlr.EnclosingEntity.TryDeref |> Option.bind (fun e -> 
+                    e.ModuleOrNamespaceType.TryLinkVal(vr.nlr.EnclosingEntity.nlr.Ccu, vr.nlr.ItemKey))
+            match resOpt with 
+            | None -> ()
+            | Some res -> 
+                vr.binding <- res; 
+            resOpt
+        | _ -> 
+            Some vr.binding
+
+    member x.Type                       = x.Deref.Type
+    member x.TypeScheme                 = x.Deref.TypeScheme
+    member x.TauType                    = x.Deref.TauType
+    member x.Typars                     = x.Deref.Typars
+    member x.LogicalName                = x.Deref.LogicalName
+    member x.DisplayName                = x.Deref.DisplayName
+    member x.CoreDisplayName            = x.Deref.CoreDisplayName
+    member x.Range                      = x.Deref.Range
+
+    member x.Accessibility              = x.Deref.Accessibility
+    member x.ActualParent               = x.Deref.ActualParent
+    member x.ApparentParent             = x.Deref.ApparentParent
+    member x.DefinitionRange            = x.Deref.DefinitionRange
+    member x.LiteralValue               = x.Deref.LiteralValue
+    member x.Id                         = x.Deref.Id
+    member x.PropertyName               = x.Deref.PropertyName
+    member x.Stamp                      = x.Deref.Stamp
+    member x.IsCompiledAsTopLevel       = x.Deref.IsCompiledAsTopLevel
+    member x.IsDispatchSlot             = x.Deref.IsDispatchSlot
+    member x.CompiledName         = x.Deref.CompiledName
+
+    member x.PublicPath                 = x.Deref.PublicPath
+    member x.ReflectedDefinition        = x.Deref.ReflectedDefinition
+    member x.IsConstructor              = x.Deref.IsConstructor
+    member x.IsOverrideOrExplicitImpl   = x.Deref.IsOverrideOrExplicitImpl
+    member x.MemberInfo                 = x.Deref.MemberInfo
+    member x.IsMember                   = x.Deref.IsMember
+    member x.IsModuleBinding            = x.Deref.IsModuleBinding
+    member x.IsInstanceMember           = x.Deref.IsInstanceMember
+
+    member x.IsMutable                  = x.Deref.IsMutable
+    member x.PermitsExplicitTypeInstantiation  = x.Deref.PermitsExplicitTypeInstantiation
+    member x.MakesNoCriticalTailcalls  = x.Deref.MakesNoCriticalTailcalls
+    member x.IsMemberOrModuleBinding    = x.Deref.IsMemberOrModuleBinding
+    member x.IsExtensionMember          = x.Deref.IsExtensionMember
+    member x.IsIncrClassConstructor = x.Deref.IsIncrClassConstructor
+    member x.IsIncrClassGeneratedMember = x.Deref.IsIncrClassGeneratedMember
+    member x.RecursiveValInfo           = x.Deref.RecursiveValInfo
+    member x.BaseOrThisInfo             = x.Deref.BaseOrThisInfo
+    member x.IsTypeFunction             = x.Deref.IsTypeFunction
+    member x.TopValInfo                  = x.Deref.TopValInfo
+    member x.InlineInfo                 = x.Deref.InlineInfo
+    member x.MustInline                 = x.Deref.MustInline
+    member x.IsCompilerGenerated        = x.Deref.IsCompilerGenerated
+    member x.Attribs                    = x.Deref.Attribs
+    member x.XmlDoc                     = x.Deref.XmlDoc
+    member x.XmlDocSig                  = x.Deref.XmlDocSig
+    member x.TopValActualParent         = x.Deref.TopValActualParent
+    member x.MemberApparentParent       = x.Deref.MemberApparentParent
+    override x.ToString() = 
+       if x.IsLocalRef then x.ResolvedTarget.DisplayName 
+       else x.nlr.ToString()
+
+and UnionCaseRef = 
+    | UCRef of TyconRef * string
+    member x.TyconRef = let (UCRef(tcref,_)) = x in tcref
+    member x.CaseName = let (UCRef(_,nm)) = x in nm
+    member x.Tycon = x.TyconRef.Deref
+
+and RecdFieldRef = 
+    | RFRef of TyconRef * string
+    member x.TyconRef = let (RFRef(tcref,_)) = x in tcref
+    member x.FieldName = let (RFRef(_,id)) = x in id
+    member x.Tycon = x.TyconRef.Deref
+
+and 
+  /// The algebra of types
+    [<NoEquality; NoComparison>]
+    typ =
+    /// Indicates the type is a universal type, only used for types of values, members and record fields 
+    | TType_forall of Typars * typ
+    /// Indicates the type is a type application 
+    | TType_app of TyconRef * tinst
+    /// Indicates the type is a tuple type 
+    | TType_tuple of typ list
+    /// Indicates the type is a function type 
+    | TType_fun of  typ * typ
+    /// Indicates the type is a non-F#-visible type representing a "proof" that a union value belongs to a particular union case
+    /// These types are not user-visible and will never appear as an inferred type. They are the types given to
+    /// the temporaries arising out of pattern matching on union values.
+    | TType_ucase of  UnionCaseRef * tinst
+    /// Indicates the type is a variable type, whether declared, generalized or an inference type parameter  
+    | TType_var of Typar 
+    | TType_measure of MeasureExpr
+
+and tinst = typ list 
+
+and MeasureExpr = 
+    | MeasureVar of Typar
+    | MeasureCon of TyconRef
+    | MeasureProd of MeasureExpr*MeasureExpr
+    | MeasureInv of MeasureExpr
+    | MeasureOne
+
+and 
+    [<NoEquality; NoComparison>]
+    CcuData = 
+    { /// Holds the filename for the DLL, if any 
+      ccu_filename: string option; 
+      
+      /// Holds the data indicating how this assembly/module is referenced from the code being compiled. 
+      ccu_scoref: ILScopeRef;
+      
+      /// A unique stamp for this DLL 
+      ccu_stamp: stamp;
+      
+      /// The fully qualified assembly reference string to refer to this assembly. This is persisted in quotations 
+      ccu_qname: string option; 
+      
+      /// A hint as to where does the code for the CCU live (e.g what was the tcConfig.implicitIncludeDir at compilation time for this DLL?) 
+      ccu_code_dir: string; 
+      
+      /// Indicates that this DLL was compiled using the F# compiler 
+      ccu_fsharp: bool; 
+      
+      /// Indicates that this DLL uses quotation literals somewhere. This is used to implement a restriction on static linking
+      mutable ccu_usesQuotations : bool;
+      
+      /// A handle to the full specification of the contents of the module contained in this ccu
+      // NOTE: may contain transient state during typechecking 
+      mutable ccu_contents: ModuleOrNamespace;
+      
+      /// A helper function used to link method signatures using type equality. This is effectively a forward call to the type equality 
+      /// logic in tastops.fs
+      mutable ccu_memberSignatureEquality : (typ -> typ -> bool) 
+      
+      ccu_forwarders : CcuTypeForwarderTable }
+
+and CcuTypeForwarderTable = Lazy<Map<string[] * string, EntityRef>>
+
+and CcuReference =  string // ILAssemblyRef
+
+/// A relinkable handle to the contents of a compilation unit. Relinking is performed by mutation.
+and CcuThunk = 
+    { mutable target: CcuData;
+      mutable orphanfixup : bool;
+      name: CcuReference  }
+      
+
+    member ccu.Deref = 
+        if isNull ccu.target || ccu.orphanfixup then 
+            raise(UnresolvedReferenceNoRange ccu.name)
+        ccu.target
+   
+    member ccu.IsUnresolvedReference = (isNull ccu.target || ccu.orphanfixup)
+
+    /// Ensure the ccu is derefable in advance. Supply a path to attach to any resulting error message.
+    member ccu.EnsureDerefable(requiringPath:string[]) = 
+        // ccu.orphanfixup is true when a reference is missing in the transitive closure of static references that
+        // may potentially be required for the metadata of referenced DLLs. It is set to true if the "loader"
+        // used in the F# metadata-deserializer or the .NET metadata reader returns a failing value (e.g. None).
+        // Note: When used from Visual Studio, the loader will not automatically chase down transitively referenced DLLs - they
+        // must be in the explicit references in the project.
+        if ccu.IsUnresolvedReference then 
+            let path = System.String.Join(".", requiringPath)
+            raise(UnresolvedPathReferenceNoRange(ccu.name,path))
+            
+    member ccu.UsesQuotations with get() = ccu.Deref.ccu_usesQuotations and set(v) = ccu.Deref.ccu_usesQuotations <- v
+    member ccu.AssemblyName = ccu.name
+    member ccu.ILScopeRef = ccu.Deref.ccu_scoref
+    member ccu.Stamp = ccu.Deref.ccu_stamp
+    member ccu.FileName = ccu.Deref.ccu_filename
+    member ccu.QualifiedName = ccu.Deref.ccu_qname
+    member ccu.SourceCodeDirectory = ccu.Deref.ccu_code_dir
+    member ccu.IsFSharp = ccu.Deref.ccu_fsharp
+    member ccu.Contents = ccu.Deref.ccu_contents
+    member ccu.TypeForwarders : Map<string[] * string, EntityRef>  = ccu.Deref.ccu_forwarders.Force()
+
+    static member Create(nm,x) = 
+        { target = x; 
+          orphanfixup = false;
+          name = nm;  }
+
+    static member CreateDelayed(nm) = 
+        { target = Unchecked.defaultof<_>; 
+          orphanfixup = false;
+          name = nm;  }
+
+    member x.Fixup(avail:CcuThunk) = 
+        match box x.target with
+        | null -> 
+            assert (avail.AssemblyName = x.AssemblyName)
+            x.target <- 
+               (match box avail.target with
+                | null -> error(Failure("internal error: ccu thunk '"+avail.name+"' not fixed up!"))
+                | _ -> avail.target)
+        | _ -> errorR(Failure("internal error: the ccu thunk for assembly "+x.AssemblyName+" not delayed!"));
+        
+    member x.FixupOrphaned() = 
+        match box x.target with
+        | null -> x.orphanfixup<-true
+        | _ -> errorR(Failure("internal error: the ccu thunk for assembly "+x.AssemblyName+" not delayed!"));
+            
+    member ccu.TryForward(nlpath:string[],item:string) : EntityRef option  = 
+        if ccu.IsUnresolvedReference then None else
+        ccu.TypeForwarders.TryFind(nlpath,item) 
+        //printfn "trying to forward %A::%s from ccu '%s', res = '%A'" p n ccu.AssemblyName res.IsSome
+
+    member ccu.MemberSignatureEquality(ty1:typ, ty2:typ) = 
+        ccu.Deref.ccu_memberSignatureEquality ty1 ty2
+    
+
+    override ccu.ToString() = ccu.AssemblyName
+
+/// The result of attempting to resolve an assembly name to a full ccu.
+/// UnresolvedCcu will contain the name of the assembly that could not be resolved.
+and CcuResolutionResult =
+    | ResolvedCcu of CcuThunk
+    | UnresolvedCcu of string
+
+and PickledModuleInfo =
+  { mspec: ModuleOrNamespace;
+    compileTimeWorkingDir: string;
+    usesQuotations : bool }
+
+//---------------------------------------------------------------------------
+// Attributes
+//---------------------------------------------------------------------------
+
+and Attribs = Attrib list 
+
+and AttribKind = 
+  /// Indicates an attribute refers to a type defined in an imported .NET assembly 
+  | ILAttrib of ILMethodRef 
+  /// Indicates an attribute refers to a type defined in an imported F# assembly 
+  | FSAttrib of ValRef
+
+/// Attrib(kind,unnamedArgs,propVal,appliedToAGetterOrSetter,range)
+and Attrib = 
+  | Attrib of TyconRef * AttribKind * AttribExpr list * AttribNamedArg list * bool * range
+
+/// We keep both source expression and evaluated expression around to help intellisense and signature printing
+and AttribExpr = AttribExpr of (* source *) expr * (* evaluated *) expr 
+
+/// AttribNamedArg(name,type,isField,value)
+and AttribNamedArg = AttribNamedArg of (string*typ*bool*AttribExpr)
+
+/// Constants in expressions
+and Constant = 
+  | TConst_bool       of bool
+  | TConst_sbyte       of sbyte
+  | TConst_byte      of byte
+  | TConst_int16      of int16
+  | TConst_uint16     of uint16
+  | TConst_int32      of int32
+  | TConst_uint32     of uint32
+  | TConst_int64      of int64
+  | TConst_uint64     of uint64
+  | TConst_nativeint  of int64
+  | TConst_unativeint of uint64
+  | TConst_float32    of single
+  | TConst_float      of double
+  | TConst_char       of char
+  | TConst_string     of string // in unicode 
+  | TConst_decimal    of System.Decimal 
+  | TConst_unit
+  | TConst_zero // null/zero-bit-pattern 
+  
+
+/// Decision trees. Pattern matching has been compiled down to
+/// a decision tree by this point.  The right-hand-sides (actions) of
+/// the decision tree are labelled by integers that are unique for that
+/// particular tree.
+and 
+    [<NoEquality; NoComparison>]
+    DecisionTree = 
+
+    /// Indicates a decision point in a decision tree. 
+    | TDSwitch  of 
+          (* input: *) expr * 
+          (* cases: *) DecisionTreeCase list * 
+          (* default: *) DecisionTree option * range
+
+    /// Indicates the decision tree has terminated with success, calling the given target with the given parameters 
+    | TDSuccess of 
+          (* results: *) FlatExprs * 
+          (* target: *) int  
+
+    /// Bind the given value throught the remaining cases of the dtree. 
+    | TDBind of 
+          (* binding: *) Binding * 
+          (* body: *) DecisionTree
+
+and DecisionTreeCase = 
+    | TCase of DecisionTreeDiscriminator * DecisionTree
+
+and 
+    [<NoEquality; NoComparison>]
+    DecisionTreeDiscriminator = 
+    /// Test if the input to a decision tree matches the given constructor 
+    | TTest_unionconstr of (UnionCaseRef * tinst) 
+
+    /// Test if the input to a decision tree is an array of the given length 
+    | TTest_array_length of int * typ  
+
+    /// Test if the input to a decision tree is the given constant value 
+    | TTest_const of Constant
+
+    /// Test if the input to a decision tree is null 
+    | TTest_isnull 
+
+    /// Test if the input to a decision tree is an instance of the given type 
+    | TTest_isinst of (* source: *) typ * (* target: *) typ
+
+    /// Run the active pattern and bind a successful result to the (one) variable in the remaining tree 
+    | TTest_query of expr * typ list * (ValRef * tinst) option * int * ActivePatternInfo
+
+
+/// A target of a decision tree. Can be thought of as a little function, though is compiled as a local block. 
+and DecisionTreeTarget = 
+    | TTarget of FlatVals * expr * SequencePointInfoForTarget
+
+and Bindings = FlatList<Binding>
+
+and Binding = 
+    | TBind of Val * expr * SequencePointInfoForBinding
+    member x.Var               = (let (TBind(v,_,_)) = x in v)
+    member x.Expr              = (let (TBind(_,e,_)) = x in e)
+    member x.SequencePointInfo = (let (TBind(_,_,sp)) = x in sp)
+    
+// ActivePatternElemRef: active pattern element (deconstruction case), e.g. 'JNil' or 'JCons'. 
+// Integer indicates which choice in the target set is being selected by this item. 
+and ActivePatternElemRef = 
+    | APElemRef of ActivePatternInfo * ValRef * int 
+
+    member x.IsTotalActivePattern = (let (APElemRef(total,_,_)) = x in total)
+    member x.ActivePatternVal = (let (APElemRef(_,vref,_)) = x in vref)
+    member x.CaseIndex = (let (APElemRef(_,_,n)) = x in n)
+
+and ValTopReprInfo  = 
+    | TopValInfo  of (* numTypars: *) TopTyparInfo list * (* args: *) TopArgInfo list list * (* result: *) TopArgInfo 
+    member x.ArgInfos       = (let (TopValInfo(_,args,_)) = x in args)
+    member x.NumCurriedArgs = (let (TopValInfo(_,args,_)) = x in args.Length)
+    member x.NumTypars      = (let (TopValInfo(n,_,_)) = x in n.Length)
+    member x.AritiesOfArgs  = (let (TopValInfo(_,args,_)) = x in List.map List.length args)
+    member x.KindsOfTypars  = (let (TopValInfo(n,_,_)) = x in n |> List.map (fun (TopTyparInfo(_,k)) -> k))
+
+/// The extra metadata stored about typars for top-level definitions. Any information here is propagated from signature through
+/// to the compiled code.
+and 
+    [<RequireQualifiedAccess>]
+    TopArgInfo = 
+    { mutable Attribs : Attribs 
+      mutable Name : ident option  }
+
+/// The extra metadata stored about typars for top-level definitions. Any information here is propagated from signature through
+/// to the compiled code.
+and TopTyparInfo = TopTyparInfo of ident * TyparKind
+
+and Typars = Typar list
+ 
+and Exprs = expr list
+and FlatExprs = FlatList<expr>
+and Vals = Val list
+and FlatVals = FlatList<Val>
+
+/// The big type of expressions.  
+and expr =
+    /// A constant expression. 
+    | TExpr_const of Constant * range * typ
+
+    /// Reference a value. The flag is only relevant if the value is an object model member 
+    /// and indicates base calls and special uses of object constructors. 
+    | TExpr_val of ValRef * ValUseFlag * range
+
+    /// Sequence expressions, used for "a;b", "let a = e in b;a" and "a then b" (the last an OO constructor). 
+    | TExpr_seq of expr * expr * SequentialOpKind * SequencePointInfoForSeq * range
+
+    /// Lambda expressions. 
+    
+    // Why multiple vspecs? A TExpr_lambda taking multiple arguments really accepts a tuple. 
+    // But it is in a convenient form to be compile accepting multiple 
+    // arguments, e.g. if compiled as a toplevel static method. 
+
+    | TExpr_lambda of uniq * Val option * Val option * Val list * expr * range * typ * SkipFreeVarsCache
+
+    // Type lambdas.  These are used for the r.h.s. of polymorphic 'let' bindings and 
+    // for expressions that implement first-class polymorphic values. 
+    | TExpr_tlambda of uniq * Typars * expr * range * typ  * SkipFreeVarsCache
+
+    /// Applications combine type and term applications, and are normalized so 
+    /// that sequential applications are combined, so "(f x y)" becomes "f [[x];[y]]". 
+    /// The type attached to the function is the formal function type, used to ensure we don't build application 
+    /// nodes that over-apply when instantiating at function types. 
+    | TExpr_app of expr * typ * tinst * Exprs * range
+
+    /// Bind a recursive set of values. 
+    | TExpr_letrec of Bindings * expr * range * FreeVarsCache
+
+    /// Bind a value. 
+    | TExpr_let of Binding * expr * range * FreeVarsCache
+
+    // Object expressions: A closure that implements an interface or a base type. 
+    // The base object type might be a delegate type. 
+    | TExpr_obj of 
+         (* unique *)           uniq * 
+         (* object typ *)       typ *                                         (* <-- NOTE: specifies type parameters for base type *)
+         (* base val *)         Val option * 
+         (* ctor call *)        expr * 
+         (* overrides *)        ObjExprMethod list * 
+         (* extra interfaces *) (typ * ObjExprMethod list) list *                   
+                                range * 
+                                SkipFreeVarsCache
+
+    // Pattern matching. 
+
+    /// Matches are a more complicated form of "let" with multiple possible destinations 
+    /// and possibly multiple ways to get to each destination.  
+    /// The first mark is that of the expression being matched, which is used 
+    /// as the mark for all the decision making and binding that happens during the match. 
+    | TExpr_match of SequencePointInfoForBinding * range * DecisionTree * DecisionTreeTarget array * range * typ * SkipFreeVarsCache
+
+    /// If we statically know some infomation then in many cases we can use a more optimized expression 
+    /// This is primarily used by terms in the standard library, particularly those implementing overloaded 
+    /// operators. 
+    | TExpr_static_optimization of StaticOptimization list * expr * expr * range
+
+    /// An intrinsic applied to some (strictly evaluated) arguments 
+    /// A few of intrinsics (TOp_try, TOp_while, TOp_for) expect arguments kept in a normal form involving lambdas 
+    | TExpr_op of ExprOpSpec * tinst * Exprs * range
+
+    // Indicates the expression is a quoted expression tree. 
+    | TExpr_quote of expr * (typ list * Exprs * ExprData) option ref * range * typ  
+    
+    /// Typechecking residue: Indicates a free choice of typars that arises due to 
+    /// minimization of polymorphism at let-rec bindings.  These are 
+    /// resolved to a concrete instantiation on subsequent rewrites. 
+    | TExpr_tchoose of Typars * expr * range
+
+    /// Typechecking residue: A TExpr_link occurs for every use of a recursively bound variable. While type-checking 
+    /// the recursive bindings a dummy expression is stored in the mutable reference cell. 
+    /// After type checking the bindings this is replaced by a use of the variable, perhaps at an 
+    /// appropriate type instantiation. These are immediately eliminated on subsequent rewrites. 
+    | TExpr_link of expr ref
+
+/// A type for a module-or-namespace-fragment and the actual definition of the module-or-namespace-fragment
+and ModuleOrNamespaceExprWithSig = 
+    | TMTyped of 
+         /// The module_typ is a binder. However it is not used in the ModuleOrNamespaceExpr: it is only referenced from the 'outside' 
+         ModuleOrNamespaceType 
+         * ModuleOrNamespaceExpr
+         * range
+
+/// The contents of a module-or-namespace-fragment definition 
+and ModuleOrNamespaceExpr = 
+    /// Indicates the module is a module with a signature 
+    | TMAbstract of ModuleOrNamespaceExprWithSig
+    /// Indicates the module fragment is made of several module fragments in succession 
+    | TMDefs     of ModuleOrNamespaceExpr list  
+    /// Indicates the module fragment is a 'let' definition 
+    | TMDefLet   of Binding * range
+    /// Indicates the module fragment is an evaluation of expression for side-effects
+    | TMDefDo   of expr * range
+    /// Indicates the module fragment is a 'rec' definition of types, values and modules
+    | TMDefRec   of Tycon list * Bindings * ModuleOrNamespaceBinding list * range
+
+/// A named module-or-namespace-fragment definition 
+and ModuleOrNamespaceBinding = 
+    | TMBind of 
+         /// This ModuleOrNamespace that represents the compilation of a module as a class. 
+         /// The same set of tycons etc. are bound in the ModuleOrNamespace as in the ModuleOrNamespaceExpr
+         ModuleOrNamespace * 
+         /// This is the body of the module/namespace 
+         ModuleOrNamespaceExpr
+
+
+and RecordConstructionInfo = 
+   /// We're in a constructor. The purpose of the record expression is to 
+   /// fill in the fields of a pre-created but uninitialized object 
+   | RecdExprIsObjInit
+   /// Normal record construction 
+   | RecdExpr
+   
+and 
+    [<NoEquality; NoComparison>]
+    ExprOpSpec =
+    /// An operation representing the creation of a union value of the particular union case
+    | TOp_ucase of UnionCaseRef 
+    /// An operation representing the creation of an exception value using an F# exception declaration
+    | TOp_exnconstr of TyconRef
+    /// An operation representing the creation of a tuple value
+    | TOp_tuple 
+    /// An operation representing the creation of an array value
+    | TOp_array
+    /// Constant bytes, but a new mutable blob is generated each time the construct is executed 
+    | TOp_bytes of byte[] 
+    | TOp_uint16s of uint16[] 
+    /// An operation representing a lambda-encoded while loop. The special while loop marker is used to mark compilations of 'foreach' expressions
+    | TOp_while of SequencePointInfoForWhileLoop * SpecialWhileLoopMarker
+    /// An operation representing a lambda-encoded for loop
+    | TOp_for of SequencePointInfoForForLoop * ForLoopStyle (* count up or down? *)
+    /// An operation representing a lambda-encoded try/catch
+    | TOp_try_catch of SequencePointInfoForTry * SequencePointInfoForWith
+    /// An operation representing a lambda-encoded try/finally
+    | TOp_try_finally of SequencePointInfoForTry * SequencePointInfoForFinally
+
+    /// Construct a record or object-model value. The ValRef is for self-referential class constructors, otherwise 
+    /// it indicates that we're in a constructor and the purpose of the expression is to 
+    /// fill in the fields of a pre-created but uninitialized object, and to assign the initialized 
+    /// version of the object into the optional mutable cell pointed to be the given value. 
+    | TOp_recd of RecordConstructionInfo * TyconRef
+    
+    /// An operation representing setting a record field
+    | TOp_rfield_set of RecdFieldRef 
+    /// An operation representing getting a record field
+    | TOp_rfield_get of RecdFieldRef 
+    /// An operation representing getting the address of a record field
+    | TOp_field_get_addr of RecdFieldRef       
+    /// An operation representing getting an integer tag for a union value representing the union case number
+    | TOp_ucase_tag_get of TyconRef 
+    /// An operation representing a coercion that proves a union value is of a particular union case. THis is not a test, its
+    /// simply added proof to enable us to generate verifiable code for field access on union types
+    | TOp_ucase_proof of UnionCaseRef
+    /// An operation representing a field-get from a union value, where that value has been proven to be of the corresponding union case.
+    | TOp_ucase_field_get of UnionCaseRef * int 
+    /// An operation representing a field-get from a union value. THe value is not assumed to have been proven to be of the corresponding union case.
+    | TOp_ucase_field_set of  UnionCaseRef * int
+    /// An operation representing a field-get from an F# exception value.
+    | TOp_exnconstr_field_get of TyconRef * int 
+    /// An operation representing a field-set on an F# exception value.
+    | TOp_exnconstr_field_set of TyconRef * int 
+    /// An operation representing a field-get from an F# tuple value.
+    | TOp_tuple_field_get of int 
+    /// IL assembly code - type list are the types pushed on the stack 
+    | TOp_asm of ILInstr list * typ list 
+    /// generate a ldflda on an 'a ref. 
+    | TOp_get_ref_lval 
+    /// Conversion node, compiled via type-directed translation or to box/unbox 
+    | TOp_coerce 
+    /// Represents a "rethrow" operation. May not be rebound, or used outside of try-finally, expecting a unit argument 
+    | TOp_reraise 
+    | TOp_return
+
+    /// Pseudo method calls. This is used for overloaded operations like op_Addition. 
+    | TOp_trait_call of TraitConstraintInfo  
+
+    /// Operation nodes represnting C-style operations on byrefs and mutable vals (l-values) 
+    | TOp_lval_op of LValueOperation * ValRef 
+
+    /// IL method calls 
+    | TOp_ilcall of 
+       bool * // virtual call? 
+       bool * // protected? 
+       bool * // is the object a value type? 
+       bool * // newobj call? 
+       ValUseFlag * // isSuperInit call? 
+       bool * // property? used for reflection 
+       bool * // DllImport? if so don't tailcall 
+       ILMethodRef * 
+       typ list * // instantiation of the enclosing type
+       typ list * // instantiation of the method
+       typ list   // the types of pushed values if any 
+
+// If this is Some(ty) then it indicates that a .NET 2.0 constrained call is required, witht he given type as the
+// static type of the object argument.
+and ConstrainedCallInfo = typ option
+
+and SpecialWhileLoopMarker = 
+    | NoSpecialWhileLoopMarker
+    | WhileLoopForCompiledForEachExprMarker  // marks the compiled form of a 'for ... in ... do ' expression
+    
+and ForLoopStyle = 
+    /// Evaluate start and end once, loop up
+    | FSharpForLoopUp 
+    /// Evaluate start and end once, loop down
+    | FSharpForLoopDown 
+    /// Evaluate start once and end multiple times, loop up
+    | CSharpForLoopUp
+
+and LValueOperation = 
+    /// In C syntax this is: &localv            
+    | LGetAddr      
+    /// In C syntax this is: *localv_ptr        
+    | LByrefGet     
+    /// In C syntax this is:  localv = e     , note == *(&localv) = e == LGetAddr; LByrefSet
+    | LSet          
+    /// In C syntax this is: *localv_ptr = e   
+    | LByrefSet     
+
+and SequentialOpKind = 
+    /// a ; b 
+    | NormalSeq 
+    /// let res = a in b;res 
+    | ThenDoSeq     
+
+and ValUseFlag =
+    /// Indicates a use of a value represents a call to a method that may require
+    /// a .NET 2.0 constrained call. A constrained call is only used for calls where 
+    // the object argument is a value type or generic type, and the call is to a method
+    //  on System.Object, System.ValueType, System.Enum or an interface methods.
+    | PossibleConstrainedCall of typ
+    /// A normal use of a value
+    | NormalValUse
+    /// A call to a constructor, e.g. 'inherit C()'
+    | CtorValUsedAsSuperInit
+    /// A call to a constructor, e.g. 'new C() = new C(3)'
+    | CtorValUsedAsSelfInit
+    /// A call to a base method, e.g. 'base.OnPaint(args)'
+    | VSlotDirectCall
+  
+and StaticOptimization = 
+    | TTyconEqualsTycon of typ * typ
+    | TTyconIsStruct of typ 
+  
+/// A representation of a method in an object expression. 
+/// Note: Methods associated with types are represented as val declarations
+/// Note: We should probably use val_specs for object expressions, as then the treatment of members 
+/// in object expressions could be more unified with the treatment of members in types 
+and ObjExprMethod = 
+    | TObjExprMethod of SlotSig * Attribs * Typars * Val list list * expr * range
+    member x.Id = let (TObjExprMethod(slotsig,_,_,_,_,m)) = x in mksyn_id m slotsig.Name
+
+and SlotSig = 
+    | TSlotSig of string * typ * Typars * Typars * SlotParam list list * typ option
+    member ss.Name             = let (TSlotSig(nm,_,_,_,_,_)) = ss in nm
+    member ss.ImplementedType  = let (TSlotSig(_,ty,_,_,_,_)) = ss in ty
+    member ss.ClassTypars      = let (TSlotSig(_,_,ctps,_,_,_)) = ss in ctps
+    member ss.MethodTypars     = let (TSlotSig(_,_,_,mtps,_,_)) = ss in mtps
+    member ss.FormalParams     = let (TSlotSig(_,_,_,_,ps,_)) = ss in ps
+    member ss.FormalReturnType = let (TSlotSig(_,_,_,_,_,rt)) = ss in rt
+
+and SlotParam = 
+    | TSlotParam of  string option * typ * bool (* in *) * bool (* out *) * bool (* optional *) * Attribs
+    member x.Type = let (TSlotParam(_,ty,_,_,_,_)) = x in ty
+
+/// Specifies the compiled representations of type and exception definitions.  
+/// Computed and cached by later phases (never computed type checking).  Cached at 
+/// type and exception definitions. Not pickled. Cache an optional ILType object for 
+/// non-generic types
+and CompiledTypeRepr = 
+    | TyrepNamed of ILTypeRef * ILBoxity * ILType option
+    | TyrepOpen of ILType  
+
+/// Metadata on values (names of arguments etc. 
+module TopValInfo = 
+    let unnamedTopArg1 : TopArgInfo = { Attribs=[]; Name=None }
+
+//-------------------------------------------------------------------------
+// Managed cached type name lookup tables
+//------------------------------------------------------------------------- 
+ 
+type CcuThunk with 
+    member ccu.TopModulesAndNamespaces = ccu.Contents.ModuleOrNamespaceType.ModuleAndNamespaceDefinitions
+    member ccu.TopTypeAndExceptionDefinitions = ccu.Contents.ModuleOrNamespaceType.TypeAndExceptionDefinitions
+
+//---------------------------------------------------------------------------
+// Equality relations on locally defined things 
+//---------------------------------------------------------------------------
+
+let typar_ref_eq    (lv1:Typar) (lv2:Typar) = (lv1.Stamp = lv2.Stamp)
+
+let typar_ref_hash (lv1:Typar) = hash lv1.Stamp
+
+/// Equality on CCU references, implemented as reference equality except when unresolved
+let ccu_eq (mv1: CcuThunk) (mv2: CcuThunk) = 
+    (mv1 === mv2) || 
+    (if mv1.IsUnresolvedReference || mv2.IsUnresolvedReference then 
+        mv1.AssemblyName = mv2.AssemblyName
+     else 
+        mv1.Contents === mv2.Contents)
+
+//---------------------------------------------------------------------------
+// Get information from refs
+//---------------------------------------------------------------------------
+
+exception InternalUndefinedTyconItem of (string * string -> int * string) * TyconRef * string
+
+type UnionCaseRef with 
+    member x.UnionCase = 
+        let (UCRef(tcref,nm)) = x
+        match tcref.GetUnionCaseByName nm with 
+        | Some res -> res
+        | None -> error (InternalUndefinedTyconItem (FSComp.SR.tastUndefinedTyconItemUnionCase, tcref, nm))
+    member x.Attribs = x.UnionCase.Attribs
+    member x.Range = x.UnionCase.Range
+
+type RecdFieldRef with 
+    member x.RecdField = 
+        let (RFRef(tcref,id)) = x
+        match tcref.GetFieldByName id with 
+        | Some res -> res
+        | None -> error (InternalUndefinedTyconItem (FSComp.SR.tastUndefinedTyconItemField, tcref, id))
+    member x.PropertyAttribs = x.RecdField.PropertyAttribs
+    member x.Range = x.RecdField.Range
+
+//--------------------------------------------------------------------------
+// Make references to TAST items
+//--------------------------------------------------------------------------
+
+let VRef_local    x : ValRef = { binding=x; nlr=Unchecked.defaultof<_> }      
+let VRef_nonlocal x : ValRef = { binding=Unchecked.defaultof<_>; nlr=x }      
+
+let (|VRef_local|VRef_nonlocal|) (x: ValRef) = 
+    match box x.nlr with 
+    | null -> VRef_local x.binding
+    | _ -> VRef_nonlocal x.nlr
+
+let ERef_local x : EntityRef = { binding=x; nlr=Unchecked.defaultof<_> }      
+let ERef_nonlocal x : EntityRef = { binding=Unchecked.defaultof<_>; nlr=x }      
+let (|ERef_local|ERef_nonlocal|) (x: EntityRef) = 
+    match box x.nlr with 
+    | null -> ERef_local x.binding
+    | _ -> ERef_nonlocal x.nlr
+
+//--------------------------------------------------------------------------
+// Type parameters and inference unknowns
+//-------------------------------------------------------------------------
+
+let mk_typar_ty (tp:Typar) = 
+    match tp.Kind with 
+    | KindType -> tp.AsType 
+    | KindMeasure -> TType_measure (MeasureVar tp)
+
+//--------------------------------------------------------------------------
+// Inference variables
+//-------------------------------------------------------------------------- 
+
+let tpref_is_solved (r:Typar) = 
+    match r.Solution with 
+    | None -> false
+    | _ -> true
+
+    
+let try_shortcut_solved_upref (r:Typar) = 
+    match r.Solution with
+    | Some (TType_measure unt) -> unt
+    | _ -> failwith "try_shortcut_solved_upref: unsolved"
+      
+
+let rec strip_upeqnsA unt = 
+    match unt with 
+    | MeasureVar r when tpref_is_solved r -> strip_upeqnsA (try_shortcut_solved_upref r)
+    | _ -> unt
+
+let rec strip_tpeqnsA ty = 
+    match ty with 
+    | TType_var r -> 
+        match r.Solution with
+        | Some soln -> strip_tpeqnsA soln
+        | None -> ty
+    | TType_measure unt -> TType_measure (strip_upeqnsA unt)
+    | _ -> ty
+
+let strip_tpeqns ty = strip_tpeqnsA ty
+
+//--------------------------------------------------------------------------
+// Construct local references
+//-------------------------------------------------------------------------- 
+
+
+let mk_nleref ccu mp = NonLocalEntityRef(ccu,mp)
+let mk_nested_nleref (nleref:NonLocalEntityRef) id = mk_nleref nleref.Ccu (Array.append nleref.Path [| id |])
+let mk_local_tcref x = ERef_local x
+let mk_nonlocal_tcref nleref id = ERef_nonlocal (mk_nested_nleref nleref id)
+
+//--------------------------------------------------------------------------
+// From Ref_private to Ref_nonlocal when exporting data.
+//--------------------------------------------------------------------------
+
+let enclosing_nleref_of_pubpath viewedCcu (PubPath(p)) = NonLocalEntityRef(viewedCcu, p.[0..p.Length-2])
+let nleref_of_pubpath viewedCcu (PubPath(p)) = NonLocalEntityRef(viewedCcu,p)
+
+//---------------------------------------------------------------------------
+// Equality between TAST items.
+//---------------------------------------------------------------------------
+
+let array_path_eq (y1:string[]) (y2:string[]) =
+    let len1 = y1.Length 
+    let len2 = y2.Length 
+    (len1 = len2) && 
+    (let rec loop i = (i >= len1) || (y1.[i] = y2.[i] && loop (i+1)) 
+     loop 0)
+
+let nleref_eq (NonLocalEntityRef(x1,y1) as smr1) (NonLocalEntityRef(x2,y2) as smr2) = 
+    smr1 === smr2 || (ccu_eq x1 x2 && array_path_eq y1 y2)
+
+/// This predicate tests if non-local resolution paths are definitely known to resolve
+/// to different entities. All references with different named paths always resolve to 
+/// different entities. Two references with the same named paths may resolve to the same 
+/// entities even if they reference through different CCUs, because one reference
+/// may be forwarded to another via a .NET TypeForwarder.
+let nleref_definitely_not_eq (NonLocalEntityRef(_,y1)) (NonLocalEntityRef(_,y2)) = 
+    not (array_path_eq y1 y2)
+
+
+/// Primitive routine to compare two EntityRef's for equality
+/// This takes into account the possibility that they may have type forwarders
+let prim_entity_ref_eq (x : EntityRef) (y : EntityRef) = 
+    x === y ||
+    match x.IsResolved,y.IsResolved with 
+    | true, true -> x.ResolvedTarget === y.ResolvedTarget 
+    | _ -> 
+    match x.IsLocalRef,y.IsLocalRef with 
+    | false, false when 
+        (// Two tcrefs with identical paths are always equal
+         nleref_eq x.nlr y.nlr || 
+         // The tcrefs may have forwarders. If they may possibly be equal then resolve them to get their canonical references
+         // and compare those using pointer equality.
+         (not (nleref_definitely_not_eq x.nlr y.nlr) && x.Deref === y.Deref)) -> 
+        true
+    | _ -> 
+        false
+
+let prim_entity_hash (x : EntityRef) =
+    match x.TryDeref with
+    |   None -> 0
+    |   Some target -> hash (box target)
+
+let ucref_eq (uc1 : UnionCaseRef) (uc2 : UnionCaseRef) =
+    prim_entity_ref_eq uc1.TyconRef uc2.TyconRef && uc1.CaseName = uc2.CaseName
+let ucref_hash (uc : UnionCaseRef) =
+    (prim_entity_hash uc.TyconRef) * 29 + (hash uc.CaseName)
+
+let taccessPublic = TAccess []
+
+//---------------------------------------------------------------------------
+// Construct TAST nodes
+//---------------------------------------------------------------------------
+
+let SkipFreeVarsCache() = ()
+let NewFreeVarsCache() = newCache ()
+
+let MakeUnionCasesTable ucs = 
+    { ucases_by_index = Array.ofList ucs; 
+      ucases_by_name = NameMap.ofKeyedList (fun uc -> uc.DisplayName) ucs }
+                                                                  
+let MakeRecdFieldsTable ucs = 
+    { rfields_by_index = Array.ofList ucs; 
+      rfields_by_name = ucs  |> NameMap.ofKeyedList (fun rfld -> rfld.Name) }
+                                                                  
+let MakeUnionCases ucs = 
+    { funion_ucases=MakeUnionCasesTable ucs; }
+
+let MakeUnionRepr ucs = TFiniteUnionRepr (MakeUnionCases ucs)
+
+let tau_typ_eq t1 t2 =
+    let rec tinst_eq tinst1 tinst2 =
+        (List.length tinst1) = (List.length tinst2) &&
+        List.forall2 tau_typ_eq tinst1 tinst2
+
+    and tau_typ_eq t1 t2 =
+        match t1, t2 with 
+        |   TType_app(tcref1, tinst1), TType_app(tcref2, tinst2) ->            
+                    prim_entity_ref_eq tcref1 tcref2 && tinst_eq tinst1 tinst2
+        |   TType_tuple tinst1, TType_tuple tinst2 -> 
+                    tinst_eq tinst1 tinst2 
+        |   TType_fun(tdom1,trange1), TType_fun(tdom2,trange2) -> 
+                    tau_typ_eq tdom1 tdom2 && tau_typ_eq trange1 trange2
+        |   TType_ucase(ucref1,tinst1), TType_ucase(ucref2,tinst2) ->
+                    ucref_eq ucref1 ucref2 && tinst_eq tinst1 tinst2
+        |   TType_var typar1, TType_var typar2 -> 
+                    typar_ref_eq typar1 typar2 || typar_ref_eq typar1 typar2 
+        |   TType_measure m1, TType_measure m2 ->
+                    measure_eq m1 m2
+        |   (TType_forall(_) as x), _ 
+        |   _, (TType_forall(_) as x) -> failwithf "Not a tau type %A" x
+        |   _ -> false
+
+    and measure_eq m1 m2 = 
+        match m1, m2 with
+        |   MeasureOne, MeasureOne -> true
+        |   MeasureInv m1, MeasureInv m2 -> measure_eq m1 m2
+        |   MeasureProd(m11,m12), MeasureProd(m21,m22) -> measure_eq m11 m21 && measure_eq m12 m22
+        |   MeasureCon tcref1, MeasureCon tcref2 -> prim_entity_ref_eq tcref1 tcref2
+        |   MeasureVar typar1, MeasureVar typar2 -> typar_ref_eq typar1 typar2
+        |   _ -> false
+
+    tau_typ_eq t1 t2
+
+let tau_typ_hash t =
+    let rec tau_typ_hash t =
+        match t with
+        |   TType_app(tcref, tinst) ->   (prim_entity_hash tcref) + 13 * (tinst_hash tinst)
+        |   TType_tuple tinst ->        1 + tinst_hash tinst 
+        |   TType_fun(tdom,trange) ->   2 + (tau_typ_hash trange) + 13 * (tau_typ_hash tdom)
+        |   TType_ucase(uc,tinst) ->    3 + (ucref_hash uc) + 13 * (tinst_hash tinst)
+        |   TType_var typar ->          5 + (typar_ref_hash typar)
+        |   TType_measure m ->          7 + (measure_hash m)
+        |   TType_forall _ ->           failwith "Non-tau types unsupported"
+    and tinst_hash tinst = List.fold (fun h t -> h * 13 + tau_typ_hash t) 0 tinst
+    and measure_hash m =
+        match m with
+        |   MeasureOne ->           1
+        |   MeasureInv m ->         2 + (measure_hash m)
+        |   MeasureProd(m1,m2) ->   3 + (measure_hash m1) + 13 * (measure_hash m2)
+        |   MeasureCon tcref ->     5 + (prim_entity_hash tcref)
+        |   MeasureVar typar ->     7 + (typar_ref_hash typar)
+    tau_typ_hash t
+
+         
+//--------------------------------------------------------------------------
+// Resource format for pickled data
+//--------------------------------------------------------------------------
+
+let FSharpOptimizationDataResourceName = "FSharpOptimizationData"
+let FSharpSignatureDataResourceName = "FSharpSignatureData"
+
+
+
diff --git a/src/FSharp.PowerPack.Metadata/tastops.fs b/src/FSharp.PowerPack.Metadata/tastops.fs
new file mode 100755
index 0000000..e5371ae
--- /dev/null
+++ b/src/FSharp.PowerPack.Metadata/tastops.fs
@@ -0,0 +1,61 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+module internal  Microsoft.FSharp.Metadata.Reader.Internal.Tastops
+
+open System.Collections.Generic 
+open Microsoft.FSharp.Metadata.Reader.Internal.AbstractIL.IL
+open Microsoft.FSharp.Metadata.Reader.Internal.PrettyNaming
+open Microsoft.FSharp.Metadata.Reader.Internal.Prelude
+open Microsoft.FSharp.Metadata.Reader.Internal.Tast
+open Microsoft.FSharp.Metadata.Reader.Internal.Env
+
+//---------------------------------------------------------------------------
+// Basic data structures
+//---------------------------------------------------------------------------
+
+[<NoEquality; NoComparison>]
+type TyparMap<'a> = TPMap of StampMap<'a>
+let tpmap_find (v: Typar) (TPMap m) = m.[v.Stamp]
+let tpmap_mem (v: Typar) (TPMap m) = m.ContainsKey(v.Stamp)
+let tpmap_add (v: Typar) x (TPMap m) = TPMap (m.Add(v.Stamp,x))
+let tpmap_empty () = TPMap Map.empty
+
+//---------------------------------------------------------------------------
+// Basic equalites
+//---------------------------------------------------------------------------
+
+let tcref_eq g tcref1 tcref2 = prim_entity_ref_eq tcref1 tcref2
+
+//---------------------------------------------------------------------------
+// Some basic type builders
+//---------------------------------------------------------------------------
+
+let mk_unit_typ g = TType_app (g.unit_tcr, [])
+let mk_nativeint_typ g = TType_app (g.nativeint_tcr, [])
+
+//--------------------------------------------------------------------------
+// Tuple compilation (types)
+//------------------------------------------------------------------------ 
+
+let maxTuple = 8
+let goodTupleFields = maxTuple-1
+
+let compiled_tuple_tcref g tys = 
+    let n = List.length tys 
+    if   n = 1 then g.tuple1_tcr
+    elif n = 2 then g.tuple2_tcr
+    elif n = 3 then g.tuple3_tcr
+    elif n = 4 then g.tuple4_tcr
+    elif n = 5 then g.tuple5_tcr
+    elif n = 6 then g.tuple6_tcr
+    elif n = 7 then g.tuple7_tcr
+    elif n = 8 then g.tuple8_tcr
+    else failwithf "compiled_tuple_tcref, n = %d" n
+
+let rec compiled_tuple_ty g tys = 
+    let n = List.length tys 
+    if n < maxTuple then TType_app (compiled_tuple_tcref g tys, tys)
+    else 
+        let tysA,tysB = List.splitAfter goodTupleFields tys
+        TType_app (g.tuple8_tcr, tysA@[compiled_tuple_ty g tysB])
+
diff --git a/src/FSharp.PowerPack.Parallel.Seq/Assembly.fs b/src/FSharp.PowerPack.Parallel.Seq/Assembly.fs
new file mode 100755
index 0000000..a41f20b
--- /dev/null
+++ b/src/FSharp.PowerPack.Parallel.Seq/Assembly.fs
@@ -0,0 +1,6 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp
+
+[<assembly: System.Security.SecurityTransparent>]
+do()    
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Parallel.Seq/FSharp.PowerPack.Parallel.Seq.fsproj b/src/FSharp.PowerPack.Parallel.Seq/FSharp.PowerPack.Parallel.Seq.fsproj
new file mode 100755
index 0000000..8bc65f2
--- /dev/null
+++ b/src/FSharp.PowerPack.Parallel.Seq/FSharp.PowerPack.Parallel.Seq.fsproj
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{24a845cd-b684-46fb-abca-979013f5015b}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>FSharp.PowerPack.Parallel.Seq</AssemblyName>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <DocumentationFile>FSharp.PowerPack.Parallel.Seq.xml</DocumentationFile>
+    <NoWarn>$(NoWarn);9</NoWarn>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <!-- References -->
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="FSharp.Core" />
+    <Reference Include="System.Core" />
+  </ItemGroup>
+  <!-- Files -->
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="assemblyinfo.FSharp.PowerPack.Parallel.Seq.dll.fs">
+      <Link>assemblyinfo.FSharp.PowerPack.Parallel.Seq.dll.fs</Link>
+    </Compile>
+    <Compile Include="pseq.fsi" />
+    <Compile Include="pseq.fs" />
+    <Compile Include="Assembly.fs" />
+    <None Include="PSeq.fsx" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Parallel.Seq/FSharp.PowerPack.Parallel.Seq.fsproj.vspscc b/src/FSharp.PowerPack.Parallel.Seq/FSharp.PowerPack.Parallel.Seq.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FSharp.PowerPack.Parallel.Seq/FSharp.PowerPack.Parallel.Seq.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FSharp.PowerPack.Parallel.Seq/assemblyinfo.FSharp.PowerPack.Parallel.Seq.dll.fs b/src/FSharp.PowerPack.Parallel.Seq/assemblyinfo.FSharp.PowerPack.Parallel.Seq.dll.fs
new file mode 100755
index 0000000..351d483
--- /dev/null
+++ b/src/FSharp.PowerPack.Parallel.Seq/assemblyinfo.FSharp.PowerPack.Parallel.Seq.dll.fs
@@ -0,0 +1,7 @@
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("FSharp.PowerPack.Parallel.Seq.dll")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("FSharp.PowerPack.Parallel.Seq.dll")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
diff --git a/src/FSharp.PowerPack.Parallel.Seq/pseq.fs b/src/FSharp.PowerPack.Parallel.Seq/pseq.fs
new file mode 100755
index 0000000..9a10680
--- /dev/null
+++ b/src/FSharp.PowerPack.Parallel.Seq/pseq.fs
@@ -0,0 +1,286 @@
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Linq
+open System.Threading
+
+// Type abbreviation for parallel sequences.
+type pseq<'T> = ParallelQuery<'T>
+
+[<RequireQualifiedAccess>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module PSeq = 
+ 
+    // Converst a seq<'T> to a pseq<'T>.
+    let inline toP (s : seq<'T>) = 
+        match s with
+        | null -> nullArg "s"
+        | :? pseq<'T> as p ->  p
+        | _ -> s.AsParallel()
+
+    // Seq.* functions
+    let empty<'T> = 
+        ParallelEnumerable.Empty<'T>()
+
+    let length s = 
+        ParallelEnumerable.Count(toP(s))
+
+    let isEmpty s = 
+        not (ParallelEnumerable.Any(toP(s)))
+
+    let singleton x = 
+        ParallelEnumerable.Repeat(x, 1)
+
+    let head s = 
+        ParallelEnumerable.First(toP(s))
+
+    let truncate n s = 
+        ParallelEnumerable.Take(toP(s), n)
+
+    let fold<'T, 'State> (f : 'State -> 'T -> 'State) acc s = 
+        ParallelEnumerable.Aggregate(toP(s),acc,Func<_,_,_>(f))
+
+    let reduce f s = 
+        ParallelEnumerable.Aggregate(toP(s), Func<_,_,_>(f))
+
+    let exists p s = 
+        ParallelEnumerable.Any(toP(s), Func<_,_>(p))
+
+    let forall p s = 
+        ParallelEnumerable.All(toP(s), Func<_,_>(p))
+
+    let exists2 (f : 'T -> 'U -> bool) s1 s2 = 
+        ParallelEnumerable.Any(ParallelEnumerable.Zip(toP(s1), toP(s2),Func<_,_,_>(f)), Func<_,_>(id))
+
+    let forall2 (f : 'T -> 'U -> bool) s1 s2 = 
+        ParallelEnumerable.All(ParallelEnumerable.Zip(toP(s1), toP(s2),Func<_,_,_>(f)), Func<_,_>(id))
+
+    let filter p s = 
+        ParallelEnumerable.Where(toP(s), Func<_,_>(p))
+
+    let iter f s = 
+        ParallelEnumerable.ForAll(toP(s), Action<_>(f))
+
+    let map f s  = 
+        ParallelEnumerable.Select(toP(s), new Func<_,_>(f)) 
+
+    let pick f s = 
+        let projected = ParallelEnumerable.Select(toP(s),Func<_,_>(f))
+        let res = ParallelEnumerable.FirstOrDefault(projected, Func<_,_>(Option.isSome))
+        match res with 
+        | Some x -> x
+        | None -> raise (new System.Collections.Generic.KeyNotFoundException())
+
+    let find p s = 
+        ParallelEnumerable.First(toP(s), Func<_,_>(p))
+
+    let tryFind p s = 
+        let withSomes = ParallelEnumerable.Select(toP(s), Func<_,_>(Some))
+        ParallelEnumerable.FirstOrDefault(withSomes, Func<_,_>(fun x -> p(Option.get(x))))
+
+    let findIndex p s = 
+        let indexed = ParallelEnumerable.Select(toP(s), Func<_,int,_>(fun x i -> (i,x)))
+        match ParallelEnumerable.First(indexed, Func<_,_>(fun (_,x) -> p(x))) with
+        | (i,x) -> i
+
+    let tryFindIndex p s = 
+         let indexed = ParallelEnumerable.Select(toP(s), Func<_,int,_>(fun x i -> Some (i,x)))
+         match ParallelEnumerable.FirstOrDefault(indexed, Func<_,_>(fun x -> p(snd(Option.get x)))) with
+         | Some (i,x) -> Some i
+         | None -> None
+
+    let ofArray (arr : 'T array) = 
+        arr.AsParallel()
+
+    let toArray s = 
+        ParallelEnumerable.ToArray(toP(s))
+
+    let ofList (l : 'T list) = 
+        l.AsParallel()
+
+    let toList (s : seq<'T>) = 
+        toP(s) |> List.ofSeq
+
+    let ofSeq (s : seq<'T>)  = 
+        s.AsParallel()
+
+    let toSeq s = 
+        toP(s).AsSequential()
+
+    let cast<'T> (s : System.Collections.IEnumerable) : pseq<'T> = 
+        ParallelEnumerable.Cast<'T>(s.AsParallel())    
+
+    let collect f s = 
+        ParallelEnumerable.SelectMany(toP(s), Func<_,_>(fun x -> (f x) :> seq<'U>))
+
+    let append s1 s2 = 
+        ParallelEnumerable.Concat(toP(s1),toP(s2))
+
+    let init n f = 
+        ParallelEnumerable.Select(ParallelEnumerable.Range(0, n), Func<_,_>(f))
+
+    let iter2 f s1 s2 = 
+        ParallelEnumerable.Zip(toP(s1),toP(s2), Func<_,_,_>(fun x y -> do f x y )) |> ignore
+
+    let nth n s = 
+        ParallelEnumerable.ElementAt(toP(s), n)
+
+    let map2 f s1 s2 = 
+        ParallelEnumerable.Zip(toP(s1),toP(s2), Func<_,_,_>(fun x y -> f x y))
+
+    let zip s1 s2 = 
+        ParallelEnumerable.Zip(toP(s1),toP(s2), Func<_,_,_>(fun x y -> (x,y)))
+
+    let mapi f s = 
+        ParallelEnumerable.Select(toP(s), new Func<_,_,_>(fun i c -> f c i))
+
+    let iteri f s = 
+        let indexed = ParallelEnumerable.Select(toP(s), Func<_,_,_>(fun x i -> (x,i)))
+        ParallelEnumerable.ForAll(indexed, Action<_>(fun (x,i) -> f i x))
+
+    let takeWhile f s = 
+        ParallelEnumerable.TakeWhile(toP(s), Func<_,_>(f))
+
+    let skip n s = 
+        ParallelEnumerable.Skip(toP(s), n)
+
+    let skipWhile f s = 
+        ParallelEnumerable.SkipWhile(toP(s), Func<_,_>(f))
+
+    let groupBy (f : 'T -> 'Key) s = 
+        ParallelEnumerable.GroupBy(toP(s),Func<_,_>(f), Func<_,_,_>(fun k v -> (k, v)), HashIdentity.Structural<_>)  
+
+    let distinct s = 
+        ParallelEnumerable.Distinct(toP(s), HashIdentity.Structural<_>)
+
+    let distinctBy p s = 
+        let comparer = 
+            { new System.Collections.Generic.IEqualityComparer<'T * 'Key> with
+                member this.Equals(((_, p1)),((_,p2))) = p1 = p2
+                member this.GetHashCode((_,p1)) = p1.GetHashCode() }
+        let projected = ParallelEnumerable.Select(toP(s), Func<_,_>(fun x -> (x, p x)))
+        let distinct = ParallelEnumerable.Distinct(projected, comparer)
+        ParallelEnumerable.Select(distinct, Func<_,_>(fun (x,px) -> x))
+
+    let sort s  = 
+        ParallelEnumerable.OrderBy(toP(s), Func<_,_>(fun x -> x), ComparisonIdentity.Structural<_>) :> pseq<'T>
+
+    let sortBy (f : 'T -> 'Key) s = 
+        ParallelEnumerable.OrderBy(toP(s), Func<_,_>(f), ComparisonIdentity.Structural<_>) :> pseq<'T>
+
+    let countBy f s = 
+        ParallelEnumerable.GroupBy(toP(s), Func<_,_>(f), Func<_,_,_>(fun k vs -> (k, Seq.length vs)))
+
+    let concat ss = 
+        ParallelEnumerable.Aggregate(toP(ss), empty, Func<_,_,_>(fun soFar y -> append soFar (toP y) : pseq<_>))
+
+    let choose chooser s = 
+        let projected = ParallelEnumerable.Select(toP(s), Func<_,_>(chooser))
+        let somes = ParallelEnumerable.Where(projected, Func<_,_>(Option.isSome))
+        ParallelEnumerable.Select(somes, Func<_,_>(Option.get))
+
+    let inline average (s : seq< ^T >) : ^T 
+              when ^T : (static member ( + ) : ^T * ^T -> ^T) 
+              and  ^T : (static member DivideByInt : ^T * int -> ^T) 
+              and  ^T : (static member Zero : ^T) = 
+        match s with
+        | null -> nullArg "s"
+        | :? seq<float> as s -> unbox(ParallelEnumerable.Average(toP(s)))
+        | :? seq<float32> as s -> unbox(ParallelEnumerable.Average(toP(s)))
+        | :? seq<decimal> as s -> unbox(ParallelEnumerable.Average(toP(s)))
+        | _ -> failwithf "Average is supported for element types float, float32 and decimal, but given type : %s" (typeof<(^T)>.ToString())
+
+    let inline averageBy (f : 'T -> ^U) (s : seq< 'T >) : ^U 
+            when ^U : (static member ( + ) : ^U * ^U -> ^U) 
+            and  ^U : (static member DivideByInt : ^U * int -> ^U) 
+            and  ^U : (static member Zero : ^U) =
+        let bType = typeof<(^U)>
+        if   bType = typeof<float> then unbox(ParallelEnumerable.Average(toP(s), Func<_,float>(fun x -> unbox(f x))))
+        elif bType = typeof<float32> then unbox(ParallelEnumerable.Average(toP(s), Func<_,float32>(fun x -> unbox(f x))))
+        elif bType = typeof<decimal> then unbox(ParallelEnumerable.Average(toP(s), Func<_,decimal>(fun x -> unbox(f x))))
+        else failwithf "AverageBy is supported for projections to types float, float32 and decimal, but used at type type : %s" (bType.ToString())
+
+    let inline sum (s : seq< ^T >) : ^T 
+            when ^T : (static member ( + ) : ^T * ^T -> ^T) 
+            and  ^T : (static member Zero : ^T) = 
+        match s with
+        | null -> nullArg "s"
+        | :? seq<int> as s -> unbox(ParallelEnumerable.Sum(toP(s)))
+        | :? seq<int64> as s -> unbox(ParallelEnumerable.Sum(toP(s)))
+        | :? seq<float> as s -> unbox(ParallelEnumerable.Sum(toP(s)))
+        | :? seq<float32> as s -> unbox(ParallelEnumerable.Sum(toP(s)))
+        | :? seq<decimal> as s -> unbox(ParallelEnumerable.Sum(toP(s)))
+        | _ -> failwithf "Sum is supported for element types int, int64, float, float32 and decimal, but given type : %s" (typeof<(^T)>.ToString())
+
+    let inline sumBy (f : 'T -> ^U) (s : seq< 'T >) : ^U  
+            when ^U : (static member ( + ) : ^U * ^U -> ^U) 
+            and  ^U : (static member Zero : ^U) = 
+        let bType = typeof<(^U)>
+        if   bType = typeof<int> then unbox(ParallelEnumerable.Sum(toP(s), Func<_,int>(fun x -> unbox(f x))))
+        elif bType = typeof<int64> then unbox(ParallelEnumerable.Sum(toP(s), Func<_,int64>(fun x -> unbox(f x))))        
+        elif bType = typeof<float> then unbox(ParallelEnumerable.Sum(toP(s), Func<_,float>(fun x -> unbox(f x))))
+        elif bType = typeof<float32> then unbox(ParallelEnumerable.Sum(toP(s), Func<_,float32>(fun x -> unbox(f x))))
+        elif bType = typeof<decimal> then unbox(ParallelEnumerable.Sum(toP(s), Func<_,decimal>(fun x -> unbox(f x))))
+        else failwithf "SumBy is supported for projections to types int, int64, float, float32 and decimal, but given type : %s" (bType.ToString())
+
+    let inline min (s : seq< ^T > ) : ^T when ^T : comparison =    
+        match s with
+        | null -> nullArg "s"
+        | :? seq<int> as s -> unbox(ParallelEnumerable.Min(toP(s)))
+        | :? seq<int64> as s -> unbox(ParallelEnumerable.Min(toP(s)))
+        | :? seq<float> as s -> unbox(ParallelEnumerable.Min(toP(s)))
+        | :? seq<float32> as s -> unbox(ParallelEnumerable.Min(toP(s)))
+        | :? seq<decimal> as s -> unbox(ParallelEnumerable.Min(toP(s)))
+        | _ ->  ParallelEnumerable.Min(toP(s), Func<_,_>(fun x -> x))
+
+    let inline minBy (f : ^T -> ^U) (s : seq< ^T >) : ^T when ^U : comparison = 
+        let elemsAndVals = ParallelEnumerable.Select(toP(s), Func<_,_>(fun x -> f x, x))
+        let (_, elem) = ParallelEnumerable.Aggregate(elemsAndVals, Func<_,_,_>(fun (minVal, minElem) (curVal, curElem) -> if curVal < minVal then (curVal, curElem) else (minVal, minElem)))
+        elem
+
+    let inline max (s : seq< ^T >) : ^T =    
+        match s with
+        | null -> nullArg "s"
+        | :? seq<int> as s -> unbox(ParallelEnumerable.Max(toP(s)))
+        | :? seq<int64> as s -> unbox(ParallelEnumerable.Max(toP(s)))
+        | :? seq<float> as s -> unbox(ParallelEnumerable.Max(toP(s)))
+        | :? seq<float32> as s -> unbox(ParallelEnumerable.Max(toP(s)))
+        | :? seq<decimal> as s -> unbox(ParallelEnumerable.Max(toP(s)))
+        | _ ->  ParallelEnumerable.Max(toP(s), Func<_,_>(fun x -> x))
+
+    let inline maxBy (f : ^T -> ^U) (s : seq< ^T >) : ^T = 
+        let elemsAndVals = ParallelEnumerable.Select(toP(s), Func<_,_>(fun x -> f x, x))
+        let (_, elem) = ParallelEnumerable.Aggregate(elemsAndVals, Func<_,_,_>(fun (minVal, minElem) (curVal, curElem) -> if curVal > minVal then (curVal, curElem) else (minVal, minElem)))
+        elem
+
+
+    // Missing Seq.* functions
+    //
+    //    ?	zip3
+    //    ?	scan
+    //    ?	windowed
+    //    ?	tryPick
+    //    ?	take
+    //    ?	readonly
+    //    ?	pairwise
+    //    ?	initInfinite
+    //    ?	delay
+    //    ?	compareWith
+    //    ?	unfold
+
+
+    // Parallel-specific functionality 
+    let ordered s = 
+        toP(s).AsOrdered()
+
+    let withDegreeOfParallelism n s = 
+        toP(s).WithDegreeOfParallelism(n)
+
+    let withExecutionMode executionMode s = 
+        toP(s).WithExecutionMode(executionMode)
+
+    let withMergeOptions mergeOptions s = 
+        toP(s).WithMergeOptions(mergeOptions)
+    
+    let withCancellation cancellationToken s = 
+        toP(s).WithCancellation(cancellationToken)
diff --git a/src/FSharp.PowerPack.Parallel.Seq/pseq.fsi b/src/FSharp.PowerPack.Parallel.Seq/pseq.fsi
new file mode 100755
index 0000000..9973353
--- /dev/null
+++ b/src/FSharp.PowerPack.Parallel.Seq/pseq.fsi
@@ -0,0 +1,956 @@
+//=========================================================================
+// (c) Microsoft Corporation 2005-2009. 
+//=========================================================================
+
+namespace Microsoft.FSharp.Collections
+
+    open System
+    open System.Collections
+    open System.Collections.Generic
+    open Microsoft.FSharp.Core
+    open Microsoft.FSharp.Collections
+    open System.Linq
+    open System.Threading
+        
+
+    type pseq<'T> = ParallelQuery<'T>
+
+    /// <summary>Parallel operations on IEnumerables.</summary>
+    [<RequireQualifiedAccess>]
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module PSeq = 
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Wraps the two given enumerations as a single concatenated
+        /// enumeration.</summary>
+        ///
+        /// <remarks>The returned sequence may be passed between threads safely. However, 
+        /// individual IEnumerator values generated from the returned sequence should not be accessed
+        /// concurrently.</remarks>
+        ///
+        /// <param name="source1">The first sequence.</param>
+        /// <param name="source2">The second sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when either of the two provided sequences is
+        /// null.</exception>
+        // [<CompiledName("Append")>]
+        val append: source1:seq<'T>  -> source2:seq<'T> -> pseq<'T> 
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Wraps a loosely-typed System.Collections sequence as a typed sequence.</summary>
+        ///
+        /// <remarks>The use of this function usually requires a type annotation.
+        /// An incorrect type annotation may result in runtime type
+        /// errors.
+        /// Individual IEnumerator values generated from the returned sequence should not be accessed concurrently.</remarks>
+        /// 
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Cast")>]
+        val cast: source:IEnumerable -> pseq<'T>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies the given function to each element of the list. Return
+        /// the list comprised of the results "x" for each element where
+        /// the function returns Some(x).</summary>
+        ///
+        /// <remarks>The returned sequence may be passed between threads safely. However, 
+        /// individual IEnumerator values generated from the returned sequence should not
+        /// be accessed concurrently.</remarks>
+        ///
+        /// <param name="chooser">A function to transform items of type T into options of type U.</param>
+        /// <param name="source">The input sequence of type T.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        /// 
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Choose")>]
+        val choose: chooser:('T -> 'U option) -> source:seq<'T> -> pseq<'U>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies the given function to each element of the sequence and concatenates all the
+        /// results.</summary>
+        ///
+        /// <remarks>Remember sequence is lazy, effects are delayed until it is enumerated.</remarks>
+        ///
+        /// <param name="mapping">A function to transform elements of the input sequence into the sequences
+        /// that will then be concatenated.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Collect")>]
+        val collect: mapping:('T -> 'Collection) -> source:seq<'T> -> pseq<'U>  when 'Collection :> seq<'U>
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Combines the given enumeration-of-enumerations as a single concatenated
+        /// enumeration.</summary>
+        ///
+        /// <remarks>The returned sequence may be passed between threads safely. However, 
+        /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.</remarks>
+        ///
+        /// <param name="sources">The input enumeration-of-enumerations.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Concat")>]
+        val concat: sources:seq<'Collection> -> pseq<'T> when 'Collection :> seq<'T>
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies a key-generating function to each element of a sequence and return a sequence yielding unique
+        /// keys and their number of occurrences in the original sequence.</summary>
+        /// 
+        /// <remarks>Note that this function returns a sequence that digests the whole initial sequence as soon as 
+        /// that sequence is iterated. As a result this function should not be used with 
+        /// large or infinite sequences. The function makes no assumption on the ordering of the original 
+        /// sequence.</remarks>
+        ///
+        /// <param name="projection">A function transforming each item of input sequence into a key to be
+        /// compared against the others.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("CountBy")>]
+        val countBy : projection:('T -> 'Key) -> source:seq<'T> -> pseq<'Key * int> when 'Key : equality
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that contains no duplicate entries according to generic hash and
+        /// equality comparisons on the entries.
+        /// If an element occurs multiple times in the sequence then the later occurrences are discarded.</summary>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Distinct")>]
+        val distinct: source:seq<'T> -> pseq<'T> when 'T : equality
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that contains no duplicate entries according to the 
+        /// generic hash and equality comparisons on the keys returned by the given key-generating function.
+        /// If an element occurs multiple times in the sequence then the later occurrences are discarded.</summary>
+        ///
+        /// <param name="projection">A function transforming the sequence items into comparable keys.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("DistinctBy")>]
+        val distinctBy: projection:('T -> 'Key) -> source:seq<'T> -> pseq<'T> when 'Key : equality
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Creates an empty sequence.</summary>
+        ///
+        /// <returns>The result sequence.</returns>
+        [<GeneralizableValueAttribute>]
+        // [<CompiledName("Empty")>]
+        val empty<'T> : pseq<'T>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Tests if any element of the sequence satisfies the given predicate.</summary>
+        ///
+        /// <remarks>The predicate is applied to the elements of the input sequence. If any application 
+        /// returns true then the overall result is true and no further elements are tested. 
+        /// Otherwise, false is returned.</remarks>
+        ///
+        /// <param name="predicate">A function to test each item of the input sequence.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Exists")>]
+        val exists: predicate:('T -> bool) -> source:seq<'T> -> bool
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Tests if any pair of corresponding elements of the input sequences satisfies the given predicate.</summary>
+        ///
+        /// <remarks>The predicate is applied to matching elements in the two sequences up to the lesser of the 
+        /// two lengths of the collections. If any application returns true then the overall result is 
+        /// true and no further elements are tested. Otherwise, false is returned. If one sequence is shorter than 
+        /// the other then the remaining elements of the longer sequence are ignored.</remarks>
+        ///
+        /// <param name="predicate">A function to test each pair of items from the input sequences.</param>
+        /// <param name="source1">The first input sequence.</param>
+        /// <param name="source2">The second input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when either of the two input sequences is null.</exception>
+        // [<CompiledName("Exists2")>]
+        val exists2: predicate:('T1 -> 'T2 -> bool) -> source1:seq<'T1> -> source2:seq<'T2> -> bool
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a new collection containing only the elements of the collection
+        /// for which the given predicate returns "true".</summary>
+        ///
+        /// <remarks>The returned sequence may be passed between threads safely. However, 
+        /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.
+        ///
+        /// Remember sequence is lazy, effects are delayed until it is enumerated.</remarks>
+        ///
+        /// <param name="predicate">A function to test whether each item in the input sequence should be included in the output.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>    
+        // [<CompiledName("Filter")>]
+        val filter: predicate:('T -> bool) -> source:seq<'T> -> pseq<'T>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the first element for which the given function returns <c>true</c>.</summary>
+        ///
+        /// <param name="predicate">A function to test whether an item in the sequence should be returned.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.Collections.Generic.KeyNotFoundException">Thrown if no element returns true when
+        /// evaluated by the predicate</exception>
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null</exception>
+        // [<CompiledName("Find")>]
+        val find: predicate:('T -> bool) -> source:seq<'T> -> 'T
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the index of the first element for which the given function returns <c>true</c>.</summary>
+        ///
+        /// <param name="predicate">A function to test whether the index of a particular element should be returned.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.Collections.Generic.KeyNotFoundException">Thrown if no element returns true when
+        /// evaluated by the predicate</exception>
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null</exception>
+        // [<CompiledName("FindIndex")>]
+        val findIndex: predicate:('T -> bool) -> source:seq<'T> -> int
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies a function to each element of the collection, threading an accumulator argument
+        /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
+        /// then computes <c>f (... (f s i0)...) iN</c></summary>
+        ///
+        /// <param name="folder">A function that updates the state with each element from the sequence.</param>
+        /// <param name="state">The initial state.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Fold")>]
+        val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Tests if all elements of the sequence satisfy the given predicate.</summary>
+        ///
+        /// <remarks>The predicate is applied to the elements of the input sequence. If any application 
+        /// returns false then the overall result is false and no further elements are tested. 
+        /// Otherwise, true is returned.</remarks>
+        ///
+        /// <param name="predicate">A function to test an element of the input sequence.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("ForAll")>]
+        val forall: predicate:('T -> bool) -> source:seq<'T> -> bool
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Tests the all pairs of elements drawn from the two sequences satisfy the
+        /// given predicate. If one sequence is shorter than 
+        /// the other then the remaining elements of the longer sequence are ignored.</summary>
+        ///
+        /// <param name="predicate">A function to test pairs of elements from the input sequences.</param>
+        /// <param name="source1">The first input sequence.</param>
+        /// <param name="source2">The second input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
+        // [<CompiledName("ForAll2")>]
+        val forall2: predicate:('T1 -> 'T2 -> bool) -> source1:seq<'T1> -> source2:seq<'T2> -> bool
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies a key-generating function to each element of a sequence and yields a sequence of 
+        /// unique keys. Each unique key has also contains a sequence of all elements that match 
+        /// to this key.</summary>
+        /// 
+        /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as 
+        /// that sequence is iterated. As a result this function should not be used with 
+        /// large or infinite sequences. The function makes no assumption on the ordering of the original 
+        /// sequence.</remarks>
+        ///
+        /// <param name="projection">A function that transforms an element of the sequence into a comparable key.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        // [<CompiledName("GroupBy")>]
+        val groupBy : projection:('T -> 'Key) -> source:seq<'T> -> pseq<'Key * seq<'T>> when 'Key : equality
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the first element of the sequence.</summary>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when the input does not have any elements.</exception>
+        // [<CompiledName("Head")>]
+        val head: source:seq<'T> -> 'T
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns true if the sequence contains no elements, false otherwise.</summary>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("IsEmpty")>]
+        val isEmpty: source:seq<'T> -> bool
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Generates a new sequence which, when iterated, will return successive
+        /// elements by calling the given function, up to the given count.  The results of calling the function
+        /// will not be saved, that is the function will be reapplied as necessary to
+        /// regenerate the elements.  The function is passed the index of the item being
+        /// generated.</summary>
+        ///
+        /// <remarks>The returned sequence may be passed between threads safely. However, 
+        /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.</remarks>
+        ///
+        /// <param name="count">The maximum number of items to generate for the sequence.</param>
+        /// <param name="initializer">A function that generates an item in the sequence from a given index.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentException">Thrown when count is negative.</exception>
+        // [<CompiledName("Initialize")>]
+        val init: count:int -> initializer:(int -> 'T) -> pseq<'T>
+        
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies the given function to each element of the collection.</summary>
+        ///
+        /// <param name="action">A function to apply to each element of the sequence.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Iterate")>]
+        val iter: action:('T -> unit) -> source:seq<'T> -> unit
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies the given function to each element of the collection. The integer passed to the
+        /// function indicates the index of element.</summary>
+        ///
+        /// <param name="action">A function to apply to each element of the sequence that can also access the current index.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("IterateIndexed")>]
+        val iteri: action:(int -> 'T -> unit) -> source:seq<'T> -> unit
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies the given function to two collections simultaneously. If one sequence is shorter than 
+        /// the other then the remaining elements of the longer sequence are ignored.</summary>
+        ///
+        /// <param name="action">A function to apply to each pair of elements from the input sequences.</param>
+        /// <param name="source1">The first input sequence.</param>
+        /// <param name="source2">The second input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
+        // [<CompiledName("Iterate2")>]
+        val iter2: action:('T1 -> 'T2 -> unit) -> source1:seq<'T1> -> source2:seq<'T2> -> unit
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the lengthof the sequence</summary>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Length")>]
+        val length: source:seq<'T> -> int
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Builds a new collection whose elements are the results of applying the given function
+        /// to each of the elements of the collection.  The given function will be applied
+        /// as elements are demanded using the <c>MoveNext</c> method on enumerators retrieved from the
+        /// object.</summary>
+        ///
+        /// <remarks>The returned sequence may be passed between threads safely. However, 
+        /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.</remarks>
+        ///
+        /// <param name="mapping">A function to transform items from the input sequence.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Map")>]
+        val map  : mapping:('T -> 'U) -> source:seq<'T> -> pseq<'U>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Builds a new collection whose elements are the results of applying the given function
+        /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than 
+        /// the other then the remaining elements of the longer sequence are ignored.</summary>
+        ///
+        /// <param name="mapping">A function to transform pairs of items from the input sequences.</param>
+        /// <param name="source">The first input sequence.</param>
+        /// <param name="source2">The second input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
+        // [<CompiledName("Map2")>]
+        val map2: mapping:('T1 -> 'T2 -> 'U) -> source1:seq<'T1> -> source2:seq<'T2> -> pseq<'U>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Builds a new collection whose elements are the results of applying the given function
+        /// to each of the elements of the collection. The integer index passed to the
+        /// function indicates the index (from 0) of element being transformed.</summary>
+        ///
+        /// <param name="mapping">A function to transform items from the input sequence that also supplies the current index.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("MapIndexed")>]
+        val mapi: mapping:(int -> 'T -> 'U) -> source:seq<'T> -> pseq<'U>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Computes the nth element in the collection.</summary>
+        ///
+        /// <param name="index">The index of element to retrieve.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Get")>]
+        val nth: index:int -> source:seq<'T> -> 'T
+
+
+        // [<CompiledName("OfArray")>]
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Views the given array as a sequence.</summary>
+        ///
+        /// <param name="source">The input array.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        val ofArray: source:'T array -> pseq<'T>
+
+        // [<CompiledName("OfList")>]
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Views the given list as a sequence.</summary>
+        ///
+        /// <param name="source">The input list.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        val ofList: source:'T list -> pseq<'T>
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies the given function to successive elements, returning the first
+        /// <c>x</c> where the function returns "Some(x)".</summary>
+        ///
+        /// <param name="chooser">A function to transform each item of the input sequence into an option of the output type.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.Collections.Generic.KeyNotFoundException">Thrown when every item of the sequence
+        /// evaluates to <c>None</c> when the given function is applied.</exception>
+        // [<CompiledName("Pick")>]
+        val pick: chooser:('T -> 'U option) -> source:seq<'T> -> 'U 
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies a function to each element of the sequence, threading an accumulator argument
+        /// through the computation. Begin by applying the function to the first two elements.
+        /// Then feed this result into the function along with the third element and so on.  
+        /// Return the final result.</summary>
+        ///
+        /// <param name="reduction">A function that takes in the current accumulated result and the next
+        /// element of the sequence to produce the next accumulated result.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when the input sequence is empty.</exception>
+        // [<CompiledName("Reduce")>]
+        val reduce: reduction:('T -> 'T -> 'T) -> source:seq<'T> -> 'T
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that yields one item only.</summary>
+        ///
+        /// <param name="value">The input item.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        // [<CompiledName("Singleton")>]
+        val singleton: value:'T -> pseq<'T>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that skips N elements of the underlying sequence and then yields the
+        /// remaining elements of the sequence.</summary>
+        ///
+        /// <param name="count">The number of items to skip.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.InvalidOperationException">Thrown when count exceeds the number of elements
+        /// in the sequence.</exception>
+        // [<CompiledName("Skip")>]
+        val skip: count:int -> source:seq<'T> -> pseq<'T>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that, when iterated, skips elements of the underlying sequence while the 
+        /// given predicate returns <c>true</c>, and then yields the remaining elements of the sequence.</summary>
+        ///
+        /// <param name="predicate">A function that evaluates an element of the sequence to a boolean value.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("SkipWhile")>]
+        val skipWhile: predicate:('T -> bool) -> source:seq<'T> -> pseq<'T>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Yields a sequence ordered by keys.</summary>
+        /// 
+        /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as 
+        /// that sequence is iterated. As a result this function should not be used with 
+        /// large or infinite sequences. The function makes no assumption on the ordering of the original 
+        /// sequence.
+        ///
+        /// This is a stable sort, that is the original order of equal elements is preserved.</remarks>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Sort")>]
+        val sort : source:seq<'T> -> pseq<'T> when 'T : comparison
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies a key-generating function to each element of a sequence and yield a sequence ordered
+        /// by keys.  The keys are compared using generic comparison as implemented by <c>Operators.compare</c>.</summary> 
+        /// 
+        /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as 
+        /// that sequence is iterated. As a result this function should not be used with 
+        /// large or infinite sequences. The function makes no assumption on the ordering of the original 
+        /// sequence.
+        ///
+        /// This is a stable sort, that is the original order of equal elements is preserved.</remarks>
+        ///
+        /// <param name="projection">A function to transform items of the input sequence into comparable keys.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("SortBy")>]
+        val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> pseq<'T> when 'Key : comparison 
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that, when iterated, yields elements of the underlying sequence while the 
+        /// given predicate returns <c>true</c>, and then returns no further elements.</summary>
+        ///
+        /// <param name="predicate">A function that evaluates to false when no more items should be returned.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("TakeWhile")>]
+        val takeWhile: predicate:('T -> bool) -> source:seq<'T> -> pseq<'T>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Builds an array from the given collection.</summary>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("ToArray")>]
+        val toArray: source:seq<'T> -> 'T array
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Builds a list from the given collection.</summary>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("ToList")>]
+        val toList: source:seq<'T> -> 'T list
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the first element for which the given function returns <c>true</c>.
+        /// Return <c>None</c> if no such element exists.</summary>
+        ///
+        /// <param name="predicate">A function that evaluates to a Boolean when given an item in the sequence.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("TryFind")>]
+        val tryFind: predicate:('T -> bool) -> source:seq<'T> -> 'T option
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the index of the first element in the sequence 
+        /// that satisfies the given predicate. Return <c>None</c> if no such element exists.</summary>
+        ///
+        /// <param name="predicate">A function that evaluates to a Boolean when given an item in the sequence.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("TryFindIndex")>]
+        val tryFindIndex : predicate:('T -> bool) -> source:seq<'T> -> int option
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that when enumerated returns at most N elements.</summary>
+        ///
+        /// <param name="count">The maximum number of items to enumerate.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        // [<CompiledName("Truncate")>]
+        val truncate: count:int -> source:seq<'T> -> pseq<'T>
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Combines the two sequences into a list of pairs. The two sequences need not have equal lengths:
+        /// when one sequence is exhausted any remaining elements in the other
+        /// sequence are ignored.</summary>
+        ///
+        /// <param name="source1">The first input sequence.</param>
+        /// <param name="source2">The second input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
+        // [<CompiledName("Zip")>]
+        val zip: source1:seq<'T1> -> source2:seq<'T2> -> pseq<'T1 * 'T2>
+
+
+
+        val ordered: source:seq<'T> -> pseq<'T>
+
+        val withDegreeOfParallelism: n:int -> source:seq<'T> -> pseq<'T>
+
+        val withExecutionMode: executionMode:ParallelExecutionMode -> source:seq<'T> -> pseq<'T>
+
+        val withMergeOptions: mergeOptions:ParallelMergeOptions -> source:seq<'T> -> pseq<'T>
+
+        val withCancellation: cancellationToken:CancellationToken -> source:seq<'T> -> pseq<'T>
+
+
+// These are not available:
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the first N elements of the sequence.</summary>
+        /// <remarks>Throws <c>InvalidOperationException</c>
+        /// if the count exceeds the number of elements in the sequence. <c>Seq.truncate</c>
+        /// returns as many items as the sequence contains instead of throwing an exception.</remarks>
+        ///
+        /// <param name="count">The number of items to take.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when the input sequence is empty.</exception>
+        /// <exception cref="System.InvalidOperationException">Thrown when count exceeds the number of elements
+        /// in the sequence.</exception>
+//        [<CompiledName("Take")>]
+//        val take: count:int -> source:seq<'T> -> seq<'T>
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Applies the given function to successive elements, returning the first
+        /// result where the function returns "Some(x)".</summary>
+        ///
+        /// <param name="chooser">A function that transforms items from the input sequence into options.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+//        [<CompiledName("TryPick")>]
+//        val tryPick: chooser:('T -> 'U option) -> source:seq<'T> -> 'U option
+
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that contains the elements generated by the given computation.
+        /// The given initial <c>state</c> argument is passed to the element generator.
+        /// For each IEnumerator elements in the stream are generated on-demand by applying the element
+        /// generator, until a None value is returned by the element generator. Each call to the element
+        /// generator returns a new residual <c>state</c>.</summary>
+        ///
+        /// <remarks>The stream will be recomputed each time an IEnumerator is requested and iterated for the Seq.
+        ///
+        /// The returned sequence may be passed between threads safely. However, 
+        /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.</remarks>
+        ///
+        /// <param name="generator">A function that takes in the current state and returns an option tuple of the next
+        /// element of the sequence and the next state value.</param>
+        /// <param name="state">The initial state value.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+//        [<CompiledName("Unfold")>]
+//        val unfold   : generator:('State -> ('T * 'State) option) -> state:'State -> seq<'T>
+
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that yields sliding windows of containing elements drawn from the input
+        /// sequence. Each window is returned as a fresh array.</summary>
+        ///
+        /// <param name="windowSize">The number of elements in each window.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when the input sequence is empty.</exception>
+//        [<CompiledName("Windowed")>]
+//        val windowed: windowSize:int -> source:seq<'T> -> seq<'T[]>
+
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Combines the three sequences into a list of triples. The sequences need not have equal lengths:
+        /// when one sequence is exhausted any remaining elements in the other
+        /// sequences are ignored.</summary>
+        ///
+        /// <param name="source1">The first input sequence.</param>
+        /// <param name="source2">The second input sequence.</param>
+        /// <param name="source3">The third input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when any of the input sequences is null.</exception>
+//        [<CompiledName("Zip3")>]
+//        val zip3: source1:seq<'T1> -> source2:seq<'T2> -> source3:seq<'T3> -> seq<'T1 * 'T2 * 'T3>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the sum of the elements in the sequence.</summary>
+        ///
+        /// <remarks>The elements are summed using the <c>+</c> operator and <c>Zero</c> property associated with the generated type.</remarks>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+//        [<CompiledName("Sum")>]
+        val inline sum   : source:seq<(^T)> -> ^T 
+                                      when ^T : (static member ( + ) : ^T * ^T -> ^T) 
+                                      and  ^T : (static member Zero : ^T)
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the sum of the results generated by applying the function to each element of the sequence.</summary>
+        /// <remarks>The generated elements are summed using the <c>+</c> operator and <c>Zero</c> property associated with the generated type.</remarks>
+        ///
+        /// <param name="projection">A function to transform items from the input sequence into the type that will be summed.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+//        [<CompiledName("SumBy")>]
+        val inline sumBy   : projection:('T -> ^U) -> source:seq<'T>  -> ^U 
+                                      when ^U : (static member ( + ) : ^U * ^U -> ^U) 
+                                      and  ^U : (static member Zero : ^U)
+
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Like fold, but computes on-demand and returns the sequence of intermediary and final results.</summary>
+        ///
+        /// <param name="folder">A function that updates the state with each element from the sequence.</param>
+        /// <param name="state">The initial state.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+//        [<CompiledName("Scan")>]
+//        val scan<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> seq<'State>
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Builds a new sequence object that delegates to the given sequence object. This ensures 
+        /// the original sequence cannot be rediscovered and mutated by a type cast. For example, 
+        /// if given an array the returned sequence will return the elements of the array, but
+        /// you cannot cast the returned sequence object to an array.</summary>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+//        [<CompiledName("ReadOnly")>]
+//        val readonly : source:seq<'T> -> seq<'T>
+//
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the lowest of all elements of the sequence, compared via <c>Operators.min</c>.</summary>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when the input sequence is empty.</exception>
+//        [<CompiledName("Min")>]
+        val inline min     : source:seq<(^T)> -> ^T when ^T : comparison 
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the lowest of all elements of the sequence, compared via Operators.min on the function result.</summary>
+        ///
+        /// <param name="projection">A function to transform items from the input sequence into comparable keys.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when the input sequence is empty.</exception>
+//        [<CompiledName("MinBy")>]
+        val inline minBy  : projection:(^T -> ^U) -> source:seq<(^T)> -> ^T when ^U : comparison 
+
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence of each element in the input sequence and its predecessor, with the
+        /// exception of the first element which is only returned as the predecessor of the second element.</summary>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+//        [<CompiledName("Pairwise")>]
+//        val pairwise: source:seq<'T> -> seq<'T * 'T>
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the greatest of all elements of the sequence, compared via Operators.max</summary>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when the input sequence is empty.</exception>
+        ///
+        /// <returns>The result sequence.</returns>
+//        [<CompiledName("Max")>]
+        val inline max     : source:seq<(^T)> -> ^T when ^T : comparison 
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the greatest of all elements of the sequence, compared via Operators.max on the function result.</summary>
+        ///
+        /// <param name="projection">A function to transform items from the input sequence into comparable keys.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when the input sequence is empty.</exception>
+//        [<CompiledName("MaxBy")>]
+        val inline maxBy  : projection:(^T -> ^U) -> source:seq<(^T)> -> ^T when ^U : comparison 
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Generates a new sequence which, when iterated, will return successive
+        /// elements by calling the given function.  The results of calling the function
+        /// will not be saved, that is the function will be reapplied as necessary to
+        /// regenerate the elements.  The function is passed the index of the item being
+        /// generated.</summary>
+        ///
+        /// <remarks>The returned sequence may be passed between threads safely. However, 
+        /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.
+        /// Iteration can continue up to <c>Int32.MaxValue</c>.</remarks>
+        ///
+        /// <param name="initializer">A function that generates an item in the sequence from a given index.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+//        [<CompiledName("InitializeInfinite")>]
+//        val initInfinite: initializer:(int -> 'T) -> seq<'T>
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that is built from the given delayed specification of a
+        /// sequence.</summary>
+        ///
+        /// <remarks>The input function is evaluated each time an IEnumerator for the sequence 
+        /// is requested.</remarks>
+        ///
+        /// <param name="generator">The generating function for the sequence.</param>
+//        [<CompiledName("Delay")>]
+//        val delay   : generator:(unit -> seq<'T>) -> seq<'T>
+//
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Compares two sequences using the given comparison function, element by element.
+        /// Returns the first non-zero result from the comparison function.  If the end of a sequence
+        /// is reached it returns a -1 if the first sequence is shorter and a 1 if the second sequence
+        /// is shorter.</summary>
+        ///
+        /// <param name="comparer">A function that takes an element from each sequence and returns an int.
+        /// If it evaluates to a non-zero value iteration is stopped and that value is returned.</param>
+        /// <param name="source1">The first input sequence.</param>
+        /// <param name="source2">The second input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when either of the input sequences
+        /// is null.</exception>
+//        [<CompiledName("CompareWith")>]
+//        val compareWith: comparer:('T -> 'T -> int) -> source1:seq<'T> -> source2:seq<'T> -> int
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns a sequence that corresponds to a cached version of the input sequence.
+        /// This result sequence will have the same elements as the input sequence. The result 
+        /// can be enumerated multiple times. The input sequence will be enumerated at most 
+        /// once and only as far as is necessary.  Caching a sequence is typically useful when repeatedly
+        /// evaluating items in the original sequence is computationally expensive or if
+        /// iterating the sequence causes side-effects that the user does not want to be
+        /// repeated multiple times.
+        ///
+        /// Enumeration of the result sequence is thread safe in the sense that multiple independent IEnumerator
+        /// values may be used simultaneously from different threads (accesses to 
+        /// the internal lookaside table are thread safe). Each individual IEnumerator
+        /// is not typically thread safe and should not be accessed concurrently.</summary>
+        ///
+        /// <remarks>Once enumeration of the input sequence has started,
+        /// it's enumerator will be kept live by this object until the enumeration has completed.
+        /// At that point, the enumerator will be disposed. 
+        ///
+        /// The enumerator may be disposed and underlying cache storage released by 
+        /// converting the returned sequence object to type IDisposable, and calling the Dispose method
+        /// on this object. The sequence object may then be re-enumerated and a fresh enumerator will
+        /// be used.</remarks>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+//        [<CompiledName("Cache")>]
+//        val cache: source:seq<'T> -> seq<'T>
+
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the average of the elements in the sequence.</summary>
+        ///
+        /// <remarks>The elements are averaged using the <c>+</c> operator, <c>DivideByInt</c> method and <c>Zero</c> property 
+        /// associated with the element type.</remarks>
+        ///
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when the input sequence has zero elements.</exception>
+//        [<CompiledName("Average")>]
+        val inline average   : source:seq<(^T)> -> ^T 
+                                      when ^T : (static member ( + ) : ^T * ^T -> ^T) 
+                                      and  ^T : (static member DivideByInt : ^T * int -> ^T) 
+                                      and  ^T : (static member Zero : ^T)
+
+        /// <summary>Operates in parallel, using System.Linq.Parallel. Returns the average of the results generated by applying the function to each element 
+        /// of the sequence.</summary>
+        ///
+        /// <remarks>The elements are averaged using the <c>+</c> operator, <c>DivideByInt</c> method and <c>Zero</c> property 
+        /// associated with the generated type.</remarks>
+        ///
+        /// <param name="projection">A function applied to transform each element of the sequence.</param>
+        /// <param name="source">The input sequence.</param>
+        ///
+        /// <returns>The result sequence.</returns>
+        ///
+        /// <exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when the input sequence has zero elements.</exception>
+//        [<CompiledName("AverageBy")>]
+        val inline averageBy   : projection:('T -> ^U) -> source:seq<'T>  -> ^U 
+                                      when ^U : (static member ( + ) : ^U * ^U -> ^U) 
+                                      and  ^U : (static member DivideByInt : ^U * int -> ^U) 
+                                      and  ^U : (static member Zero : ^U)
+
diff --git a/src/FSharp.PowerPack.Parallel.Seq/pseq.fsx b/src/FSharp.PowerPack.Parallel.Seq/pseq.fsx
new file mode 100755
index 0000000..77715df
--- /dev/null
+++ b/src/FSharp.PowerPack.Parallel.Seq/pseq.fsx
@@ -0,0 +1,49 @@
+#r "System.Core.dll"
+
+#load "PSeq.fs"
+
+open Microsoft.FSharp.Collections
+
+let isPrime n = 
+    let upperBound = int (sqrt (float n))
+    let hasDivisor =     
+        [2..upperBound]
+        |> List.exists (fun i -> n % i = 0)
+    not hasDivisor
+        
+let nums = [|1..500000|]
+
+let finalDigitOfPrimes = 
+    nums 
+    |> PSeq.filter isPrime
+    |> PSeq.groupBy (fun i -> i % 10)
+    |> PSeq.map (fun (k, vs) -> (k, Seq.length vs))
+    |> PSeq.toArray
+
+let averageOfFinalDigit = 
+    nums 
+    |> PSeq.filter isPrime
+    |> PSeq.groupBy (fun i -> i % 10)
+    |> PSeq.map (fun (k, vs) -> (k, Seq.length vs))
+    |> PSeq.averageBy (fun (k,n) -> float n)
+
+let sumOfLastDigitsOfPrimes = 
+    nums 
+    |> PSeq.filter isPrime
+    |> PSeq.sumBy (fun x -> x % 10)
+
+open System
+open System.Linq
+let stringSeq1:seq<string> = seq ["1";"2"]
+let stringSeq2:seq<string> = seq ["3";"4"]
+
+let appendStringSeq = System.Linq.ParallelEnumerable.Concat(stringSeq1.AsParallel(), stringSeq2.AsParallel())
+
+let expectedResultString = seq ["1";"2";"3";"4"]
+
+let res = 
+    System.Linq.ParallelEnumerable.All(System.Linq.ParallelEnumerable.Zip(expectedResultString.AsParallel(), 
+                                                                          appendStringSeq.AsParallel(), 
+                                                                          Func<_,_,_>(fun x y -> x,y)),
+                                       Func<_,bool>(fun (x,y) -> x = y))
+
diff --git a/src/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj b/src/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj
new file mode 100755
index 0000000..c444425
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <TOOLS Condition=" '$(TOOLS)' == '' ">..\..\tools</TOOLS>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{1B749E89-2B1A-4443-A522-EEB348E01555}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>FSharp.PowerPack.Unittests.v40</RootNamespace>
+    <AssemblyName>FSharp.PowerPack.Unittests.v40</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <StrongName>false</StrongName>
+    <!--->ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB}</ProjectTypeGuids-->
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>62</NoWarn>
+    <OtherFlags>--mlcompatibility</OtherFlags>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>62</NoWarn>
+    <OtherFlags>--mlcompatibility</OtherFlags>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="LibraryTestFx.fs" />
+    <Compile Include="Utilities.fs" />
+    <Compile Include="SeqModule.fs" />
+    <Compile Include="SeqModule2.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="FSharp.Core" />
+    <Reference Include="nunit.framework">
+      <HintPath>$(TOOLS)\NUnit\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Data.Linq" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\FSharp.PowerPack.Parallel.Seq\FSharp.PowerPack.Parallel.Seq.fsproj">
+      <Name>FSharp.PowerPack.Parallel.Seq</Name>
+      <Project>{24a845cd-b684-46fb-abca-979013f5015b}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj.vspscc b/src/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FSharp.PowerPack.Unittests.v40/LibraryTestFx.fs b/src/FSharp.PowerPack.Unittests.v40/LibraryTestFx.fs
new file mode 100755
index 0000000..65667bf
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests.v40/LibraryTestFx.fs
@@ -0,0 +1,67 @@
+
+module FSharp.Core.Unittests.LibraryTestFx
+
+open System
+open System.Collections.Generic
+open Microsoft.FSharp.Collections
+open System.Linq
+
+open NUnit.Framework
+
+// Workaround for bug 3601, we are issuing an unnecessary warning
+#nowarn "0004"
+
+/// Check that the lamda throws an exception of the given type. Otherwise
+/// calls Assert.Fail()
+let private CheckThrowsExn<'a when 'a :> exn> (f : unit -> unit) =
+    let funcThrowsAsExpected =
+        try
+            let _ = f ()
+            Some "no exception" // Did not throw!
+        with
+        | :? 'a
+            -> None // Thew null ref, OK
+        | exn -> Some  (exn.ToString()) // Did now throw a null ref exception!
+    match funcThrowsAsExpected with
+    | None -> ()
+    | Some s -> Assert.Fail(s)
+
+let private CheckThrowsExn2<'a when 'a :> exn> s (f : unit -> unit) =
+    let funcThrowsAsExpected =
+        try
+            let _ = f ()
+            false // Did not throw!
+        with
+        | :? 'a
+            -> true   // Thew null ref, OK
+        | _ -> false  // Did now throw a null ref exception!
+    if funcThrowsAsExpected
+    then ()
+    else Assert.Fail(s)
+
+// Illegitimate exceptions. Once we've scrubbed the library, we should add an
+// attribute to flag these exception's usage as a bug.
+let CheckThrowsNullRefException      f = CheckThrowsExn<NullReferenceException>   f
+let CheckThrowsIndexOutRangException f = CheckThrowsExn<IndexOutOfRangeException> f
+
+// Legit exceptions
+let CheckThrowsNotSupportedException f = CheckThrowsExn<NotSupportedException>    f
+let CheckThrowsArgumentException     f = CheckThrowsExn<ArgumentException>        f
+let CheckThrowsArgumentNullException f = CheckThrowsExn<ArgumentNullException>    f
+let CheckThrowsArgumentNullException2 s f  = CheckThrowsExn2<ArgumentNullException>  s  f
+let CheckThrowsKeyNotFoundException  f = CheckThrowsExn<KeyNotFoundException>     f
+let CheckThrowsDivideByZeroException f = CheckThrowsExn<DivideByZeroException>    f
+let CheckThrowsInvalidOperationExn   f = CheckThrowsExn<InvalidOperationException> f
+let CheckThrowsFormatException       f = CheckThrowsExn<FormatException>           f
+let CheckThrowsAggregateException    f = CheckThrowsExn<AggregateException>           f
+
+// Verifies two sequences are equal (same length, equiv elements)
+let VerifyPSeqsEqual seq1 seq2 =
+    let len1 = PSeq.length seq1
+    let len2 = PSeq.length seq2
+    if len1 <> len2 then Assert.Fail(sprintf "seqs not equal length: %d and %d" len1 len2)
+    let set1 = set seq1
+    let set2 = set seq2
+    if set1 = set2
+    then ()
+    else Assert.Fail(sprintf "contents not the same: %A %A" set1 set2)
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests.v40/SeqModule.fs b/src/FSharp.PowerPack.Unittests.v40/SeqModule.fs
new file mode 100755
index 0000000..0c47afb
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests.v40/SeqModule.fs
@@ -0,0 +1,790 @@
+
+namespace FSharp.Core.Unittests.FSharp_Core.Microsoft_FSharp_Collections
+
+open System
+open NUnit.Framework
+open Microsoft.FSharp.Collections
+
+open FSharp.Core.Unittests.LibraryTestFx
+
+// Various tests for the:
+// Microsoft.FSharp.Collections.seq type
+
+(*
+[Test Strategy]
+Make sure each method works on:
+* Integer Seq (value type)
+* String Seq  (reference type)
+* Empty Seq   (0 elements)
+* Null Seq    (null)
+*)
+
+[<TestFixture>]
+type SeqModule() =
+
+//    [<Test>]
+//    member this.CachedSeq_Clear() =
+//     
+//        let evaluatedItems : int list ref = ref []
+//        let cachedSeq = 
+//            PSeq.initInfinite (fun i -> evaluatedItems := i :: !evaluatedItems; i)
+//            |> PSeq.cache
+//        
+//        // Verify no items have been evaluated from the Seq yet
+//        Assert.AreEqual(List.length !evaluatedItems, 0)
+//        
+//        // Force evaluation of 10 elements
+//        PSeq.take 10 cachedSeq
+//        |> PSeq.toList
+//        |> ignore
+//        
+//        // verify ref clear switch length
+//        Assert.AreEqual(List.length !evaluatedItems, 10)
+//
+//        // Force evaluation of 10 elements
+//        PSeq.take 10 cachedSeq
+//        |> PSeq.toList
+//        |> ignore
+//        
+//        // Verify ref clear switch length (should be cached)
+//        Assert.AreEqual(List.length !evaluatedItems, 10)
+//
+//        
+//        // Clear
+//        (box cachedSeq :?> System.IDisposable) .Dispose()
+//        
+//        // Force evaluation of 10 elements
+//        PSeq.take 10 cachedSeq
+//        |> PSeq.toList
+//        |> ignore
+//        
+//        // Verify length of evaluatedItemList is 20
+//        Assert.AreEqual(List.length !evaluatedItems, 20)
+//        ()
+        
+    [<Test>]
+    member this.Append() =
+
+        // empty Seq 
+        let emptySeq1 = PSeq.empty
+        let emptySeq2 = PSeq.empty
+        let appendEmptySeq = PSeq.append emptySeq1 emptySeq2
+        let expectResultEmpty = PSeq.empty
+           
+        VerifyPSeqsEqual expectResultEmpty appendEmptySeq
+          
+        // Integer Seq  
+        let integerSeq1:seq<int> = seq [0..4]
+        let integerSeq2:seq<int> = seq [5..9]
+         
+        let appendIntergerSeq = PSeq.append integerSeq1 integerSeq2
+       
+        let expectResultInteger = seq { for i in 0..9 -> i}
+        
+        VerifyPSeqsEqual expectResultInteger appendIntergerSeq
+        
+        
+        // String Seq
+        let stringSeq1:seq<string> = seq ["1";"2"]
+        let stringSeq2:seq<string> = seq ["3";"4"]
+        
+        let appendStringSeq = PSeq.append stringSeq1 stringSeq2
+        
+        let expectedResultString = seq ["1";"2";"3";"4"]
+        
+        VerifyPSeqsEqual expectedResultString appendStringSeq
+        
+        // null Seq
+        let nullSeq1 = seq [null;null]
+
+        let nullSeq2 =seq [null;null]
+
+        let appendNullSeq = PSeq.append nullSeq1 nullSeq2
+        
+        let expectedResultNull = seq [ null;null;null;null]
+        
+        VerifyPSeqsEqual expectedResultNull appendNullSeq
+        ()
+        
+        
+    [<Test>]
+    member this.Average() =
+        // empty Seq 
+        let emptySeq:pseq<double> = PSeq.empty<double>
+        
+        CheckThrowsInvalidOperationExn (fun () ->  PSeq.average emptySeq |> ignore)
+        
+            
+        // double Seq
+        let doubleSeq:seq<double> = seq [1.0;2.2;2.5;4.3]
+        
+        let averageDouble = PSeq.average doubleSeq
+        
+        Assert.IsFalse( averageDouble <> 2.5)
+        
+        // float32 Seq
+        let floatSeq:seq<float32> = seq [ 2.0f;4.4f;5.0f;8.6f]
+        
+        let averageFloat = PSeq.average floatSeq
+        
+        Assert.IsFalse( averageFloat <> 5.0f)
+        
+        // decimal Seq
+        let decimalSeq:seq<decimal> = seq [ 0M;19M;19.03M]
+        
+        let averageDecimal = PSeq.average decimalSeq
+        
+        Assert.IsFalse( averageDecimal <> 12.676666666666666666666666667M )
+        
+        // null Seq
+        let nullSeq:seq<double> = null
+            
+        CheckThrowsArgumentNullException (fun () -> PSeq.average nullSeq |> ignore) 
+        ()
+        
+        
+    [<Test>]
+    member this.AverageBy() =
+        // empty Seq 
+        let emptySeq:pseq<double> = PSeq.empty<double>
+        
+        CheckThrowsInvalidOperationExn (fun () ->  PSeq.averageBy (fun x -> x+1.0) emptySeq |> ignore)
+        
+        // double Seq
+        let doubleSeq:seq<double> = seq [1.0;2.2;2.5;4.3]
+        
+        let averageDouble = PSeq.averageBy (fun x -> x-2.0) doubleSeq
+        
+        Assert.IsFalse( averageDouble <> 0.5 )
+        
+        // float32 Seq
+        let floatSeq:seq<float32> = seq [ 2.0f;4.4f;5.0f;8.6f]
+        
+        let averageFloat = PSeq.averageBy (fun x -> x*3.3f)  floatSeq
+        
+        Assert.IsFalse( averageFloat <> 16.5f )
+        
+        // decimal Seq
+        let decimalSeq:seq<decimal> = seq [ 0M;19M;19.03M]
+        
+        let averageDecimal = PSeq.averageBy (fun x -> x/10.7M) decimalSeq
+        
+        Assert.IsFalse( averageDecimal <> 1.1847352024922118380062305296M )
+        
+        // null Seq
+        let nullSeq:seq<double> = null
+            
+        CheckThrowsArgumentNullException (fun () -> PSeq.averageBy (fun (x:double)->x+4.0) nullSeq |> ignore) 
+        ()
+        
+//    [<Test>]
+//    member this.Cache() =
+//        // empty Seq 
+//        let emptySeq:pseq<double> = PSeq.empty<double>
+//        
+//        let cacheEmpty = PSeq.cache emptySeq
+//        
+//        let expectedResultEmpty = PSeq.empty
+//        
+//        VerifyPSeqsEqual expectedResultEmpty cacheEmpty
+//               
+//        // double Seq
+//        let doubleSeq:seq<double> = seq [1.0;2.2;2.5;4.3]
+//        
+//        let cacheDouble = PSeq.cache doubleSeq
+//        
+//        VerifyPSeqsEqual doubleSeq cacheDouble
+//        
+//            
+//        // float32 Seq
+//        let floatSeq:seq<float32> = seq [ 2.0f;4.4f;5.0f;8.6f]
+//        
+//        let cacheFloat = PSeq.cache floatSeq
+//        
+//        VerifyPSeqsEqual floatSeq cacheFloat
+//        
+//        // decimal Seq
+//        let decimalSeq:seq<decimal> = seq [ 0M; 19M; 19.03M]
+//        
+//        let cacheDecimal = PSeq.cache decimalSeq
+//        
+//        VerifyPSeqsEqual decimalSeq cacheDecimal
+//        
+//        // null Seq
+//        let nullSeq = seq [null]
+//        
+//        let cacheNull = PSeq.cache nullSeq
+//        
+//        VerifyPSeqsEqual nullSeq cacheNull
+//        ()
+
+    [<Test>]
+    member this.Case() =
+
+        // integer Seq
+        let integerArray = [|1;2|]
+        let integerSeq = PSeq.cast integerArray
+        
+        let expectedIntegerSeq = seq [1;2]
+        
+        VerifyPSeqsEqual expectedIntegerSeq integerSeq
+        
+        // string Seq
+        let stringArray = [|"a";"b"|]
+        let stringSeq = PSeq.cast stringArray
+        
+        let expectedStringSeq = seq["a";"b"]
+        
+        VerifyPSeqsEqual expectedStringSeq stringSeq
+        
+        // empty Seq
+        let emptySeq = PSeq.cast PSeq.empty
+        let expectedEmptySeq = PSeq.empty
+        
+        VerifyPSeqsEqual expectedEmptySeq PSeq.empty
+        
+        // null Seq
+        let nullArray = [|null;null|]
+        let NullSeq = PSeq.cast nullArray
+        let expectedNullSeq = seq [null;null]
+        
+        VerifyPSeqsEqual expectedNullSeq NullSeq
+        
+        
+        ()
+        
+    [<Test>]
+    member this.Choose() =
+        
+        // int Seq
+        let intSeq = seq [1..20]    
+        let funcInt x = if (x%5=0) then Some x else None       
+        let intChoosed = PSeq.choose funcInt intSeq
+        let expectedIntChoosed = seq { for i = 1 to 4 do yield i*5}
+        
+        
+       
+        VerifyPSeqsEqual expectedIntChoosed intChoosed
+        
+        // string Seq
+        let stringSrc = seq ["list";"List"]
+        let funcString x = match x with
+                           | "list"-> Some x
+                           | "List" -> Some x
+                           | _ -> None
+        let strChoosed = PSeq.choose funcString stringSrc   
+        let expectedStrChoose = seq ["list";"List"]
+      
+        VerifyPSeqsEqual expectedStrChoose strChoosed
+        
+        // empty Seq
+        let emptySeq = PSeq.empty
+        let emptyChoosed = PSeq.choose funcInt emptySeq
+        
+        let expectedEmptyChoose = PSeq.empty
+        
+        VerifyPSeqsEqual expectedEmptyChoose emptySeq
+        
+
+        // null Seq
+        let nullSeq:seq<'a> = null    
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.choose funcInt nullSeq |> ignore) 
+        ()
+    
+//    [<Test>]
+//    member this.Compare() =
+//    
+//        // int Seq
+//        let intSeq1 = seq [1;3;7;9]    
+//        let intSeq2 = seq [2;4;6;8] 
+//        let funcInt x y = if (x>y) then x else 0
+//        let intcompared = PSeq.compareWith funcInt intSeq1 intSeq2
+//       
+//        Assert.IsFalse( intcompared <> 7 )
+//        
+//        // string Seq
+//        let stringSeq1 = seq ["a"; "b"]
+//        let stringSeq2 = seq ["c"; "d"]
+//        let funcString x y = match (x,y) with
+//                             | "a", "c" -> 0
+//                             | "b", "d" -> 1
+//                             |_         -> -1
+//        let strcompared = PSeq.compareWith funcString stringSeq1 stringSeq2  
+//        Assert.IsFalse( strcompared <> 1 )
+//         
+//        // empty Seq
+//        let emptySeq = PSeq.empty
+//        let emptycompared = PSeq.compareWith funcInt emptySeq emptySeq
+//        
+//        Assert.IsFalse( emptycompared <> 0 )
+//       
+//        // null Seq
+//        let nullSeq:seq<int> = null    
+//         
+//        CheckThrowsArgumentNullException (fun () -> PSeq.compareWith funcInt nullSeq emptySeq |> ignore)  
+//        CheckThrowsArgumentNullException (fun () -> PSeq.compareWith funcInt emptySeq nullSeq |> ignore)  
+//        CheckThrowsArgumentNullException (fun () -> PSeq.compareWith funcInt nullSeq nullSeq |> ignore)  
+//
+//        ()
+        
+    [<Test>]
+    member this.Concat() =
+         // integer Seq
+        let seqInt = 
+            seq { for i in 0..9 do                
+                    yield seq {for j in 0..9 do
+                                yield i*10+j}}
+        let conIntSeq = PSeq.concat seqInt
+        let expectedIntSeq = seq { for i in 0..99 do yield i}
+        
+        VerifyPSeqsEqual expectedIntSeq conIntSeq
+         
+        // string Seq
+        let strSeq = 
+            seq { for a in 'a' .. 'b' do
+                    for b in 'a' .. 'b' do
+                        yield seq [a; b] }
+     
+        let conStrSeq = PSeq.concat strSeq
+        let expectedStrSeq = seq ['a';'a';'a';'b';'b';'a';'b';'b';]
+        VerifyPSeqsEqual expectedStrSeq conStrSeq
+        
+//        // Empty Seq
+//        let emptySeqs = seq [seq[ PSeq.empty;PSeq.empty];seq[ PSeq.empty;PSeq.empty]]
+//        let conEmptySeq = PSeq.concat emptySeqs
+//        let expectedEmptySeq =seq { for i in 1..4 do yield PSeq.empty}
+//        
+//        VerifyPSeqsEqual expectedEmptySeq conEmptySeq   
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.concat nullSeq  |> ignore) 
+ 
+        () 
+        
+    [<Test>]
+    member this.CountBy() =
+        // integer Seq
+        let funcIntCount_by (x:int) = x%3 
+        let seqInt = 
+            seq { for i in 0..9 do                
+                    yield i}
+        let countIntSeq = PSeq.countBy funcIntCount_by seqInt
+         
+        let expectedIntSeq = seq [0,4;1,3;2,3]
+        
+        VerifyPSeqsEqual expectedIntSeq countIntSeq
+         
+        // string Seq
+        let funcStrCount_by (s:string) = s.IndexOf("key")
+        let strSeq = seq [ "key";"blank key";"key";"blank blank key"]
+       
+        let countStrSeq = PSeq.countBy funcStrCount_by strSeq
+        let expectedStrSeq = seq [0,2;6,1;12,1]
+        VerifyPSeqsEqual expectedStrSeq countStrSeq
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let countEmptySeq = PSeq.countBy funcIntCount_by emptySeq
+        let expectedEmptySeq =seq []
+        
+        VerifyPSeqsEqual expectedEmptySeq countEmptySeq  
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+       
+        CheckThrowsArgumentNullException (fun () -> PSeq.countBy funcIntCount_by nullSeq  |> ignore) 
+        () 
+    
+    [<Test>]
+    member this.Distinct() =
+        
+        // integer Seq
+        let IntDistinctSeq =  
+            seq { for i in 0..9 do                
+                    yield i % 3 }
+       
+        let DistinctIntSeq = PSeq.distinct IntDistinctSeq
+       
+        let expectedIntSeq = seq [0;1;2]
+        
+        VerifyPSeqsEqual expectedIntSeq DistinctIntSeq
+     
+        // string Seq
+        let strDistinctSeq = seq ["elementDup"; "ele1"; "ele2"; "elementDup"]
+       
+        let DistnctStrSeq = PSeq.distinct strDistinctSeq
+        let expectedStrSeq = seq ["elementDup"; "ele1"; "ele2"]
+        VerifyPSeqsEqual expectedStrSeq DistnctStrSeq
+
+        // array Seq
+        let arrDistinctSeq = seq [[|1|];[|1;2|]; [|1|];[|3|]]
+       
+        let DistnctArrSeq = PSeq.distinct arrDistinctSeq
+        let expectedArrSeq = seq [[|1|]; [|1; 2|]; [|3|]]
+        VerifyPSeqsEqual expectedArrSeq DistnctArrSeq
+        
+        
+        // Empty Seq
+        let emptySeq : pseq<decimal * unit>         = PSeq.empty
+        let distinctEmptySeq : pseq<decimal * unit> = PSeq.distinct emptySeq
+        let expectedEmptySeq : pseq<decimal * unit> = PSeq.ofList []
+       
+        VerifyPSeqsEqual expectedEmptySeq distinctEmptySeq
+
+        // null Seq
+        let nullSeq:seq<unit> = null
+       
+        CheckThrowsArgumentNullException(fun () -> PSeq.distinct nullSeq  |> ignore) 
+        () 
+    
+    [<Test>]
+    member this.DistinctBy () =
+        // integer Seq
+        let funcInt x = x % 3 
+        let IntDistinct_bySeq =  
+            seq { for i in 0..9 do                
+                    yield i }
+       
+        let distinct_byIntSeq = PSeq.distinctBy funcInt IntDistinct_bySeq
+        
+        Assert.AreEqual(3, PSeq.length distinct_byIntSeq )
+        
+        let mappedBack = distinct_byIntSeq |> PSeq.map funcInt
+
+        let expectedIntSeq = seq [0;1;2]
+        
+        VerifyPSeqsEqual expectedIntSeq mappedBack 
+             
+        // string Seq
+        let funcStrDistinct (s:string) = s.IndexOf("key")
+        let strSeq = seq [ "key"; "blank key"; "key dup"; "blank key dup"]
+       
+        let DistnctStrSeq = PSeq.distinctBy funcStrDistinct strSeq
+        let expectedStrSeq = seq ["key"; "blank key"]
+        VerifyPSeqsEqual expectedStrSeq DistnctStrSeq
+        
+        // Empty Seq
+        let emptySeq            : pseq<int> = PSeq.empty
+        let distinct_byEmptySeq : pseq<int> = PSeq.distinctBy funcInt emptySeq
+        let expectedEmptySeq    : pseq<int> = PSeq.ofList []
+       
+        VerifyPSeqsEqual expectedEmptySeq distinct_byEmptySeq
+
+        // null Seq
+        let nullSeq : seq<'a> = null
+       
+        CheckThrowsArgumentNullException(fun () -> PSeq.distinctBy funcInt nullSeq  |> ignore) 
+        () 
+    
+    [<Test>]
+    member this.Exists() =
+
+        // Integer Seq
+        let funcInt x = (x % 2 = 0) 
+        let IntexistsSeq =  
+            seq { for i in 0..9 do                
+                    yield i}
+       
+        let ifExistInt = PSeq.exists funcInt IntexistsSeq
+        
+        Assert.IsTrue( ifExistInt) 
+            
+        // String Seq
+        let funcStr (s:string) = s.Contains("key")
+        let strSeq = seq ["key"; "blank key"]
+       
+        let ifExistStr = PSeq.exists funcStr strSeq
+        
+        Assert.IsTrue( ifExistStr)
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let ifExistsEmpty = PSeq.exists funcInt emptySeq
+        
+        Assert.IsFalse( ifExistsEmpty)
+       
+        
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+           
+        CheckThrowsArgumentNullException (fun () -> PSeq.exists funcInt nullSeq |> ignore) 
+        () 
+    
+    [<Test>]
+    member this.Exists2() =
+        // Integer Seq
+        let funcInt x y = (x+y)%3=0 
+        let Intexists2Seq1 =  seq [1;3;7]
+        let Intexists2Seq2 = seq [1;6;3]
+            
+        let ifExist2Int = PSeq.exists2 funcInt Intexists2Seq1 Intexists2Seq2
+        Assert.IsTrue( ifExist2Int)
+             
+        // String Seq
+        let funcStr s1 s2 = ((s1 + s2) = "CombinedString")
+        let strSeq1 = seq [ "Combined"; "Not Combined"] |> PSeq.ordered
+        let strSeq2 = seq [ "String";   "Other String"] |> PSeq.ordered
+        let ifexists2Str = PSeq.exists2 funcStr strSeq1 strSeq2
+        Assert.IsTrue(ifexists2Str)
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let ifexists2Empty = PSeq.exists2 funcInt emptySeq emptySeq
+        Assert.IsFalse( ifexists2Empty)
+       
+        // null Seq
+        let nullSeq:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.exists2 funcInt nullSeq nullSeq |> ignore) 
+        () 
+    
+    
+    [<Test>]
+    member this.Filter() =
+        // integer Seq
+        let funcInt x = if (x % 5 = 0) then true else false
+        let IntSeq =
+            seq { for i in 1..20 do
+                    yield i }
+                    
+        let filterIntSeq = PSeq.filter funcInt IntSeq
+          
+        let expectedfilterInt = seq [ 5;10;15;20]
+        
+        VerifyPSeqsEqual expectedfilterInt filterIntSeq
+        
+        // string Seq
+        let funcStr (s:string) = s.Contains("Expected Content")
+        let strSeq = seq [ "Expected Content"; "Not Expected"; "Expected Content"; "Not Expected"]
+        
+        let filterStrSeq = PSeq.filter funcStr strSeq
+        
+        let expectedfilterStr = seq ["Expected Content"; "Expected Content"]
+        
+        VerifyPSeqsEqual expectedfilterStr filterStrSeq    
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let filterEmptySeq = PSeq.filter funcInt emptySeq
+        
+        let expectedEmptySeq =seq []
+       
+        VerifyPSeqsEqual expectedEmptySeq filterEmptySeq
+       
+        
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.filter funcInt nullSeq  |> ignore) 
+        () 
+    
+    [<Test>]
+    member this.Find() =
+        
+        // integer Seq
+        let funcInt x = if (x % 5 = 0) then true else false
+        let IntSeq =
+            seq { for i in 1..20 do
+                    yield i }
+                    
+        let findInt = PSeq.find funcInt IntSeq
+        Assert.AreEqual(findInt, 5)  
+             
+        // string Seq
+        let funcStr (s:string) = s.Contains("Expected Content")
+        let strSeq = seq [ "Expected Content";"Not Expected"]
+        
+        let findStr = PSeq.find funcStr strSeq
+        Assert.AreEqual(findStr, "Expected Content")
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.find funcInt emptySeq |> ignore)
+       
+        // null Seq
+        let nullSeq:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.find funcInt nullSeq |> ignore) 
+        ()
+    
+    [<Test>]
+    member this.FindIndex() =
+        
+        // integer Seq
+        let digits = [1 .. 100] |> PSeq.ofList
+        let idx = digits |> PSeq.findIndex (fun i -> i.ToString().Length > 1)
+        Assert.AreEqual(idx, 9)
+
+        // empty Seq 
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.findIndex (fun i -> true) PSeq.empty |> ignore)
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.findIndex (fun i -> true) null |> ignore)
+        ()
+    
+    [<Test>]
+    member this.Pick() =
+    
+        let digits = [| 1 .. 10 |] |> PSeq.ofArray
+        let result = PSeq.pick (fun i -> if i > 5 then Some(i.ToString()) else None) digits
+        Assert.AreEqual(result, "6")
+        
+        // Empty seq (Bugged, 4173)
+        CheckThrowsKeyNotFoundException (fun () -> PSeq.pick (fun i -> Some('a')) ([| |] : int[]) |> ignore)
+
+        // Null
+        CheckThrowsArgumentNullException (fun () -> PSeq.pick (fun i -> Some(i + 0)) null |> ignore)
+        ()
+        
+    [<Test>]
+    member this.Fold() =
+        let funcInt x y = x+y
+             
+        let IntSeq =
+            seq { for i in 1..10 do
+                    yield i}
+                    
+        let foldInt = PSeq.fold funcInt 1 IntSeq
+        if foldInt <> 56 then Assert.Fail()
+        
+        // string Seq
+        let funcStr (x:string) (y:string) = x+y
+        let strSeq = seq ["B"; "C";  "D" ; "E"]
+        let foldStr = PSeq.fold  funcStr "A" strSeq
+      
+        if foldStr <> "ABCDE" then Assert.Fail()
+        
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let foldEmpty = PSeq.fold funcInt 1 emptySeq
+        if foldEmpty <> 1 then Assert.Fail()
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.fold funcInt 1 nullSeq |> ignore) 
+        () 
+        
+    [<Test>]
+    member this.ForAll() =
+
+        let funcInt x  = if x%2 = 0 then true else false
+        let IntSeq =
+            seq { for i in 1..10 do
+                    yield i*2}
+        let for_allInt = PSeq.forall funcInt  IntSeq
+           
+        if for_allInt <> true then Assert.Fail()
+        
+             
+        // string Seq
+        let funcStr (x:string)  = x.Contains("a")
+        let strSeq = seq ["a"; "ab";  "abc" ; "abcd"]
+        let for_allStr = PSeq.forall  funcStr strSeq
+       
+        if for_allStr <> true then Assert.Fail()
+        
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let for_allEmpty = PSeq.forall funcInt emptySeq
+        
+        if for_allEmpty <> true then Assert.Fail()
+        
+        // null Seq
+        let nullSeq:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.forall funcInt  nullSeq |> ignore) 
+        () 
+        
+    [<Test>]
+    member this.ForAll2() =
+
+        let funcInt x y = if (x+y)%2 = 0 then true else false
+        let IntSeq =
+            seq { for i in 1..10 do
+                    yield i}
+            |> PSeq.ordered
+                    
+        let for_all2Int = PSeq.forall2 funcInt  IntSeq IntSeq
+           
+        if for_all2Int <> true then Assert.Fail()
+        
+        // string Seq
+        let funcStr (x:string) (y:string)  = (x+y).Length = 5
+        let strSeq1 = seq ["a"; "ab";  "abc" ; "abcd"] |> PSeq.ordered
+        let strSeq2 = seq ["abcd"; "abc";  "ab" ; "a"] |> PSeq.ordered
+        let for_all2Str = PSeq.forall2  funcStr strSeq1 strSeq2
+       
+        if for_all2Str <> true then Assert.Fail()
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let for_all2Empty = PSeq.forall2 funcInt emptySeq emptySeq
+        
+        if for_all2Empty <> true then Assert.Fail()
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.forall2 funcInt  nullSeq nullSeq |> ignore) 
+        
+    [<Test>]
+    member this.GroupBy() =
+        
+        let funcInt x = x%5
+             
+        let IntSeq =
+            seq { for i in 0 .. 9 do
+                    yield i }
+                    
+        let group_byInt = PSeq.groupBy funcInt IntSeq |> PSeq.map (fun (i, v) -> i, PSeq.toList v |> set)
+        
+        let expectedIntSeq = 
+            seq { for i in 0..4 do
+                     yield i, set [i; i+5] }
+                   
+        VerifyPSeqsEqual group_byInt expectedIntSeq
+             
+        // string Seq
+        let funcStr (x:string) = x.Length
+        let strSeq = seq ["length7"; "length 8";  "length7" ; "length  9"]
+        
+        let group_byStr = PSeq.groupBy  funcStr strSeq |> PSeq.map (fun (i, v) -> i, PSeq.toList v |> set)
+        let expectedStrSeq = 
+            seq {
+                yield 7, set ["length7"; "length7"]
+                yield 8, set ["length 8"]
+                yield 9, set ["length  9"] }
+       
+        VerifyPSeqsEqual expectedStrSeq group_byStr
+
+
+        // array keys
+        let funcStr (x:string) = x.ToCharArray() |> Array.filter (fun c -> Char.IsUpper(c))
+        let strSeq = seq ["Hello"; "Goodbye";  "Hello"; "How Are You?"]
+        
+        let group_byStr = PSeq.groupBy funcStr strSeq |> PSeq.map (fun (i, v) -> i, PSeq.toList v|> set)
+        let expectedStrSeq = 
+            seq {
+                yield [|'H'|], set ["Hello"; "Hello"]
+                yield [|'G'|], set ["Goodbye"]
+                yield [|'H';'A';'Y'|], set ["How Are You?"] }
+       
+        VerifyPSeqsEqual expectedStrSeq group_byStr
+
+        
+//        // Empty Seq
+//        let emptySeq = PSeq.empty
+//        let group_byEmpty = PSeq.groupBy funcInt emptySeq
+//        let expectedEmptySeq = seq []
+//
+//        VerifyPSeqsEqual expectedEmptySeq group_byEmpty
+        
+        // null Seq
+        let nullSeq:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.iter (fun _ -> ()) (PSeq.groupBy funcInt nullSeq)) 
+        () 
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests.v40/SeqModule2.fs b/src/FSharp.PowerPack.Unittests.v40/SeqModule2.fs
new file mode 100755
index 0000000..4720ef8
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests.v40/SeqModule2.fs
@@ -0,0 +1,1210 @@
+
+namespace FSharp.Core.Unittests.FSharp_Core.Microsoft_FSharp_Collections
+
+open System
+open NUnit.Framework
+open Microsoft.FSharp.Collections
+open FSharp.Core.Unittests.LibraryTestFx
+open System.Linq
+
+[<TestFixture>]
+type SeqModule2() =
+
+    [<Test>]
+    member this.Hd() =
+             
+        let IntSeq =
+            seq { for i in 0 .. 9 do
+                    yield i }
+                    
+        if PSeq.head IntSeq <> 0 then Assert.Fail()
+                 
+        // string Seq
+        let strSeq = seq ["first"; "second";  "third"]
+        if PSeq.head strSeq <> "first" then Assert.Fail()
+         
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        CheckThrowsInvalidOperationExn ( fun() -> PSeq.head emptySeq)
+      
+        // null Seq
+        let nullSeq:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () ->PSeq.head nullSeq) 
+        () 
+        
+        
+    [<Test>]
+    member this.Init() =
+
+        let funcInt x = x
+        let init_finiteInt = PSeq.init 9 funcInt
+        let expectedIntSeq = seq [ 0..8]
+      
+        VerifyPSeqsEqual expectedIntSeq  init_finiteInt
+        
+             
+        // string Seq
+        let funcStr x = x.ToString()
+        let init_finiteStr = PSeq.init 5  funcStr
+        let expectedStrSeq = seq ["0";"1";"2";"3";"4"]
+
+        VerifyPSeqsEqual expectedStrSeq init_finiteStr
+        
+        // null Seq
+        let funcNull x = null
+        let init_finiteNull = PSeq.init 3 funcNull
+        let expectedNullSeq = seq [ null;null;null]
+        
+        VerifyPSeqsEqual expectedNullSeq init_finiteNull
+        () 
+        
+//    [<Test>]
+//    member this.InitInfinite() =
+//
+//        let funcInt x = x
+//        let init_infiniteInt = PSeq.initInfinite funcInt
+//        let resultint = PSeq.find (fun x -> x =100) init_infiniteInt
+//        
+//        Assert.AreEqual(100,resultint)
+//        
+//             
+//        // string Seq
+//        let funcStr x = x.ToString()
+//        let init_infiniteStr = PSeq.initInfinite  funcStr
+//        let resultstr = PSeq.find (fun x -> x = "100") init_infiniteStr
+//        
+//        Assert.AreEqual("100",resultstr)
+//       
+       
+    [<Test>]
+    member this.IsEmpty() =
+        
+        //seq int
+        let seqint = seq [1;2;3]
+        let is_emptyInt = PSeq.isEmpty seqint
+        
+        Assert.IsFalse(is_emptyInt)
+              
+        //seq str
+        let seqStr = seq["first";"second"]
+        let is_emptyStr = PSeq.isEmpty  seqStr
+
+        Assert.IsFalse(is_emptyInt)
+        
+        //seq empty
+        let seqEmpty = PSeq.empty
+        let is_emptyEmpty = PSeq.isEmpty  seqEmpty
+        Assert.IsTrue(is_emptyEmpty) 
+        
+        //seq null
+        let seqnull:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.isEmpty seqnull |> ignore)
+        ()
+        
+    [<Test>]
+    member this.Iter() =
+//        //seq int
+//        let seqint =  seq [ 1..3]
+//        let cacheint = ref 0
+//       
+//        let funcint x = cacheint := !cacheint + x
+//        PSeq.iter funcint seqint
+//        Assert.AreEqual(6,!cacheint)
+//              
+//        //seq str
+//        let seqStr = seq ["first";"second"]
+//        let cachestr =ref ""
+//        let funcstr x = cachestr := !cachestr+x
+//        PSeq.iter funcstr seqStr
+//         
+//        Assert.AreEqual("firstsecond",!cachestr, sprintf "Not equal! firstsecond <> %A" !cachestr)
+        
+         // empty array    
+        let emptyseq = PSeq.empty
+        let resultEpt = ref 0
+        PSeq.iter (fun x -> Assert.Fail()) emptyseq   
+
+        // null seqay
+        let nullseq:seq<'a> =  null
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.iter (fun x -> ()) nullseq |> ignore)  
+        ()
+        
+    [<Test>]
+    member this.Iter2() =
+    
+//        //seq int
+//        let seqint =  seq [ 1..3]
+//        let cacheint = ref 0
+//       
+//        let funcint x y = cacheint := !cacheint + x+y
+//        PSeq.iter2 funcint seqint seqint
+//        Assert.AreEqual(12,!cacheint)
+//              
+//        //seq str
+//        let seqStr = seq ["first";"second"]
+//        let cachestr =ref ""
+//        let funcstr x y = cachestr := !cachestr+x+y
+//        PSeq.iter2 funcstr seqStr seqStr
+//         
+//        Assert.AreEqual("firstfirstsecondsecond",!cachestr)
+//        
+         // empty array    
+        let emptyseq = PSeq.empty
+        let resultEpt = ref 0
+        PSeq.iter2 (fun x y-> Assert.Fail()) emptyseq  emptyseq 
+
+        // null seqay
+        let nullseq:seq<'a> =  null
+        CheckThrowsArgumentNullException (fun () -> PSeq.iter2 (fun x y -> ()) nullseq nullseq |> ignore)  
+        
+        ()
+        
+    [<Test>]
+    member this.Iteri() =
+    
+//        // seq int
+//        let seqint =  seq [ 1..10]
+//        let cacheint = ref 0
+//       
+//        let funcint x y = cacheint := !cacheint + x+y
+//        PSeq.iteri funcint seqint
+//        Assert.AreEqual(100,!cacheint)
+//              
+//        // seq str
+//        let seqStr = seq ["first";"second"]
+//        let cachestr =ref 0
+//        let funcstr (x:int) (y:string) = cachestr := !cachestr+ x + y.Length
+//        PSeq.iteri funcstr seqStr
+//         
+//        Assert.AreEqual(12,!cachestr)
+//        
+//         // empty array    
+//        let emptyseq = PSeq.empty
+//        let resultEpt = ref 0
+//        PSeq.iteri funcint emptyseq
+//        Assert.AreEqual(0,!resultEpt)
+
+        // null seqay
+        let nullseq:seq<'a> =  null
+        CheckThrowsArgumentNullException (fun () -> PSeq.iteri (fun x i -> ()) nullseq |> ignore)  
+        ()
+        
+    [<Test>]
+    member this.Length() =
+
+         // integer seq  
+        let resultInt = PSeq.length {1..8}
+        if resultInt <> 8 then Assert.Fail()
+        
+        // string Seq    
+        let resultStr = PSeq.length (seq ["Lists"; "are";  "commonly" ; "list" ])
+        if resultStr <> 4 then Assert.Fail()
+        
+        // empty Seq     
+        let resultEpt = PSeq.length PSeq.empty
+        if resultEpt <> 0 then Assert.Fail()
+
+        // null Seq
+        let nullSeq:seq<'a> = null     
+        CheckThrowsArgumentNullException (fun () -> PSeq.length  nullSeq |> ignore)  
+        
+        ()
+        
+    [<Test>]
+    member this.Map() =
+
+         // integer Seq
+        let funcInt x = 
+                match x with
+                | _ when x % 2 = 0 -> 10*x            
+                | _ -> x
+       
+        let resultInt = PSeq.map funcInt { 1..10 }
+        let expectedint = seq [1;20;3;40;5;60;7;80;9;100]
+        
+        VerifyPSeqsEqual expectedint resultInt
+        
+        // string Seq
+        let funcStr (x:string) = x.ToLower()
+        let resultStr = PSeq.map funcStr (seq ["Lists"; "Are";  "Commonly" ; "List" ])
+        let expectedSeq = seq ["lists"; "are";  "commonly" ; "list"]
+        
+        VerifyPSeqsEqual expectedSeq resultStr
+        
+        // empty Seq
+        let resultEpt = PSeq.map funcInt PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+
+        // null Seq
+        let nullSeq:seq<'a> = null 
+        CheckThrowsArgumentNullException (fun () -> PSeq.map funcStr nullSeq |> ignore)
+        
+        ()
+        
+    [<Test>]
+    member this.Map2() =
+         // integer Seq
+        let funcInt x y = x+y
+        let resultInt = PSeq.map2 funcInt { 1..10 } {2..2..20} 
+        let expectedint = seq [3;6;9;12;15;18;21;24;27;30]
+        
+        VerifyPSeqsEqual expectedint resultInt
+        
+        // string Seq
+        let funcStr (x:int) (y:string) = x+y.Length
+        let resultStr = PSeq.map2 funcStr (seq[3;6;9;11]) (seq ["Lists"; "Are";  "Commonly" ; "List" ])
+        let expectedSeq = seq [8;9;17;15]
+        
+        VerifyPSeqsEqual expectedSeq resultStr
+        
+        // empty Seq
+        let resultEpt = PSeq.map2 funcInt PSeq.empty PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+
+        // null Seq
+        let nullSeq:seq<'a> = null 
+        let validSeq = seq [1]
+        CheckThrowsArgumentNullException (fun () -> PSeq.map2 funcInt nullSeq validSeq |> ignore)
+        
+        ()
+        
+        
+    member private this.MapWithSideEffectsTester (map : (int -> int) -> seq<int> -> pseq<int>) expectExceptions =
+        let i = ref 0
+        let f x = i := !i + 1; x*x
+        let e = ([1;2] |> map f).GetEnumerator()
+        
+        if expectExceptions then
+            CheckThrowsInvalidOperationExn  (fun _ -> e.Current|>ignore)
+            Assert.AreEqual(0, !i)
+        if not (e.MoveNext()) then Assert.Fail()
+        Assert.AreEqual(1, !i)
+        let _ = e.Current
+        Assert.AreEqual(1, !i)
+        let _ = e.Current
+        Assert.AreEqual(1, !i)
+        
+        if not (e.MoveNext()) then Assert.Fail()
+        Assert.AreEqual(2, !i)
+        let _ = e.Current
+        Assert.AreEqual(2, !i)
+        let _ = e.Current
+        Assert.AreEqual(2, !i)
+
+        if e.MoveNext() then Assert.Fail()
+        Assert.AreEqual(2, !i)
+        if expectExceptions then
+            CheckThrowsInvalidOperationExn (fun _ -> e.Current |> ignore)
+            Assert.AreEqual(2, !i)
+
+        
+        i := 0
+        let e = ([] |> map f).GetEnumerator()
+        if e.MoveNext() then Assert.Fail()
+        Assert.AreEqual(0,!i)
+        if e.MoveNext() then Assert.Fail()
+        Assert.AreEqual(0,!i)
+        
+        
+    member private this.MapWithExceptionTester (map : (int -> int) -> seq<int> -> pseq<int>) =
+        let raiser x = if x > 0 then raise(NotSupportedException()) else x
+        let raises = (map raiser [0; 1])
+        CheckThrowsAggregateException(fun _ -> PSeq.toArray raises |> ignore)
+       
+
+//    [<Test>]
+//    member this.MapWithSideEffects () =
+//        this.MapWithSideEffectsTester PSeq.map true
+        
+    [<Test>]
+    member this.MapWithException () =
+        this.MapWithExceptionTester PSeq.map
+
+        
+//    [<Test>]
+//    member this.SingletonCollectWithSideEffects () =
+//        this.MapWithSideEffectsTester (fun f-> PSeq.collect (f >> PSeq.singleton)) true
+        
+    [<Test>]
+    member this.SingletonCollectWithException () =
+        this.MapWithExceptionTester (fun f-> PSeq.collect (f >> PSeq.singleton))
+
+     
+//    [<Test>]
+//    member this.SystemLinqSelectWithSideEffects () =
+//        this.MapWithSideEffectsTester (fun f s -> System.Linq.ParallelEnumerable.Select(s.AsParallel(), Func<_,_>(f))) false
+//        
+    [<Test>]
+    member this.SystemLinqSelectWithException () =
+        this.MapWithExceptionTester (fun f s -> System.Linq.ParallelEnumerable.Select(s.AsParallel(), Func<_,_>(f)))
+
+        
+//    [<Test>]
+//    member this.MapiWithSideEffects () =
+//        let i = ref 0
+//        let f _ x = i := !i + 1; x*x
+//        let e = ([1;2] |> PSeq.mapi f).GetEnumerator()
+//        
+//        CheckThrowsInvalidOperationExn  (fun _ -> e.Current|>ignore)
+//        Assert.AreEqual(0, !i)
+//        if not (e.MoveNext()) then Assert.Fail()
+//        Assert.AreEqual(1, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(1, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(1, !i)
+//        
+//        if not (e.MoveNext()) then Assert.Fail()
+//        Assert.AreEqual(2, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(2, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(2, !i)
+//        
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(2, !i)
+//        CheckThrowsInvalidOperationExn  (fun _ -> e.Current|>ignore)
+//        Assert.AreEqual(2, !i)
+//        
+//        i := 0
+//        let e = ([] |> PSeq.mapi f).GetEnumerator()
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(0,!i)
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(0,!i)
+        
+//    [<Test>]
+//    member this.Map2WithSideEffects () =
+//        let i = ref 0
+//        let f x y = i := !i + 1; x*x
+//        let e = (PSeq.map2 f [1;2] [1;2]).GetEnumerator()
+//        
+//        CheckThrowsInvalidOperationExn  (fun _ -> e.Current|>ignore)
+//        Assert.AreEqual(0, !i)
+//        if not (e.MoveNext()) then Assert.Fail()
+//        Assert.AreEqual(1, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(1, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(1, !i)
+//        
+//        if not (e.MoveNext()) then Assert.Fail()
+//        Assert.AreEqual(2, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(2, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(2, !i)
+//
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(2,!i)
+//        CheckThrowsInvalidOperationExn  (fun _ -> e.Current|>ignore)
+//        Assert.AreEqual(2, !i)
+//        
+//        i := 0
+//        let e = (PSeq.map2 f [] []).GetEnumerator()
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(0,!i)
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(0,!i)
+        
+    [<Test>]
+    member this.Collect() =
+         // integer Seq
+        let funcInt x = seq [x+1]
+        let resultInt = PSeq.collect funcInt { 1..10 } 
+       
+        let expectedint = seq {2..11}
+        
+        VerifyPSeqsEqual expectedint resultInt
+        
+        // string Seq
+        let funcStr (y:string) = y+"ist"
+       
+        let resultStr = PSeq.collect funcStr (seq ["L"])
+        
+        
+        let expectedSeq = seq ['L';'i';'s';'t']
+        
+        VerifyPSeqsEqual expectedSeq resultStr
+        
+        // empty Seq
+        let resultEpt = PSeq.collect funcInt PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+
+        // null Seq
+        let nullSeq:seq<'a> = null 
+       
+        CheckThrowsArgumentNullException (fun () -> PSeq.collect funcInt nullSeq |> ignore)
+        
+        ()
+        
+    [<Test>]
+    member this.Mapi() =
+
+         // integer Seq
+        let funcInt x y = x+y
+        let resultInt = PSeq.mapi funcInt { 10..2..20 } 
+        let expectedint = seq [10;13;16;19;22;25]
+        
+        VerifyPSeqsEqual expectedint resultInt
+        
+        // string Seq
+        let funcStr (x:int) (y:string) =x+y.Length
+       
+        let resultStr = PSeq.mapi funcStr (seq ["Lists"; "Are";  "Commonly" ; "List" ])
+        let expectedStr = seq [5;4;10;7]
+         
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // empty Seq
+        let resultEpt = PSeq.mapi funcInt PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+
+        // null Seq
+        let nullSeq:seq<'a> = null 
+       
+        CheckThrowsArgumentNullException (fun () -> PSeq.mapi funcInt nullSeq |> ignore)
+        
+        ()
+        
+    [<Test>]
+    member this.Max() =
+        // integer Seq
+        let resultInt = PSeq.max { 10..20 } 
+        Assert.AreEqual(20,resultInt)
+
+
+        // integer64 Seq
+        let resultInt64 = PSeq.max { 10L..20L } 
+        Assert.AreEqual(20L,resultInt64)
+
+
+        // float Seq
+        let resultFloat = PSeq.max { 10.0..20.0 } 
+        Assert.AreEqual(20.0,resultFloat)
+
+        // float32 Seq
+        let resultFloat32 = PSeq.max { 10.0f..20.0f } 
+        Assert.AreEqual(20.0f,resultFloat32)
+
+        // decimal Seq
+        let resultDecimal = PSeq.max { (decimal 10)..(decimal 20) } 
+        Assert.AreEqual((decimal 20),resultDecimal)
+
+        // string Seq
+       
+        let resultStr = PSeq.max (seq ["Lists"; "Are";  "MaxString" ; "List" ])
+        Assert.AreEqual("MaxString",resultStr)
+          
+        // empty Seq
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.max ( PSeq.empty : pseq<float>) |> ignore)
+        
+        // null Seq
+        let nullSeq:seq<float> = null 
+        CheckThrowsArgumentNullException (fun () -> PSeq.max nullSeq |> ignore)
+        
+        ()
+        
+    [<Test>]
+    member this.MaxBy() =
+    
+        // integer Seq
+        let funcInt x = - (x % 18)
+        let resultInt = PSeq.maxBy funcInt { 2..2..20 } 
+        Assert.AreEqual(18,resultInt)
+        
+        // string Seq
+        let funcStr (x:string)  = x.Length 
+        let resultStr = PSeq.maxBy funcStr (seq ["Lists"; "Are";  "Commonly" ; "List" ])
+        Assert.AreEqual("Commonly",resultStr)
+         
+        // empty Seq
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.maxBy funcInt (PSeq.empty : pseq<int>) |> ignore)
+        
+        // null Seq
+        let nullSeq:seq<int> = null 
+        CheckThrowsArgumentNullException (fun () ->PSeq.maxBy funcInt nullSeq |> ignore)
+        
+
+        ()
+        
+    [<Test>]
+    member this.MinBy() =
+    
+        // integer Seq
+        let funcInt x = decimal(x % 18)
+        let resultInt = PSeq.minBy funcInt { 2..2..20 } 
+        Assert.AreEqual(18,resultInt)
+        
+        // string Seq
+        let funcStr (x:string)  = x.Length 
+        let resultStr = PSeq.minBy funcStr (seq ["Lists"; "Are";  "Commonly" ; "List" ])
+        Assert.AreEqual("Are",resultStr)
+          
+        // empty Seq
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.minBy funcInt (PSeq.empty : pseq<int>) |> ignore) 
+        
+        // null Seq
+        let nullSeq:seq<int> = null 
+        CheckThrowsArgumentNullException (fun () ->PSeq.minBy funcInt nullSeq |> ignore)
+        
+        ()
+        
+          
+    [<Test>]
+    member this.Min() =
+
+        // integer Seq
+        let resultInt = PSeq.min { 10..20 } 
+        Assert.AreEqual(10,resultInt)
+
+
+        // integer64 Seq
+        let resultInt64 = PSeq.min { 10L..20L } 
+        Assert.AreEqual(10L,resultInt64)
+
+
+        // float Seq
+        let resultFloat = PSeq.min { 10.0..20.0 } 
+        Assert.AreEqual(10.0,resultFloat)
+
+        // float32 Seq
+        let resultFloat32 = PSeq.min { 10.0f..20.0f } 
+        Assert.AreEqual(10.0f,resultFloat32)
+
+        // decimal Seq
+        let resultDecimal = PSeq.min { (decimal 10)..(decimal 20) } 
+        Assert.AreEqual((decimal 10),resultDecimal)
+
+        
+//        // string Seq
+//        let resultStr = PSeq.min (seq ["Lists"; "Are";  "minString" ; "List" ])
+//        Assert.AreEqual("Are",resultStr)
+          
+        // empty Seq
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.min (PSeq.empty : pseq<int>) |> ignore) 
+        
+        // null Seq
+        let nullSeq:seq<float> = null 
+        CheckThrowsArgumentNullException (fun () -> PSeq.min nullSeq |> ignore)
+        
+        ()
+        
+    [<Test>]
+    member this.Nth() =
+         
+        // Negative index
+        for i = -1 downto -10 do
+           CheckThrowsArgumentException (fun () -> PSeq.nth i { 10 .. 20 } |> ignore)
+            
+        // Out of range
+        for i = 11 to 20 do
+           CheckThrowsArgumentException (fun () -> PSeq.nth i { 10 .. 20 } |> ignore)
+         
+         // integer Seq
+        let resultInt = PSeq.nth 3 { 10..20 } 
+        Assert.AreEqual(13, resultInt)
+        
+        // string Seq
+        let resultStr = PSeq.nth 3 (seq ["Lists"; "Are";  "nthString" ; "List" ])
+        Assert.AreEqual("List",resultStr)
+          
+        // empty Seq
+        CheckThrowsArgumentException(fun () -> PSeq.nth 0 (PSeq.empty : pseq<decimal>) |> ignore)
+       
+        // null Seq
+        let nullSeq:seq<'a> = null 
+        CheckThrowsArgumentNullException (fun () ->PSeq.nth 3 nullSeq |> ignore)
+        
+        ()
+         
+    [<Test>]
+    member this.Of_Array() =
+         // integer Seq
+        let resultInt = PSeq.ofArray [|1..10|]
+        let expectedInt = {1..10}
+         
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let resultStr = PSeq.ofArray [|"Lists"; "Are";  "ofArrayString" ; "List" |]
+        let expectedStr = seq ["Lists"; "Are";  "ofArrayString" ; "List" ]
+        VerifyPSeqsEqual expectedStr resultStr
+          
+        // empty Seq 
+        let resultEpt = PSeq.ofArray [| |] 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+       
+        ()
+        
+    [<Test>]
+    member this.Of_List() =
+         // integer Seq
+        let resultInt = PSeq.ofList [1..10]
+        let expectedInt = {1..10}
+         
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+       
+        let resultStr =PSeq.ofList ["Lists"; "Are";  "ofListString" ; "List" ]
+        let expectedStr = seq ["Lists"; "Are";  "ofListString" ; "List" ]
+        VerifyPSeqsEqual expectedStr resultStr
+          
+        // empty Seq 
+        let resultEpt = PSeq.ofList [] 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+        ()
+        
+          
+//    [<Test>]
+//    member this.Pairwise() =
+//         // integer Seq
+//        let resultInt = PSeq.pairwise {1..3}
+//       
+//        let expectedInt = seq [1,2;2,3]
+//         
+//        VerifyPSeqsEqual expectedInt resultInt
+//        
+//        // string Seq
+//        let resultStr =PSeq.pairwise ["str1"; "str2";"str3" ]
+//        let expectedStr = seq ["str1","str2";"str2","str3"]
+//        VerifyPSeqsEqual expectedStr resultStr
+//          
+//        // empty Seq 
+//        let resultEpt = PSeq.pairwise [] 
+//        VerifyPSeqsEqual resultEpt PSeq.empty
+//       
+//        ()
+        
+    [<Test>]
+    member this.Reduce() =
+         
+        // integer Seq
+        let resultInt = PSeq.reduce (fun x y -> x + y) (seq [5;4;3;2;1])
+        Assert.AreEqual(15,resultInt)
+        
+//        // string Seq
+//        let resultStr = PSeq.reduce (fun (x:string) (y:string) -> x.Remove(0,y.Length)) (seq ["ABCDE";"A"; "B";  "C" ; "D" ])
+//        Assert.AreEqual("E",resultStr) 
+       
+        // empty Seq 
+        CheckThrowsInvalidOperationExn(fun () -> PSeq.reduce (fun x y -> x/y)  PSeq.empty |> ignore)
+        
+        // null Seq
+        let nullSeq : seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.reduce (fun (x:string) (y:string) -> x.Remove(0,y.Length))  nullSeq  |> ignore)   
+        ()
+
+         
+//    [<Test>]
+//    member this.Scan() =
+//        // integer Seq
+//        let funcInt x y = x+y
+//        let resultInt = PSeq.scan funcInt 9 {1..10}
+//        let expectedInt = seq [9;10;12;15;19;24;30;37;45;54;64]
+//        VerifyPSeqsEqual expectedInt resultInt
+//        
+//        // string Seq
+//        let funcStr x y = x+y
+//        let resultStr =PSeq.scan funcStr "x" ["str1"; "str2";"str3" ]
+//        
+//        let expectedStr = seq ["x";"xstr1"; "xstr1str2";"xstr1str2str3"]
+//        VerifyPSeqsEqual expectedStr resultStr
+//          
+//        // empty Seq 
+//        let resultEpt = PSeq.scan funcInt 5 PSeq.empty 
+//       
+//        VerifyPSeqsEqual resultEpt (seq [ 5])
+//       
+//        // null Seq
+//        let seqNull:seq<'a> = null
+//        CheckThrowsArgumentNullException(fun() -> PSeq.scan funcInt 5 seqNull |> ignore)
+//        ()
+        
+    [<Test>]
+    member this.Singleton() =
+        // integer Seq
+        let resultInt = PSeq.singleton 1
+       
+        let expectedInt = seq [1]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let resultStr =PSeq.singleton "str1"
+        let expectedStr = seq ["str1"]
+        VerifyPSeqsEqual expectedStr resultStr
+         
+        // null Seq
+        let resultNull = PSeq.singleton null
+        let expectedNull = seq [null]
+        VerifyPSeqsEqual expectedNull resultNull
+        ()
+    
+        
+    [<Test>]
+    member this.Skip() =
+    
+        // integer Seq
+        let resultInt = PSeq.skip 2 (seq [1;2;3;4])
+        let expectedInt = seq [3;4]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let resultStr =PSeq.skip 2 (seq ["str1";"str2";"str3";"str4"])
+        let expectedStr = seq ["str3";"str4"]
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // empty Seq 
+        let resultEpt = PSeq.skip 0 PSeq.empty 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+        
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.skip 1 null |> ignore)
+        ()
+       
+    [<Test>]
+    member this.Skip_While() =
+    
+        // integer Seq
+        let funcInt x = (x < 3)
+        let resultInt = PSeq.skipWhile funcInt (seq [1;2;3;4;5;6])
+        let expectedInt = seq [3;4;5;6]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let funcStr (x:string) = x.Contains(".")
+        let resultStr =PSeq.skipWhile funcStr (seq [".";"asdfasdf.asdfasdf";"";"";"";"";"";"";"";"";""])
+        let expectedStr = seq ["";"";"";"";"";"";"";"";""]
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // empty Seq 
+        let resultEpt = PSeq.skipWhile funcInt PSeq.empty 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+        
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.skipWhile funcInt null |> ignore)
+        ()
+       
+    [<Test>]
+    member this.Sort() =
+
+        // integer Seq
+        let resultInt = PSeq.sort (seq [1;3;2;4;6;5;7])
+        let expectedInt = {1..7}
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+       
+        let resultStr =PSeq.sort (seq ["str1";"str3";"str2";"str4"])
+        let expectedStr = seq ["str1";"str2";"str3";"str4"]
+        VerifyPSeqsEqual expectedStr resultStr
+
+        // array Seq
+       
+        let resultArray =PSeq.sort (seq [[|1;2|]; [|5|]; [|3;4|]; [|4|]])
+        let expectedArray = seq [[|4|]; [|5|]; [|1; 2|]; [|3; 4|]]
+        VerifyPSeqsEqual expectedArray resultArray
+        
+        // empty Seq 
+        let resultEpt = PSeq.sort PSeq.empty 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.sort null  |> ignore)
+        ()
+        
+    [<Test>]
+    member this.SortBy() =
+
+        // integer Seq
+        let funcInt x = Math.Abs(x-5)
+        let resultInt = PSeq.sortBy funcInt (seq [1;2;4;5;7])
+        let expectedInt = seq [5;4;7;2;1]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let funcStr (x:string) = x.IndexOf("key")
+        let resultStr =PSeq.sortBy funcStr (seq ["st(key)r";"str(key)";"s(key)tr";"(key)str"])
+        
+        let expectedStr = seq ["(key)str";"s(key)tr";"st(key)r";"str(key)"]
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // array Seq
+        let resultArray =PSeq.sortBy (Array.toList) (seq [[|1;2|]; [|5|]; [|3;4|]; [|4|]])
+        let expectedArray = seq [[|4|]; [|5|]; [|1; 2|]; [|3; 4|]]
+        VerifyPSeqsEqual expectedArray resultArray
+
+        // empty Seq 
+        let resultEpt = PSeq.sortBy funcInt PSeq.empty 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.sortBy funcInt null  |> ignore)
+        ()
+        
+    [<Test>]
+    member this.Sum() =
+    
+        // integer Seq
+        let resultInt = PSeq.sum (seq [1..10])
+        Assert.AreEqual(55,resultInt)
+
+        // int64 Seq
+        let resultInt64 = PSeq.sum (seq [1L..10L])
+        Assert.AreEqual(55L,resultInt64)
+        
+        // float32 Seq
+        let floatSeq = (seq [ 1.2f;3.5f;6.7f ])
+        let resultFloat = PSeq.sum floatSeq
+        if resultFloat <> 11.4f then Assert.Fail()
+        
+        // double Seq
+        let doubleSeq = (seq [ 1.0;8.0 ])
+        let resultDouble = PSeq.sum doubleSeq
+        if resultDouble <> 9.0 then Assert.Fail()
+        
+        // decimal Seq
+        let decimalSeq = (seq [ 0M;19M;19.03M ])
+        let resultDecimal = PSeq.sum decimalSeq
+        if resultDecimal <> 38.03M then Assert.Fail()      
+          
+      
+        // empty float32 Seq
+        let emptyFloatSeq = PSeq.empty<System.Single> 
+        let resultEptFloat = PSeq.sum emptyFloatSeq 
+        if resultEptFloat <> 0.0f then Assert.Fail()
+        
+        // empty double Seq
+        let emptyDoubleSeq = PSeq.empty<System.Double> 
+        let resultDouEmp = PSeq.sum emptyDoubleSeq 
+        if resultDouEmp <> 0.0 then Assert.Fail()
+        
+        // empty decimal Seq
+        let emptyDecimalSeq = PSeq.empty<System.Decimal> 
+        let resultDecEmp = PSeq.sum emptyDecimalSeq 
+        if resultDecEmp <> 0M then Assert.Fail()
+       
+        ()
+        
+    [<Test>]
+    member this.SumBy() =
+
+        // integer Seq
+        let resultInt = PSeq.sumBy (fun x -> x + 1) (seq [1..10])
+        Assert.AreEqual(65,resultInt)
+        
+        // int64 Seq
+        let resultInt64 = PSeq.sumBy int (seq [1L..10L])
+        Assert.AreEqual(55,resultInt64)
+
+        // float32 Seq
+        let floatSeq = (seq [ 1.2f;3.5f;6.7f ])
+        let resultFloat = PSeq.sumBy float32 floatSeq
+        if resultFloat <> 11.4f then Assert.Fail()
+        
+        // double Seq
+        let doubleSeq = (seq [ 1.0;8.0 ])
+        let resultDouble = PSeq.sumBy double doubleSeq
+        if resultDouble <> 9.0 then Assert.Fail()
+        
+        // decimal Seq
+        let decimalSeq = (seq [ 0M;19M;19.03M ])
+        let resultDecimal = PSeq.sumBy decimal decimalSeq
+        if resultDecimal <> 38.03M then Assert.Fail()      
+
+        // empty float32 Seq
+        let emptyFloatSeq = PSeq.empty<System.Single> 
+        let resultEptFloat = PSeq.sumBy float32 emptyFloatSeq 
+        if resultEptFloat <> 0.0f then Assert.Fail()
+        
+        // empty double Seq
+        let emptyDoubleSeq = PSeq.empty<System.Double> 
+        let resultDouEmp = PSeq.sumBy double emptyDoubleSeq 
+        if resultDouEmp <> 0.0 then Assert.Fail()
+        
+        // empty decimal Seq
+        let emptyDecimalSeq = PSeq.empty<System.Decimal> 
+        let resultDecEmp = PSeq.sumBy decimal emptyDecimalSeq 
+        if resultDecEmp <> 0M then Assert.Fail()
+       
+        ()
+        
+//    [<Test>]
+//    member this.Take() =
+//        // integer Seq
+//        
+//        let resultInt = PSeq.take 3 (seq [1;2;4;5;7])
+//       
+//        let expectedInt = seq [1;2;4]
+//        VerifyPSeqsEqual expectedInt resultInt
+//        
+//        // string Seq
+//       
+//        let resultStr =PSeq.take 2(seq ["str1";"str2";"str3";"str4"])
+//     
+//        let expectedStr = seq ["str1";"str2"]
+//        VerifyPSeqsEqual expectedStr resultStr
+//        
+//        // empty Seq 
+//        let resultEpt = PSeq.take 0 PSeq.empty 
+//      
+//        VerifyPSeqsEqual resultEpt PSeq.empty
+//        
+//         
+//        // null Seq
+//        CheckThrowsArgumentNullException(fun() -> PSeq.take 1 null |> ignore)
+//        ()
+        
+    [<Test>]
+    member this.takeWhile() =
+        // integer Seq
+        let funcInt x = (x < 6)
+        let resultInt = PSeq.takeWhile funcInt (seq [1;2;4;5;6;7])
+      
+        let expectedInt = seq [1;2;4;5]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let funcStr (x:string) = (x.Length < 4)
+        let resultStr =PSeq.takeWhile funcStr (seq ["a"; "ab"; "abc"; "abcd"; "abcde"])
+      
+        let expectedStr = seq ["a"; "ab"; "abc"]
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // empty Seq 
+        let resultEpt = PSeq.takeWhile funcInt PSeq.empty 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+        
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.takeWhile funcInt null |> ignore)
+        ()
+        
+    [<Test>]
+    member this.To_Array() =
+        // integer Seq
+        let resultInt = PSeq.toArray(seq [1;2;4;5;7])
+     
+        let expectedInt = [|1;2;4;5;7|]
+        Assert.AreEqual(expectedInt,resultInt)
+        
+        // string Seq
+        let resultStr =PSeq.toArray (seq ["str1";"str2";"str3"])
+    
+        let expectedStr =  [|"str1";"str2";"str3"|]
+        Assert.AreEqual(expectedStr,resultStr)
+        
+        // empty Seq 
+        let resultEpt = PSeq.toArray PSeq.empty 
+        Assert.AreEqual([||],resultEpt)
+        
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.toArray null |> ignore)
+        ()
+    
+    [<Test>]
+    member this.To_List() =
+        // integer Seq
+        let resultInt = PSeq.toList (seq [1;2;4;5;7])
+        let expectedInt = [1;2;4;5;7]
+        Assert.AreEqual(expectedInt,resultInt)
+        
+        // string Seq
+        let resultStr =PSeq.toList (seq ["str1";"str2";"str3"])
+        let expectedStr =  ["str1";"str2";"str3"]
+        Assert.AreEqual(expectedStr,resultStr)
+        
+        // empty Seq 
+        let resultEpt = PSeq.toList PSeq.empty 
+        Assert.AreEqual([],resultEpt)
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.toList null |> ignore)
+        ()
+        
+    [<Test>]
+    member this.Truncate() =
+        // integer Seq
+        let resultInt = PSeq.truncate 3 (seq [1;2;4;5;7])
+        let expectedInt = [1;2;4]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let resultStr =PSeq.truncate 2 (seq ["str1";"str2";"str3"])
+        let expectedStr =  ["str1";"str2"]
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // empty Seq 
+        let resultEpt = PSeq.truncate 0 PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+        
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.truncate 1 null |> ignore)
+        ()
+        
+    [<Test>]
+    member this.tryFind() =
+        // integer Seq
+        let resultInt = PSeq.tryFind (fun x -> (x%2=0)) (seq [1;2;4;5;7])
+        Assert.AreEqual(Some(2), resultInt)
+        
+         // integer Seq - None
+        let resultInt = PSeq.tryFind (fun x -> (x%2=0)) (seq [1;3;5;7])
+        Assert.AreEqual(None, resultInt)
+        
+        // string Seq
+        let resultStr = PSeq.tryFind (fun (x:string) -> x.Contains("2")) (seq ["str1";"str2";"str3"])
+        Assert.AreEqual(Some("str2"),resultStr)
+        
+         // string Seq - None
+        let resultStr = PSeq.tryFind (fun (x:string) -> x.Contains("2")) (seq ["str1";"str4";"str3"])
+        Assert.AreEqual(None,resultStr)
+       
+        
+        // empty Seq 
+        let resultEpt = PSeq.tryFind (fun x -> (x%2=0)) PSeq.empty
+        Assert.AreEqual(None,resultEpt)
+
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.tryFind (fun x -> (x%2=0))  null |> ignore)
+        ()
+        
+    [<Test>]
+    member this.TryFindIndex() =
+
+        // integer Seq
+        let resultInt = PSeq.tryFindIndex (fun x -> (x % 5 = 0)) [8; 9; 10]
+        Assert.AreEqual(Some(2), resultInt)
+        
+         // integer Seq - None
+        let resultInt = PSeq.tryFindIndex (fun x -> (x % 5 = 0)) [9;3;11]
+        Assert.AreEqual(None, resultInt)
+        
+        // string Seq
+        let resultStr = PSeq.tryFindIndex (fun (x:string) -> x.Contains("2")) ["str1"; "str2"; "str3"]
+        Assert.AreEqual(Some(1),resultStr)
+        
+         // string Seq - None
+        let resultStr = PSeq.tryFindIndex (fun (x:string) -> x.Contains("2")) ["str1"; "str4"; "str3"]
+        Assert.AreEqual(None,resultStr)
+       
+        
+        // empty Seq 
+        let resultEpt = PSeq.tryFindIndex (fun x -> (x%2=0)) PSeq.empty
+        Assert.AreEqual(None, resultEpt)
+        
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.tryFindIndex (fun x -> (x % 2 = 0))  null |> ignore)
+        ()
+        
+//    [<Test>]
+//    member this.Unfold() =
+//        // integer Seq
+//        
+//        let resultInt = PSeq.unfold (fun x -> if x = 1 then Some(7,2) else  None) 1
+//        
+//        VerifyPSeqsEqual (seq [7]) resultInt
+//          
+//        // string Seq
+//        let resultStr =PSeq.unfold (fun (x:string) -> if x.Contains("unfold") then Some("a","b") else None) "unfold"
+//        VerifyPSeqsEqual (seq ["a"]) resultStr
+//        ()
+//        
+        
+//    [<Test>]
+//    member this.Windowed() =
+//        // integer Seq
+//        let resultInt = PSeq.windowed 5 (seq [1..10])
+//        let expectedInt = 
+//            seq { for i in 1..6 do
+//                    yield [| i; i+1; i+2; i+3; i+4 |] }
+//        VerifyPSeqsEqual expectedInt resultInt
+//        
+//        // string Seq
+//        let resultStr =PSeq.windowed 2 (seq ["str1";"str2";"str3";"str4"])
+//        let expectedStr = seq [ [|"str1";"str2"|];[|"str2";"str3"|];[|"str3";"str4"|]]
+//        VerifyPSeqsEqual expectedStr resultStr
+//      
+//        // empty Seq 
+//        let resultEpt = PSeq.windowed 2 PSeq.empty
+//        VerifyPSeqsEqual PSeq.empty resultEpt
+//          
+//        // null Seq
+//        CheckThrowsArgumentNullException(fun() -> PSeq.windowed 2 null |> ignore)
+//        ()
+        
+    [<Test>]
+    member this.Zip() =
+    
+        // integer Seq
+        let resultInt = PSeq.zip (seq [1..7]) (seq [11..17])
+        let expectedInt = 
+            seq { for i in 1..7 do
+                    yield i, i+10 }
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let resultStr =PSeq.zip (seq ["str3";"str4"]) (seq ["str1";"str2"])
+        let expectedStr = seq ["str3","str1";"str4","str2"]
+        VerifyPSeqsEqual expectedStr resultStr
+      
+        // empty Seq 
+        let resultEpt = PSeq.zip PSeq.empty PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+          
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.zip null null |> ignore)
+        CheckThrowsArgumentNullException(fun() -> PSeq.zip null (seq [1..7]) |> ignore)
+        CheckThrowsArgumentNullException(fun() -> PSeq.zip (seq [1..7]) null |> ignore)
+        ()
+        
+//    [<Test>]
+//    member this.Zip3() =
+//        // integer Seq
+//        let resultInt = PSeq.zip3 (seq [1..7]) (seq [11..17]) (seq [21..27])
+//        let expectedInt = 
+//            seq { for i in 1..7 do
+//                    yield i, (i + 10), (i + 20) }
+//        VerifyPSeqsEqual expectedInt resultInt
+//        
+//        // string Seq
+//        let resultStr =PSeq.zip3 (seq ["str1";"str2"]) (seq ["str11";"str12"]) (seq ["str21";"str22"])
+//        let expectedStr = seq ["str1","str11","str21";"str2","str12","str22" ]
+//        VerifyPSeqsEqual expectedStr resultStr
+//      
+//        // empty Seq 
+//        let resultEpt = PSeq.zip3 PSeq.empty PSeq.empty PSeq.empty
+//        VerifyPSeqsEqual PSeq.empty resultEpt
+//          
+//        // null Seq
+//        CheckThrowsArgumentNullException(fun() -> PSeq.zip3 null null null |> ignore)
+//        CheckThrowsArgumentNullException(fun() -> PSeq.zip3 null (seq [1..7]) (seq [1..7]) |> ignore)
+//        CheckThrowsArgumentNullException(fun() -> PSeq.zip3 (seq [1..7]) null (seq [1..7]) |> ignore)
+//        CheckThrowsArgumentNullException(fun() -> PSeq.zip3 (seq [1..7]) (seq [1..7]) null |> ignore)
+//        ()
+        
+//    [<Test>]
+//    member this.tryPick() =
+//         // integer Seq
+//        let resultInt = PSeq.tryPick (fun x-> if x = 1 then Some("got") else None) (seq [1..5])
+//         
+//        Assert.AreEqual(Some("got"),resultInt)
+//        
+//        // string Seq
+//        let resultStr = PSeq.tryPick (fun x-> if x = "Are" then Some("got") else None) (seq ["Lists"; "Are"])
+//        Assert.AreEqual(Some("got"),resultStr)
+//        
+//        // empty Seq   
+//        let resultEpt = PSeq.tryPick (fun x-> if x = 1 then Some("got") else None) PSeq.empty
+//        Assert.IsNull(resultEpt)
+//       
+//        // null Seq
+//        let nullSeq : seq<'a> = null 
+//        let funcNull x = Some(1)
+//        
+//        CheckThrowsArgumentNullException(fun () -> PSeq.tryPick funcNull nullSeq |> ignore)
+//   
+//        ()
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests.v40/Utilities.fs b/src/FSharp.PowerPack.Unittests.v40/Utilities.fs
new file mode 100755
index 0000000..7fb28c4
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests.v40/Utilities.fs
@@ -0,0 +1,125 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open System
+open System.Collections.Generic
+
+[<AutoOpen>]
+module Utilities = 
+    let test msg b = Assert.IsTrue(b, "MiniTest '" + msg + "'")
+    let logMessage msg = 
+        System.Console.WriteLine("LOG:" + msg)
+//        System.Diagnostics.Trace.WriteLine("LOG:" + msg)
+    let check msg v1 v2 = test msg (v1 = v2)
+    let reportFailure msg = Assert.Fail msg
+    let numActiveEnumerators = ref 0
+    let throws f = try f() |> ignore; false with e -> true
+
+    let countEnumeratorsAndCheckedDisposedAtMostOnceAtEnd (seq: seq<'a>) =
+       let enumerator() = 
+                 numActiveEnumerators := !numActiveEnumerators + 1;
+                 let disposed = ref false in
+                 let endReached = ref false in
+                 let ie = seq.GetEnumerator() in
+                 { new System.Collections.Generic.IEnumerator<'a> with 
+                      member x.Current =
+                          test "rvlrve0" (not !endReached);
+                          test "rvlrve1" (not !disposed);
+                          ie.Current
+                      member x.Dispose() = 
+                          test "rvlrve2" !endReached;
+                          test "rvlrve4" (not !disposed);
+                          numActiveEnumerators := !numActiveEnumerators - 1;
+                          disposed := true;
+                          ie.Dispose() 
+                   interface System.Collections.IEnumerator with 
+                      member x.MoveNext() = 
+                          test "rvlrve0" (not !endReached);
+                          test "rvlrve3" (not !disposed);
+                          endReached := not (ie.MoveNext());
+                          not !endReached
+                      member x.Current = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          box ie.Current
+                      member x.Reset() = 
+                          ie.Reset()
+                   } in
+
+       { new seq<'a> with 
+             member x.GetEnumerator() =  enumerator() 
+         interface System.Collections.IEnumerable with 
+             member x.GetEnumerator() =  (enumerator() :> _) }
+
+    let countEnumeratorsAndCheckedDisposedAtMostOnce (seq: seq<'a>) =
+       let enumerator() = 
+                 let disposed = ref false in
+                 let endReached = ref false in
+                 let ie = seq.GetEnumerator() in
+                 numActiveEnumerators := !numActiveEnumerators + 1;
+                 { new System.Collections.Generic.IEnumerator<'a> with 
+                      member x.Current =
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          ie.Current
+                      member x.Dispose() = 
+                          test "qrvlrve4" (not !disposed);
+                          numActiveEnumerators := !numActiveEnumerators - 1;
+                          disposed := true;
+                          ie.Dispose() 
+                   interface System.Collections.IEnumerator with 
+                      member x.MoveNext() = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve3" (not !disposed);
+                          endReached := not (ie.MoveNext());
+                          not !endReached
+                      member x.Current = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          box ie.Current
+                      member x.Reset() = 
+                          ie.Reset()
+                   } in
+
+       { new seq<'a> with 
+             member x.GetEnumerator() =  enumerator() 
+         interface System.Collections.IEnumerable with 
+             member x.GetEnumerator() =  (enumerator() :> _) }
+
+    // Verifies two sequences are equal (same length, equiv elements)
+    let verifySeqsEqual seq1 seq2 =
+        if Seq.length seq1 <> Seq.length seq2 then Assert.Fail()
+        
+        let zippedElements = Seq.zip seq1 seq2
+        if zippedElements |> Seq.forall (fun (a, b) -> a = b) 
+        then ()
+        else Assert.Fail()
+        
+    /// Check that the lamda throws an exception of the given type. Otherwise
+    /// calls Assert.Fail()
+    let private checkThrowsExn<'a when 'a :> exn> (f : unit -> unit) =
+        let funcThrowsAsExpected =
+            try
+                let _ = f ()
+                false // Did not throw!
+            with
+            | :? 'a
+                -> true   // Thew null ref, OK
+            | _ -> false  // Did now throw a null ref exception!
+        if funcThrowsAsExpected
+        then ()
+        else Assert.Fail()
+
+    // Illegitimate exceptions. Once we've scrubbed the library, we should add an
+    // attribute to flag these exception's usage as a bug.
+    let checkThrowsNullRefException      f = checkThrowsExn<NullReferenceException>   f
+    let checkThrowsIndexOutRangException f = checkThrowsExn<IndexOutOfRangeException> f
+
+    // Legit exceptions
+    let checkThrowsNotSupportedException f = checkThrowsExn<NotSupportedException>    f
+    let checkThrowsArgumentException     f = checkThrowsExn<ArgumentException>        f
+    let checkThrowsArgumentNullException f = checkThrowsExn<ArgumentNullException>    f
+    let checkThrowsKeyNotFoundException  f = checkThrowsExn<KeyNotFoundException>     f
+    let checkThrowsDivideByZeroException f = checkThrowsExn<DivideByZeroException>    f
+    let checkThrowsInvalidOperationExn   f = checkThrowsExn<InvalidOperationException> f
+
+       
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/App_Code/logic.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/App_Code/logic.fs
new file mode 100755
index 0000000..4a88d22
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/App_Code/logic.fs
@@ -0,0 +1,15 @@
+#light
+module FSharpWeb.Logic
+
+// Calculates a factorial
+let rec factorial x = 
+  if (x <= 1) then 1 else x * (factorial (x - 1))
+  
+// Loading data for the databinding sample  
+type Colors = { Name:string; Rgb:string; }
+let loadData () =  
+  [ { Name="Green"; Rgb="#00ff00" };
+    { Name="Red";   Rgb="#ff0000" };
+    { Name="Blue";  Rgb="#0000ff" }; ]
+    
+  
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/DataBinding.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/DataBinding.aspx
new file mode 100755
index 0000000..dee946e
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/DataBinding.aspx
@@ -0,0 +1,30 @@
+<%@ Page Language="F#" AutoEventWireup="true" CodeFile="DataBinding.aspx.fs" Inherits="FSharpWeb.DataBinding" %>
+
+<!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>Untitled Page</title>
+    <style type="text/css">
+      body { font-family:calibri,verdana,sans-serif; }
+    </style>
+</head>
+<body>
+    <form runat="server">
+    <div>
+      <h1>ASP.NET F# Intro</h1>
+      <p>Other samples: <a href="default.aspx">Factorial</a> | <a href="databinding.aspx">DataBinding</a></p>
+      
+      <h2>Displaying data</h2>
+      <asp:Button id="btnTest" runat="server" text="Click me!" OnClick="ButtonClicked" /><br />
+      <ul>
+      <asp:Repeater id="rptData" runat="server">
+        <itemtemplate>
+          <li style="color:<%# this.Eval("Rgb") %>"><%# this.Eval("Name") %></li>
+        </itemtemplate>
+      </asp:Repeater>
+      </ul>
+    </div>
+    </form>
+</body>
+</html>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/DataBinding.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/DataBinding.aspx.fs
new file mode 100755
index 0000000..230848a
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/DataBinding.aspx.fs
@@ -0,0 +1,22 @@
+#light
+namespace FSharpWeb
+
+open System
+open System.Web
+open System.Web.UI
+open System.Web.UI.WebControls
+
+open FSharpWeb
+
+type DataBinding() =
+  inherit Page()
+  
+  [<DefaultValue>]
+  val mutable btnTest : Button
+  [<DefaultValue>]
+  val mutable rptData : Repeater
+  
+  member x.ButtonClicked(sender, e) =
+    x.rptData.DataSource <- Logic.loadData();
+    x.rptData.DataBind();
+    
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/Default.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/Default.aspx
new file mode 100755
index 0000000..4cdee72
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/Default.aspx
@@ -0,0 +1,24 @@
+<%@ Page Language="F#" AutoEventWireup="true" CodeFile="Default.aspx.fs" Inherits="FSharpWeb.Default" %>
+
+<!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>
+    <title>Untitled Page</title>
+    <style type="text/css">
+      body { font-family:calibri,verdana,sans-serif; }
+    </style>
+</head>
+<body>
+    <form runat="server">
+    <div>
+      <h1>ASP.NET F# Intro</h1>
+      <p>Other samples: <a href="default.aspx">Factorial</a> | <a href="databinding.aspx">DataBinding</a></p>
+      
+      <h2>Calculating factorial</h2>
+      <asp:Button id="Button1" runat="server" text="Click me!" OnClick="ButtonClicked" /><br />
+      <asp:Label id="Label1" runat="server" />
+    </div>
+    </form>
+</body>
+</html>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/Default.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/Default.aspx.fs
new file mode 100755
index 0000000..0c9e5fe
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/Default.aspx.fs
@@ -0,0 +1,32 @@
+#light
+namespace FSharpWeb
+
+open System
+open System.Web
+open System.Web.UI
+open System.Web.UI.WebControls
+
+//open FSharpWeb
+
+type Default() =
+  inherit Page()
+  
+  [<DefaultValue>]
+  val mutable Button1 : Button
+
+  [<DefaultValue>]
+  val mutable Label1 : Label
+
+  member this.ButtonClicked(sender, e) =
+    this.Label1.Text <- 
+      (sprintf "Factorial of 5 is: %d" (FSharpWeb.Logic.factorial 5))
+
+
+(*
+  // initialize all controls to a null value
+  new() = 
+    let init() = (Array.zeroCreate 1).[0]
+    { btnTest = init();
+      Label1 = init(); 
+    }
+*)
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/web.config b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/web.config
new file mode 100755
index 0000000..2208eb4
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetIntro/web.config
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<configuration>
+
+  <system.web>
+    <compilation debug="true">  
+    </compilation>
+  </system.web>
+  
+  <system.codedom>
+    <compilers>
+      <compiler language="F#;f#;fs;fsharp" extension=".fs" type="Microsoft.FSharp.Compiler.CodeDom.FSharpAspNetCodeProvider, FSharp.Compiler.CodeDom, Version=1.9.9.9, Culture=neutral, PublicKeyToken=a19089b1c74d0809"/>
+    </compilers>
+  </system.codedom>
+</configuration>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetTester.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetTester.fs
new file mode 100755
index 0000000..809b981
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/AspNetTester.fs
@@ -0,0 +1,297 @@
+
+namespace FSharp.PowerPack.Unittests
+
+open NUnit.Framework
+open System.IO
+open System.Net
+
+
+// DEBUGGING NOTES:
+//
+// Run this directly: 
+//  "c:\Program Files\Common Files\microsoft shared\DevServer\9.0\WebDev.WebServer.EXE"
+//
+// e.g.
+//
+// "c:\Program Files\Common Files\microsoft shared\DevServer\9.0\WebDev.WebServer.EXE" /port:8082 /path:C:\fsharp\rc1\extras\fsppack\head\src\FSharp.PowerPack.Unittests\ASP.NET\AspNetIntro
+//
+// Then open up http://localhost:8082 and the appropriate page
+
+[<AutoOpen>]
+module AspNetUtilities = 
+
+    let port = 8282
+
+    let http (url: string) =
+        let req = System.Net.WebRequest.Create url
+        use resp = req.GetResponse()
+        use stream = resp.GetResponseStream()
+        use reader = new StreamReader(stream)
+        let html = reader.ReadToEnd()
+        html
+
+    let httpHeaderSum (url: string) =
+        let req = System.Net.WebRequest.Create url
+        use resp = req.GetResponse()
+        use stream = resp.GetResponseStream()
+        use reader = new StreamReader(stream)
+        let html = reader.ReadToEnd()
+        let sum = int (resp.Headers.["Sum"])
+        let ver = new System.Version(resp.Headers.["NetFxVer"])
+        resp.Close()
+        sum,ver
+
+    let startWeb (port : int, webSitePath : string) =
+
+        // Copy the relevant FSharp.Compiler.CodeDom DLL to the website
+        let webSiteBinPath = Path.Combine(webSitePath, @"bin")
+        let codeDomOriginalLocation = typeof<Microsoft.FSharp.Compiler.CodeDom.FSharpAspNetCodeProvider>.Assembly.Location 
+
+        logMessage (sprintf "AspNet WebSite Bin directory: %s" webSiteBinPath)
+        if not (Directory.Exists webSiteBinPath) then 
+            Directory.CreateDirectory(webSiteBinPath) |> ignore
+        logMessage (sprintf "AspNet CodeDom original location: %s" codeDomOriginalLocation)
+        let codeDomRunLocation = Path.Combine(webSiteBinPath, "FSharp.Compiler.CodeDom.dll")
+
+        File.Copy(codeDomOriginalLocation, codeDomRunLocation, true)
+        logMessage (sprintf "AspNet CodeDom copied to: %s" codeDomRunLocation)
+        // Start web server
+
+        let progfile = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles)
+        let webserver90 = Path.Combine(progfile, @"Common Files\microsoft shared\DevServer\9.0\WebDev.WebServer.EXE")
+        let webserver100v2 = Path.Combine(progfile, @"Common Files\microsoft shared\DevServer\10.0\WebDev.WebServer20.EXE")
+        let webserver100v4 = Path.Combine(progfile, @"Common Files\microsoft shared\DevServer\10.0\WebDev.WebServer40.EXE")
+        let webserver = 
+            if File.Exists(webserver100v2) then 
+                if System.Environment.Version.Major = 2 then webserver100v2
+                else webserver100v4
+            elif File.Exists(webserver90) then webserver90 
+            else failwith "No ASP.NET dev web server found."
+        
+        let args = sprintf "/port:%d /path:\"%s\"" port webSitePath
+
+        logMessage (sprintf "Starting web server '%s' args = %A" webserver args)
+        logMessage (sprintf "To debug this test, run \n   \"%s\" %s /port:8082 /path:%s" webserver args webSitePath)
+
+        let psi = new System.Diagnostics.ProcessStartInfo(webserver, args)
+        psi.UseShellExecute <- true
+        let p = System.Diagnostics.Process.Start(psi)
+
+        logMessage (sprintf "AspNet Web Server started, PID = %d" p.Id)
+        p.Id
+
+    let killWeb (webServerPID : int) =
+        try
+            logMessage (sprintf "Killing AspNet Web Server, PID = %d" webServerPID)
+            System.Diagnostics.Process.GetProcessById(webServerPID).Kill()
+        with _ -> ()
+
+
+[<TestFixture>]
+type public AspNet_verySimple() =
+
+    let mutable webserverPID = -1
+
+    [<TestFixtureSetUp>]
+    member this.Setup() = webserverPID <- startWeb(port, Path.Combine(__SOURCE_DIRECTORY__, @"VerySimple"))
+
+    [<TestFixtureTearDown>]
+    member this.TearDown() = if webserverPID <> -1 then killWeb(webserverPID)
+
+  
+    [<Test>]
+    member this.LoadPagesTest() = 
+
+        try
+           logMessage (sprintf "sleeping...")
+           System.Threading.Thread.Sleep 1000
+           logMessage (sprintf "requesting...")
+           let s, v = httpHeaderSum ("http://localhost:" + port.ToString() + "/")
+           if s <> 153 then reportFailure (sprintf "Actual=%d, Expected=%d" s 153)
+           if v <> System.Environment.Version then reportFailure (sprintf "Actual=%A, Expected=%A" v (System.Environment.Version))
+           logMessage (sprintf "AspNet test passed: (%d,%A)" s v)
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
+
+
+[<TestFixture>]
+type public AspNet_Time() =
+
+    let mutable webserverPID = -1
+
+    [<TestFixtureSetUp>]
+    member this.Setup() = 
+        webserverPID <- startWeb(port, Path.Combine(__SOURCE_DIRECTORY__, @"Time"))
+        logMessage (sprintf "sleeping...")
+        System.Threading.Thread.Sleep 1000
+
+    [<TestFixtureTearDown>]
+    member this.TearDown() = if webserverPID <> -1 then killWeb(webserverPID)
+  
+    [<Test>]
+    member this.LoadTimePage() = 
+
+        try
+
+           let html = http ("http://localhost:" + port.ToString() + "/Time.aspx")
+           if not (html.Contains "The current time is") then reportFailure (sprintf "Couldn't find marker text in HTML returned, html = %s" html)
+           logMessage (sprintf "AspNet test Time.aspx passed: (%s)" html)
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
+    [<Test>]
+    member this.LoadTime2Page() = 
+
+        try
+
+           let html = http ("http://localhost:" + port.ToString() + "/Time2.aspx")
+           if not (html.Contains "The current time is") then reportFailure (sprintf "Couldn't find marker text in HTML returned, html = %s" html)
+           logMessage (sprintf "AspNet test Time2.aspx passed: (%s)" html)
+
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
+
+    [<Test>]
+    member this.LoadAsyncTimePage() = 
+
+        try
+
+           let html = http ("http://localhost:" + port.ToString() + "/AsyncTime.aspx")
+           if not (html.Contains "The current time is") then reportFailure (sprintf "Couldn't find marker text in HTML returned, html = %s" html)
+           logMessage (sprintf "AspNet test AsyncTime.aspx passed: (%s)" html)
+
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
+    [<Test>]
+    member this.LoadAsyncTime2Page() = 
+
+        try
+
+           let html = http ("http://localhost:" + port.ToString() + "/AsyncTime2.aspx")
+           if not (html.Contains "The current time is") then reportFailure (sprintf "Couldn't find marker text in HTML returned, html = %s" html)
+           logMessage (sprintf "AspNet test AsyncTime2.aspx passed: (%s)" html)
+
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
+
+[<TestFixture>]
+type public AspNet_AspNetIntro() =
+
+    let mutable webserverPID = -1
+
+    [<TestFixtureSetUp>]
+    member this.Setup() = 
+        webserverPID <- startWeb(port, Path.Combine(__SOURCE_DIRECTORY__, @"AspNetIntro"))
+        logMessage (sprintf "sleeping...")
+        System.Threading.Thread.Sleep 1000
+
+    [<TestFixtureTearDown>]
+    member this.TearDown() = if webserverPID <> -1 then killWeb(webserverPID)
+  
+    [<Test>]
+    member this.LoadDefaultPage() = 
+
+        try
+           logMessage (sprintf "requesting...")
+
+           let html = http ("http://localhost:" + port.ToString() + "/default.aspx")
+           if not (html.Contains "ASP.NET F# Intro") then reportFailure (sprintf "Couldn't find marker text in HTML returned, html = %s" html)
+           logMessage (sprintf "AspNet test default.aspx passed: (%s)" html)
+
+
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
+
+    [<Test>]
+    member this.LoadDataBindingPage() = 
+        try
+           logMessage (sprintf "requesting...")
+
+           let html = http ("http://localhost:" + port.ToString() + "/databinding.aspx")
+           if not (html.Contains "Displaying data") then reportFailure (sprintf "Couldn't find marker text in HTML returned, html = %s" html)
+           logMessage (sprintf "AspNet test databinding.aspx passed: (%s)" html)
+
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
+
+[<TestFixture>]
+type public AspNet_PersonalWebSite() =
+
+    let mutable webserverPID = -1
+
+    [<TestFixtureSetUp>]
+    member this.Setup() = 
+        // Make sure the database MDF files are writable
+        let dbPath =  Path.Combine(__SOURCE_DIRECTORY__, @"PersonalWebSite\App_Data\PERSONAL.MDF")
+
+        if File.Exists dbPath then 
+           File.SetAttributes(dbPath, File.GetAttributes dbPath &&& ~~~FileAttributes.ReadOnly )
+
+        let dbPath =  Path.Combine(__SOURCE_DIRECTORY__, @"PersonalWebSite\App_Data\ASPNETDB.MDF")
+
+        if File.Exists dbPath then 
+           File.SetAttributes(dbPath, File.GetAttributes dbPath &&& ~~~FileAttributes.ReadOnly )
+
+        webserverPID <- startWeb(port, Path.Combine(__SOURCE_DIRECTORY__, @"PersonalWebSite"))
+
+        logMessage (sprintf "sleeping...")
+        System.Threading.Thread.Sleep 1000
+
+    [<TestFixtureTearDown>]
+    member this.TearDown() = if webserverPID <> -1 then killWeb(webserverPID)
+  
+    [<Test>]
+    member this.LoadLinksPage() = 
+
+        try
+           logMessage (sprintf "requesting...")
+
+           let html = http ("http://localhost:" + port.ToString() + "/Links.aspx")
+           if not (html.Contains "About the Links") then reportFailure (sprintf "Couldn't find marker text in HTML returned, html = %s" html)
+           logMessage (sprintf "AspNet test Links.aspx passed: (%s)" html)
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
+    [<Test>]
+    member this.LoadDefaultPage() = 
+
+        try
+           logMessage (sprintf "requesting...")
+
+           let html = http ("http://localhost:" + port.ToString() + "/")
+           if not (html.Contains "Your Name Here") then reportFailure (sprintf "Couldn't find marker text in HTML returned, html = %s" html)
+           logMessage (sprintf "AspNet test default.aspx passed: (%s)" html)
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
+    [<Test>]
+    member this.LoadAlbumsPage() = 
+
+        try
+           logMessage (sprintf "requesting...")
+
+           let html = http ("http://localhost:" + port.ToString() + "/Albums.aspx")
+           if not (html.Contains "Welcome to My Photo Galleries") then reportFailure (sprintf "Couldn't find marker text in HTML returned, html = %s" html)
+           logMessage (sprintf "AspNet test Albums.aspx passed: (%s)" html)
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
+    [<Test>]
+    member this.LoadResumePage() = 
+
+        try
+           logMessage (sprintf "requesting...")
+
+           let html = http ("http://localhost:" + port.ToString() + "/Resume.aspx")
+           if not (html.Contains "Your Name Here") then reportFailure (sprintf "Couldn't find marker text in HTML returned, html = %s" html)
+           logMessage (sprintf "AspNet test Resume.aspx passed: (%s)" html)
+
+        with
+        | e -> reportFailure (sprintf "AspNet test failed: %s" e.Message)
+
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Albums.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Albums.aspx
new file mode 100755
index 0000000..199b5d9
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Albums.aspx
@@ -0,0 +1,104 @@
+<%@ Page Language="F#" MasterPageFile="~/Default.master" Title="Your Name Here | Admin"
+	CodeFile="Albums.aspx.fs" Inherits="PersonalWebSite.Admin_Albums_aspx" %>
+
+<asp:content id="Content1" contentplaceholderid="Main" runat="server">
+
+	<div class="shim column"></div>
+
+	<div class="page" id="admin-albums">
+
+		<div id="sidebar">
+			<h3>Add New Album</h3>
+			<p>Before uploading your pictures, create an album to organize your pictures.</p>
+			<asp:FormView Runat="server"
+				DataSourceID="ObjectDataSource1" DefaultMode="Insert"
+				BorderWidth="0" CellPadding="0">
+				<InsertItemTemplate>
+					<asp:RequiredFieldValidator	ID="RequiredFieldValidator1" Runat="server" ErrorMessage="You must choose a	title." ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
+					<p>
+						Title<br />
+						<asp:TextBox ID="TextBox1" Runat="server" Width="200" Text='<%# Bind("Caption") %>' CssClass="textfield" />
+						<asp:CheckBox ID="CheckBox2" Runat="server" checked='<%# Bind("IsPublic") %>' text="Make this album public" />
+					</p>
+					<p style="text-align:right;">
+						<asp:ImageButton ID="ImageButton1" Runat="server" CommandName="Insert" skinid="add"/>
+					</p>
+				</InsertItemTemplate>
+			</asp:FormView>
+		</div>
+
+		<div id="content">
+			<h3>Your Albums</h3>
+			
+			<p>The following are the albums	currently on your site. Click <b>Edit</b> to modify the pictures in each 
+			album. Click <b>Delete</b> to permanently remove the album and all of its pictures</p>
+			
+			<asp:gridview id="GridView1" runat="server"
+				datasourceid="ObjectDataSource1" datakeynames="AlbumID" cellpadding="6"
+				autogeneratecolumns="False" BorderStyle="None" BorderWidth="0px" width="420px" showheader="false">
+				<EmptyDataTemplate>
+				You currently have no albums.
+				</EmptyDataTemplate>
+				<EmptyDataRowStyle CssClass="emptydata"></EmptyDataRowStyle>
+				<columns>
+					<asp:TemplateField>
+						<ItemStyle Width="116" />
+						<ItemTemplate>
+							<table border="0" cellpadding="0" cellspacing="0" class="photo-frame">
+								<tr>
+									<td class="topx--"></td>
+									<td class="top-x-"></td>
+									<td class="top--x"></td>
+								</tr>
+								<tr>
+									<td class="midx--"></td>
+									<td><a href='Photos.aspx?AlbumID=<%# base.Eval("AlbumID") %>'>
+										<img src="../Handler.ashx?AlbumID=<%# base.Eval("AlbumID") %>&Size=S" class="photo_198" style="border:4px solid white" alt="Sample Photo from Album Number <%# base.Eval("AlbumID") %>" /></a></td>
+									<td class="mid--x"></td>
+								</tr>
+								<tr>
+									<td class="botx--"></td>
+									<td class="bot-x-"></td>
+									<td class="bot--x"></td>
+								</tr>
+							</table>
+						</ItemTemplate>
+					</asp:TemplateField>
+					<asp:TemplateField>
+						<ItemStyle Width="280" />
+						<ItemTemplate>
+							<div style="padding:8px 0;">
+								<b><%# box (this.Server.HtmlEncode(base.Eval("Caption").ToString())) %></b><br />
+								<%# base.Eval("Count") %> Photo(s)<asp:Label ID="Label1" Runat="server" Text=" Public" Visible='<%# base.Eval("IsPublic") %>'></asp:Label>
+							</div>
+							<div style="width:100%;text-align:right;">
+								<asp:ImageButton ID="ImageButton2" Runat="server" CommandName="Edit" SkinID="rename" />
+								<a href='Photos.aspx?AlbumID=<%# base.Eval("AlbumID") %>'><asp:image ID="Image1" runat="Server"  skinid="edit" /></a>
+								<asp:ImageButton ID="ImageButton3" Runat="server" CommandName="Delete" SkinID="delete" />
+							</div>
+						</ItemTemplate>
+						<EditItemTemplate>
+							<div style="padding:8px 0;">
+								<asp:TextBox ID="TextBox2" Runat="server" Width="160" Text='<%# Bind("Caption") %>' CssClass="textfield" />
+								<asp:CheckBox ID="CheckBox1" Runat="server" checked='<%# Bind("IsPublic") %>' text="Public" />
+							</div>
+							<div style="width:100%;text-align:right;">
+								<asp:ImageButton ID="ImageButton4" Runat="server" CommandName="Update" SkinID="save" />
+								<asp:ImageButton ID="ImageButton5" Runat="server" CommandName="Cancel" SkinID="cancel" />
+							</div>
+						</EditItemTemplate>
+					</asp:TemplateField>
+				</columns>
+			</asp:gridview>
+		</div>
+
+	</div>
+	
+	<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server" TypeName="PersonalWebSite.PhotoManager" 
+		SelectMethod="GetAlbums"
+		InsertMethod="AddAlbum" 
+		DeleteMethod="RemoveAlbum" 
+		UpdateMethod="EditAlbum" >
+	</asp:ObjectDataSource>
+
+</asp:content>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Albums.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Albums.aspx.fs
new file mode 100755
index 0000000..32ec063
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Albums.aspx.fs
@@ -0,0 +1,19 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Admin_Albums_aspx = class
+  inherit System.Web.UI.Page
+  val mutable ObjectDataSource1 : ObjectDataSource
+  val mutable GridView1 : GridView
+  new () = { ObjectDataSource1=null; GridView1=null; }
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Details.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Details.aspx
new file mode 100755
index 0000000..a7efbda
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Details.aspx
@@ -0,0 +1,42 @@
+<%@ Page Language="F#" MasterPageFile="~/Default.master" Title="Your Name Here | Admin"
+    CodeFile="Details.aspx.fs" Inherits="PersonalWebSite.Admin_Details_aspx" %>
+
+<asp:content id="Content1" contentplaceholderid="Main" runat="server">
+
+    <div class="shim gradient"></div>
+
+	<div class="page" id="admin-details">
+		<asp:formview id="FormView1" runat="server" datasourceid="ObjectDataSource1" cssclass="view"
+			borderstyle="none" borderwidth="0" CellPadding="0" cellspacing="0" EnableViewState="false">
+			<itemtemplate>
+				<p><%# box (this.Server.HtmlEncode(base.Eval("PhotoCaption").ToString())) %></p>
+				<table border="0" cellpadding="0" cellspacing="0" class="photo-frame">
+					<tr>
+						<td class="topx--"></td>
+						<td class="top-x-"></td>
+						<td class="top--x"></td>
+					</tr>
+					<tr>
+						<td class="midx--"></td>
+						<td><img src="../Handler.ashx?PhotoID=<%# base.Eval("PhotoID") %>&Size=L" class="photo_198" style="border:4px solid white" alt='Photo Number <%# base.Eval("PhotoID") %>' /></a></td>
+						<td class="mid--x"></td>
+					</tr>
+					<tr>
+						<td class="botx--"></td>
+						<td class="bot-x-"></td>
+						<td class="bot--x"></td>
+					</tr>
+				</table>
+				<p> </p>
+			</itemtemplate>
+		</asp:formview>
+	</div>
+
+	<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server" TypeName="PersonalWebSite.PhotoManager" 
+		SelectMethod="GetPhotos">
+		<SelectParameters>
+			<asp:QueryStringParameter Name="AlbumID" Type="Int32" QueryStringField="AlbumID" DefaultValue="0"/>
+		</SelectParameters>
+	</asp:ObjectDataSource>
+
+</asp:content>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Details.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Details.aspx.fs
new file mode 100755
index 0000000..a003dfb
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Details.aspx.fs
@@ -0,0 +1,24 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Admin_Details_aspx = class
+  inherit System.Web.UI.Page
+  val mutable ObjectDataSource1 : ObjectDataSource
+  val mutable FormView1 : FormView
+  new () = { FormView1=null; ObjectDataSource1=null;}
+  
+  member this.Page_Load(sender:obj, e:EventArgs) =
+    if (not this.IsPostBack) then
+      let i = Convert.ToInt32(this.Request.QueryString.get_Item("Page"))
+      if (i >= 0) then this.FormView1.PageIndex <- i;
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Photos.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Photos.aspx
new file mode 100755
index 0000000..7c300ec
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Photos.aspx
@@ -0,0 +1,114 @@
+<%@	Page Language="F#" MasterPageFile="~/Default.master" Title="Your Name Here | Admin"
+	CodeFile="Photos.aspx.fs" Inherits="PersonalWebSite.Admin_Photos_aspx" %>
+
+<asp:content id="Content1" contentplaceholderid="Main" runat="server">
+
+	<div class="shim column"></div>
+	
+	<div class="page" id="admin-photos">
+		<div id="sidebar">
+			<h4>Bulk Upload	Photos</h4>
+			<p>The following files were found in your <b>Upload</b>	folder. Click on <b>Import</b>	to import these	pictures to your photo album. This operation may take a	few moments.</p>
+			<asp:ImageButton Runat="server" onclick="Button1_Click" SkinID="import" />
+			<br />
+			<br />
+			<asp:datalist runat="server" repeatcolumns="1" repeatlayout="table" repeatdirection="horizontal" DataSourceID="ObjectDataSource2">
+				<itemtemplate>
+					<%#	Container.DataItem %>
+				</itemtemplate>
+			</asp:datalist>
+		</div>
+
+		<div id="content">
+			<h4>Add	Photos</h4>
+			<p>To add single photos	over HTTP, select a file and caption, then click <b>Add</b>.</p>
+			<asp:FormView ID="FormView1" Runat="server" 
+				DataSourceID="ObjectDataSource1" DefaultMode="insert"
+				BorderWidth="0px" CellPadding="0" OnItemInserting="FormView1_ItemInserting">
+				<InsertItemTemplate>
+					<asp:RequiredFieldValidator	ID="RequiredFieldValidator1" Runat="server" ErrorMessage="You must choose a caption." ControlToValidate="PhotoFile" Display="Dynamic" Enabled="false" />
+					<p>
+						Photo<br />
+						<asp:FileUpload ID="PhotoFile" Runat="server" Width="416" FileBytes='<%# Bind("BytesOriginal") %>' CssClass="textfield" /><br />
+						Caption<br />
+						<asp:TextBox ID="PhotoCaption" Runat="server" Width="326" Text='<%# Bind("PhotoCaption") %>' CssClass="textfield" />
+					</p>
+					<p style="text-align:right;">
+						<asp:ImageButton ID="AddNewPhotoButton" Runat="server" CommandName="Insert" skinid="add"/>
+					</p>
+				</InsertItemTemplate>
+			</asp:FormView>
+			<hr />
+			<h4>Photos in This Album</h4>
+			<p>The following are the photos	currently in this album.</p>
+			<asp:gridview id="GridView1" runat="server" datasourceid="ObjectDataSource1" 
+				datakeynames="PhotoID" cellpadding="6" EnableViewState="false"
+				autogeneratecolumns="False" BorderStyle="None" BorderWidth="0px" width="420px" showheader="false" >
+				<EmptyDataRowStyle CssClass="emptydata"></EmptyDataRowStyle>
+				<EmptyDataTemplate>
+					You currently have no photos.
+				</EmptyDataTemplate>
+				<columns>
+					<asp:TemplateField>
+						<ItemStyle Width="50" />
+						<ItemTemplate>
+							<table border="0" cellpadding="0" cellspacing="0" class="photo-frame">
+								<tr>
+									<td class="topx--"></td>
+									<td class="top-x-"></td>
+									<td class="top--x"></td>
+								</tr>
+								<tr>
+									<td class="midx--"></td>
+									<td><a href='Details.aspx?AlbumID=<%# base.Eval("PhotoAlbumID") %>&Page=<%# box (Container :?> GridViewRow).RowIndex %>'>
+										<img src='../Handler.ashx?Size=S&PhotoID=<%# base.Eval("PhotoID") %>' class="photo_198" style="border:2px solid white;width:50px;" alt='Thumbnail of Photo Number <%# base.Eval("PhotoID") %>' /></a></td>
+									<td class="mid--x"></td>
+								</tr>
+								<tr>
+									<td class="botx--"></td>
+									<td class="bot-x-"></td>
+									<td class="bot--x"></td>
+								</tr>
+							</table>
+						</ItemTemplate>
+					</asp:TemplateField>
+					<asp:boundfield headertext="Caption" datafield="PhotoCaption" />
+					<asp:TemplateField>
+						<ItemStyle Width="150" />
+						<ItemTemplate>
+							<div style="width:100%;text-align:right;">
+								<asp:ImageButton ID="ImageButton2" Runat="server" CommandName="Edit" SkinID="rename" />
+								<asp:ImageButton ID="ImageButton3" Runat="server" CommandName="Delete"  SkinID="delete" />
+							</div>
+						</ItemTemplate>
+						<EditItemTemplate>
+							<div style="width:100%;text-align:right;">
+								<asp:ImageButton ID="ImageButton4" Runat="server" CommandName="Update" SkinID="save" />
+								<asp:ImageButton ID="ImageButton5" Runat="server" CommandName="Cancel"  SkinID="cancel" />
+							</div>
+						</EditItemTemplate>
+					</asp:TemplateField>
+				</columns>
+			</asp:gridview>
+		</div>
+
+	 </div>
+	
+	<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server" TypeName="PersonalWebSite.PhotoManager" 
+		SelectMethod="GetPhotos"
+		InsertMethod="AddPhoto" 
+		DeleteMethod="RemovePhoto" 
+		UpdateMethod="EditPhoto" >
+		<SelectParameters>
+			<asp:QueryStringParameter Name="AlbumID" Type="Int32" QueryStringField="AlbumID" />
+		</SelectParameters>
+		<InsertParameters>
+			<asp:QueryStringParameter Name="AlbumID" Type="Int32" QueryStringField="AlbumID" />
+		</InsertParameters>
+	</asp:ObjectDataSource>
+	
+	<asp:ObjectDataSource ID="ObjectDataSource2" Runat="server" TypeName="PersonalWebSite.PhotoManager" 
+		SelectMethod="ListUploadDirectory" >
+	</asp:ObjectDataSource>
+	 
+</asp:content>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Photos.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Photos.aspx.fs
new file mode 100755
index 0000000..51bcd6e
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Admin/Photos.aspx.fs
@@ -0,0 +1,40 @@
+#light
+namespace PersonalWebSite
+
+open PersonalWebSite
+
+open System;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+open System.Data;
+open System.Data.OleDb;
+open System.IO;
+
+type Admin_Photos_aspx = class
+  inherit System.Web.UI.Page
+  
+  val mutable ObjectDataSource1 : ObjectDataSource;
+  val mutable ObjectDataSource2 : ObjectDataSource;
+  val mutable FormView1 : FormView
+  val mutable GridView1 : GridView
+  
+  new () = { ObjectDataSource2=null; ObjectDataSource1=null; FormView1=null; GridView1=null; }
+
+  member this.FormView1_ItemInserting(sender:obj, e:FormViewInsertEventArgs) =
+    if ((e.Values.get_Item("BytesOriginal") :?> byte[]).Length = 0) then e.Cancel <- true
+
+  member this.Button1_Click(sender:obj, e:ImageClickEventArgs) =
+    let d = new DirectoryInfo(this.Server.MapPath("~/Upload"));
+    for f in d.GetFiles("*.jpg") do
+      using (f.OpenRead()) (fun sr ->
+        let siz = int (sr.Length);
+        let buffer = ((Array.zeroCreate siz):byte[])
+        sr.Read(buffer, 0, siz) |> ignore
+        PhotoManager.AddPhoto (Convert.ToInt32(this.Request.QueryString.get_Item("AlbumID")), f.Name, buffer) )
+    this.GridView1.DataBind();
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Albums.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Albums.aspx
new file mode 100755
index 0000000..b254504
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Albums.aspx
@@ -0,0 +1,60 @@
+<%@ Page Language="F#" MasterPageFile="~/Default.master" Title="Your Name Here | Albums"
+    CodeFile="Albums.aspx.fs" Inherits="PersonalWebSite.Albums_aspx" %>
+
+<asp:content id="Content1" contentplaceholderid="Main" runat="server">
+
+    <div class="shim gradient"></div>
+
+    <div class="page" id="albums">
+
+        <h3>Welcome to My Photo Galleries</h3>
+        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod 
+        tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis 
+        nostrud exercitation consequat. esse molestie consequat, vel willum.</p>
+        <hr />
+        <asp:DataList ID="DataList1" runat="Server"  dataSourceID="ObjectDataSource1" cssclass="view"
+            repeatColumns="2" repeatdirection="Horizontal" borderwidth="0" cellpadding="0" cellspacing="0">
+            <ItemStyle cssClass="item" />
+            <ItemTemplate>
+                <table border="0" cellpadding="0" cellspacing="0" class="album-frame">
+                    <tr>
+                        <td class="topx----"><asp:image runat="Server" id="b01" skinid="b01" /></td>
+                        <td class="top-x---"><asp:image runat="Server" id="b02" skinid="b02" /></td>
+                        <td class="top--x--"></td>
+                        <td class="top---x-"><asp:image runat="Server" id="b03" skinid="b03" /></td>
+                        <td class="top----x"><asp:image runat="Server" id="b04" skinid="b04" /></td>
+                    </tr>
+                    <tr>
+                        <td class="mtpx----"><asp:image runat="Server" id="b05" skinid="b05" /></td>
+                        <td colspan="3" rowspan="3"><a href='Photos.aspx?AlbumID=<%# base.Eval("AlbumID") %>' ><img src="Handler.ashx?AlbumID=<%# base.Eval("AlbumID") %>&Size=M" class="photo_198" style="border:4px solid white" alt='Sample Photo from Album Number <%# base.Eval("AlbumID") %>' /></a></td>
+                        <td class="mtp----x"><asp:image runat="Server" id="b06" skinid="b06" /></td>
+                    </tr>
+                    <tr>
+                        <td class="midx----"></td>
+                        <td class="mid----x"></td>
+                    </tr>
+                    <tr>
+                        <td class="mbtx----"><asp:image runat="Server" id="b07" skinid="b07" /></td>
+                        <td class="mbt----x"><asp:image runat="Server" id="b08" skinid="b08" /></td>
+                    </tr>
+                    <tr>
+                        <td class="botx----"><asp:image runat="Server" id="b09" skinid="b09" /></td>
+                        <td class="bot-x---"><asp:image runat="Server" id="b10" skinid="b10" /></td>
+                        <td class="bot--x--"></td>
+                        <td class="bot---x-"><asp:image runat="Server" id="b11" skinid="b11" /></td>
+                        <td class="bot----x"><asp:image runat="Server" id="b12" skinid="b12" /></td>
+                    </tr>
+                </table>
+				<h4><a href="Photos.aspx?AlbumID=<%# base.Eval("AlbumID") %>"><%# box (this.Server.HtmlEncode(base.Eval("Caption").ToString())) %></a></h4>
+				<%# base.Eval("Count") %> Photo(s)
+            </ItemTemplate>
+        </asp:DataList>
+    
+    </div>
+
+	<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server" TypeName="PersonalWebSite.PhotoManager" 
+		SelectMethod="GetAlbums">
+	</asp:ObjectDataSource>
+    
+
+</asp:content>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Albums.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Albums.aspx.fs
new file mode 100755
index 0000000..61487db
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Albums.aspx.fs
@@ -0,0 +1,20 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Albums_aspx = class
+  inherit System.Web.UI.Page
+  
+  val mutable ObjectDataSource1 : ObjectDataSource
+  val mutable DataList1 : DataList
+  new () =  { ObjectDataSource1 = null; DataList1 = null; }
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Code/PhotoManager.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Code/PhotoManager.fs
new file mode 100755
index 0000000..5da6b17
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Code/PhotoManager.fs
@@ -0,0 +1,203 @@
+#light
+namespace PersonalWebSite
+#nowarn "49" // uppercase argument names required by ASP.NET data binding
+
+open System
+open System.Collections
+open System.Collections.Generic
+open System.Configuration
+open System.Data
+open System.Data.SqlClient
+open System.Drawing
+open System.Drawing.Drawing2D
+open System.Drawing.Imaging
+open System.IO
+open System.Web
+open System.Configuration
+
+// Record types can be used for storing data from DB
+type Album = { AlbumID:int; Count:int; Caption:string; IsPublic:bool }
+type Photo = { PhotoID:int; PhotoAlbumID:int; PhotoCaption:string; }
+
+type PhotoSize =
+  | Small = 1     // 100px
+  | Medium = 2    // 198px
+  | Large = 3     // 600px
+  | Original = 4  // Original Size
+
+// Module with all web functionality used by databinding
+module PhotoManager = 
+
+  // Helper Functions
+  let CalculateDimensions ((width, height) : int*int) (targetSize:int) =
+    if (height > width) then
+      (int32 ((float width) * ((float targetSize) / (float height))), targetSize)
+    else
+      (targetSize, int32 ((float height) * ((float targetSize) / (float width))))
+    
+  let ResizeImageFile (imageFile:byte[]) (targetSize:int) =
+    use oldImage = System.Drawing.Image.FromStream(new MemoryStream(imageFile))
+    let (nw, nh) = CalculateDimensions (oldImage.Width, oldImage.Height) targetSize
+    use newImage = new Bitmap(nw, nh, PixelFormat.Format24bppRgb)
+    use canvas = Graphics.FromImage(newImage)
+    canvas.SmoothingMode <- SmoothingMode.AntiAlias
+    canvas.InterpolationMode <- InterpolationMode.HighQualityBicubic
+    canvas.PixelOffsetMode <- PixelOffsetMode.HighQuality
+    canvas.DrawImage(oldImage, Rectangle(Point(0, 0), Size(nw, nh))) 
+    let m = new MemoryStream()
+    newImage.Save(m, ImageFormat.Jpeg)
+    m.GetBuffer() 
+
+  let ListUploadDirectory() =
+    let d = new DirectoryInfo(System.Web.HttpContext.Current.Server.MapPath("~/Upload"))
+    d.GetFileSystemInfos("*.jpg")
+    
+  // Photo-Related Methods
+  let GetPhoto (photoid:int) (size:PhotoSize) = 
+    let isize = (unbox (box size)) : int in
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString)
+    use command = new SqlCommand("GetPhoto", connection)
+    command.CommandType <- CommandType.StoredProcedure
+    command.Parameters.Add(SqlParameter("@PhotoID", photoid)) |> ignore
+    command.Parameters.Add(SqlParameter("@Size", isize)) |> ignore
+    let filter = not (HttpContext.Current.User.IsInRole("Friends") || HttpContext.Current.User.IsInRole("Administrators"))
+    command.Parameters.Add(SqlParameter("@IsPublic", filter)) |> ignore
+    connection.Open()
+    let result = command.ExecuteScalar()
+    try 
+      new MemoryStream(result :?> byte[])
+    with _ -> 
+      null 
+
+  let GetDefaultPhoto (size:PhotoSize) =
+    let path = HttpContext.Current.Server.MapPath("~/Images/")
+    let ext = 
+      match size with 
+        | PhotoSize.Small  -> "placeholder-100.jpg"
+        | PhotoSize.Medium -> "placeholder-200.jpg"
+        | PhotoSize.Large  -> "placeholder-600.jpg"
+        | _ ->                "placeholder-600.jpg"
+    new FileStream(path + ext, FileMode.Open, FileAccess.Read, FileShare.Read)
+
+  let GetFirstPhoto (albumid:int) (size:PhotoSize) =
+    let isize = (unbox (box size)) : int in
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString)
+    use command = new SqlCommand("GetFirstPhoto", connection)
+    command.CommandType <- CommandType.StoredProcedure
+    command.Parameters.Add(SqlParameter("@AlbumID", albumid)) |> ignore
+    command.Parameters.Add(SqlParameter("@Size", isize)) |> ignore
+    let filter = not (HttpContext.Current.User.IsInRole("Friends") || HttpContext.Current.User.IsInRole("Administrators"))
+    command.Parameters.Add(SqlParameter("@IsPublic", filter)) |> ignore
+    connection.Open()
+    let result = command.ExecuteScalar()
+    try
+      new MemoryStream(result :?> byte[])
+    with _ ->
+      null
+ 
+  let GetPhotos (albumID:int) =
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString)
+    use command = new SqlCommand("GetPhotos", connection)
+    command.CommandType <- CommandType.StoredProcedure
+    command.Parameters.Add(SqlParameter("@AlbumID", albumID)) |> ignore
+    let filter = not (HttpContext.Current.User.IsInRole("Friends") || HttpContext.Current.User.IsInRole("Administrators"))
+    command.Parameters.Add(SqlParameter("@IsPublic", filter)) |> ignore
+    connection.Open()
+    let list = new List<Photo>()
+    use reader = command.ExecuteReader()
+    while (reader.Read()) do
+      let temp = {PhotoID = unbox (reader.get_Item("PhotoID")); PhotoAlbumID = unbox (reader.get_Item("AlbumID")); PhotoCaption = unbox (reader.get_Item("Caption"))}
+      list.Add(temp) 
+    list 
+
+  let GetRandomAlbumID() =
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString)
+    use command = new SqlCommand("GetNonEmptyAlbums", connection)
+    command.CommandType <- CommandType.StoredProcedure
+    connection.Open()
+    let list = new List<int>()
+    use reader = command.ExecuteReader()
+    while (reader.Read()) do
+      list.Add(unbox (reader.get_Item("AlbumID"))) 
+    try
+      let r = Random()
+      list.get_Item(r.Next(list.Count))
+    with _ ->
+      -1 
+    
+  let GetRandomPhotos () = GetPhotos (GetRandomAlbumID())
+  
+  let AddPhoto (AlbumID:int, PhotoCaption:string, BytesOriginal:byte[]) =
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString) 
+    use command = new SqlCommand("AddPhoto", connection) 
+    command.CommandType <- CommandType.StoredProcedure
+    command.Parameters.Add(SqlParameter("@AlbumID", AlbumID)) |> ignore
+    command.Parameters.Add(SqlParameter("@Caption", PhotoCaption)) |> ignore
+    command.Parameters.Add(SqlParameter("@BytesOriginal", BytesOriginal)) |> ignore
+    command.Parameters.Add(SqlParameter("@BytesFull", ResizeImageFile BytesOriginal 600)) |> ignore
+    command.Parameters.Add(SqlParameter("@BytesPoster", ResizeImageFile BytesOriginal 198)) |> ignore
+    command.Parameters.Add(SqlParameter("@BytesThumb", ResizeImageFile BytesOriginal 100)) |> ignore
+    connection.Open()
+    command.ExecuteNonQuery() 
+
+  let RemovePhoto (PhotoID:int) =
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString)
+    use command = new SqlCommand("RemovePhoto", connection)
+    command.CommandType <- CommandType.StoredProcedure
+    command.Parameters.Add(SqlParameter("@PhotoID", PhotoID)) |> ignore
+    connection.Open()
+    command.ExecuteNonQuery() 
+
+  let EditPhoto (PhotoCaption:string, PhotoID:int) =
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString)
+    use command = new SqlCommand("EditPhoto", connection)
+    command.CommandType <- CommandType.StoredProcedure
+    command.Parameters.Add(SqlParameter("@Caption", PhotoCaption)) |> ignore
+    command.Parameters.Add(SqlParameter("@PhotoID", PhotoID)) |> ignore
+    connection.Open()
+    command.ExecuteNonQuery() 
+
+  // Album-Related Methods
+
+  let GetAlbums() =
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString)
+    use command = new SqlCommand("GetAlbums", connection)
+    command.CommandType <- CommandType.StoredProcedure
+    let filter = not (HttpContext.Current.User.IsInRole("Friends") || HttpContext.Current.User.IsInRole("Administrators"))
+    command.Parameters.Add(SqlParameter("@IsPublic", filter)) |> ignore
+    connection.Open()
+    let list = new List<Album>()
+    use reader = command.ExecuteReader()
+    while (reader.Read()) do
+      let temp = { AlbumID = unbox (reader.get_Item("AlbumID")); Count = unbox (reader.get_Item("NumberOfPhotos"));
+                   Caption = unbox (reader.get_Item("Caption")); IsPublic = unbox (reader.get_Item("IsPublic"))}
+      list.Add(temp) 
+    list 
+
+  let AddAlbum (Caption:string, IsPublic:bool) =
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString)
+    use command = new SqlCommand("AddAlbum", connection)
+    command.CommandType <- CommandType.StoredProcedure
+    command.Parameters.Add(SqlParameter("@Caption", Caption)) |> ignore
+    command.Parameters.Add(SqlParameter("@IsPublic", IsPublic)) |> ignore
+    connection.Open()
+    command.ExecuteNonQuery() 
+
+  let RemoveAlbum (AlbumID:int) =
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString)
+    use command = new SqlCommand("RemoveAlbum", connection)
+    command.CommandType <- CommandType.StoredProcedure
+    command.Parameters.Add(SqlParameter("@AlbumID", AlbumID)) |> ignore
+    connection.Open()
+    command.ExecuteNonQuery()
+
+  let EditAlbum (Caption:string) (IsPublic:bool) (AlbumID:int) =
+    use connection = new SqlConnection(ConfigurationManager.ConnectionStrings.get_Item("Personal").ConnectionString)
+    use command = new SqlCommand("EditAlbum", connection)
+    command.CommandType <- CommandType.StoredProcedure
+    command.Parameters.Add(SqlParameter("@Caption", Caption)) |> ignore
+    command.Parameters.Add(SqlParameter("@IsPublic", IsPublic)) |> ignore
+    command.Parameters.Add(SqlParameter("@AlbumID", AlbumID)) |> ignore
+    connection.Open()
+    command.ExecuteNonQuery() 
+
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/ASPNETDB.MDF b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/ASPNETDB.MDF
new file mode 100755
index 0000000..8406496
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/ASPNETDB.MDF differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/Personal.mdf b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/Personal.mdf
new file mode 100755
index 0000000..dcaec67
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/Personal.mdf differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/Personal_log.ldf b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/Personal_log.ldf
new file mode 100755
index 0000000..4562407
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/Personal_log.ldf differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/aspnetdb_log.ldf b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/aspnetdb_log.ldf
new file mode 100755
index 0000000..7652f69
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/aspnetdb_log.ldf differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/personal-add.sql b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/personal-add.sql
new file mode 100755
index 0000000..7966849
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/personal-add.sql
@@ -0,0 +1,203 @@
+CREATE TABLE [Albums] (
+	[AlbumID] [int] IDENTITY (1, 1) NOT NULL ,
+	[Caption] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
+	[IsPublic] [bit] NOT NULL 
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [Photos] (
+	[PhotoID] [int] IDENTITY (1, 1) NOT NULL ,
+	[AlbumID] [int] NOT NULL ,
+	[Caption] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
+	[BytesOriginal] [image] NOT NULL ,
+	[BytesFull] [image] NOT NULL ,
+	[BytesPoster] [image] NOT NULL ,
+	[BytesThumb] [image] NOT NULL 
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+ALTER TABLE [Albums]
+	ADD CONSTRAINT [PK_Albums] PRIMARY KEY
+		CLUSTERED ([AlbumID])ON [PRIMARY]
+GO
+
+ALTER TABLE [Photos]
+	ADD CONSTRAINT [PK_Photos] PRIMARY KEY
+		CLUSTERED ([PhotoID]) ON [PRIMARY]
+GO
+
+ALTER TABLE [Photos]
+	ADD CONSTRAINT [FK_Photos_Albums] FOREIGN KEY ([AlbumID])
+	REFERENCES [Albums] ([AlbumID])
+		ON DELETE CASCADE
+		ON UPDATE CASCADE
+GO
+
+
+SET QUOTED_IDENTIFIER ON 
+GO
+SET ANSI_NULLS ON 
+GO
+
+
+CREATE PROCEDURE AddAlbum
+	@Caption nvarchar(50),
+	@IsPublic bit
+AS
+	INSERT INTO [Albums] ([Caption],[IsPublic]) VALUES (@Caption, @IsPublic)
+RETURN
+GO
+
+CREATE PROCEDURE AddPhoto
+		@AlbumID int,
+		@Caption nvarchar(50),
+		@BytesOriginal image,
+		@BytesFull image,
+		@BytesPoster image,
+		@BytesThumb image
+AS
+	INSERT INTO [Photos] (
+		[AlbumID],
+		[BytesOriginal],
+		[Caption],
+		[BytesFull],
+		[BytesPoster],
+		[BytesThumb] )
+	VALUES (
+		@AlbumID,
+		@BytesOriginal,
+		@Caption,
+		@BytesFull,
+		@BytesPoster,
+		@BytesThumb )
+RETURN
+GO
+
+CREATE PROCEDURE EditAlbum
+	@Caption nvarchar(50),
+	@IsPublic bit,
+	@AlbumID int
+AS
+	UPDATE [Albums] 
+	SET 
+		[Caption] = @Caption, 
+		[IsPublic] = @IsPublic 
+	WHERE 
+		[AlbumID] = @AlbumID
+RETURN
+GO
+
+CREATE PROCEDURE EditPhoto
+	@Caption nvarchar(50),
+	@PhotoID int
+AS
+	UPDATE [Photos]
+	SET [Caption] = @Caption
+	WHERE [PhotoID]	= @PhotoID
+RETURN
+GO
+
+CREATE PROCEDURE GetAlbums
+	@IsPublic bit
+AS
+	SELECT 
+		[Albums].[AlbumID], 
+		[Albums].[Caption], 
+		[Albums].[IsPublic], 
+		Count([Photos].[PhotoID]) AS NumberOfPhotos 
+	FROM [Albums] LEFT JOIN [Photos] 
+		ON [Albums].[AlbumID] = [Photos].[AlbumID] 
+	WHERE
+		([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+	GROUP BY 
+		[Albums].[AlbumID], 
+		[Albums].[Caption], 
+		[Albums].[IsPublic]
+RETURN
+GO
+
+CREATE PROCEDURE GetFirstPhoto
+	@AlbumID int,
+	@Size int,
+	@IsPublic bit
+AS
+	IF @Size = 1
+		SELECT TOP 1 [BytesThumb] FROM [Photos] LEFT JOIN [Albums] ON [Albums].[AlbumID] = [Photos].[AlbumID] WHERE [Albums].[AlbumID] = @AlbumID AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+	ELSE IF @Size = 2
+		SELECT TOP 1 [BytesPoster] FROM [Photos] LEFT JOIN [Albums] ON [Albums].[AlbumID] = [Photos].[AlbumID] WHERE [Albums].[AlbumID] = @AlbumID AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+	ELSE IF @Size = 3
+		SELECT TOP 1 [BytesFull] FROM [Photos] LEFT JOIN [Albums] ON [Albums].[AlbumID] = [Photos].[AlbumID] WHERE [Albums].[AlbumID] = @AlbumID AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+	ELSE IF @Size = 4
+		SELECT TOP 1 [BytesOriginal] FROM [Photos] LEFT JOIN [Albums] ON [Albums].[AlbumID] = [Photos].[AlbumID] WHERE [Albums].[AlbumID] = @AlbumID AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+	ELSE
+		SELECT TOP 1 [BytesPoster] FROM [Photos] LEFT JOIN [Albums] ON [Albums].[AlbumID] = [Photos].[AlbumID] WHERE [Albums].[AlbumID] = @AlbumID AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+RETURN
+GO
+
+CREATE PROCEDURE GetNonEmptyAlbums
+AS
+	SELECT 
+		[Albums].[AlbumID]
+	FROM [Albums] LEFT JOIN [Photos] 
+		ON [Albums].[AlbumID] = [Photos].[AlbumID] 
+	WHERE
+		[Albums].[IsPublic] = 1
+	GROUP BY 
+		[Albums].[AlbumID], 
+		[Albums].[Caption], 
+		[Albums].[IsPublic]
+	HAVING
+		Count([Photos].[PhotoID]) > 0
+RETURN
+GO
+
+CREATE PROCEDURE GetPhoto
+	@PhotoID int,
+	@Size int,
+	@IsPublic bit
+AS
+	IF @Size = 1
+		SELECT TOP 1 [BytesThumb] FROM [Photos] LEFT JOIN [Albums] ON [Albums].[AlbumID] = [Photos].[AlbumID] WHERE [PhotoID] = @PhotoID AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+	ELSE IF @Size = 2
+		SELECT TOP 1 [BytesPoster] FROM [Photos] LEFT JOIN [Albums] ON [Albums].[AlbumID] = [Photos].[AlbumID] WHERE [PhotoID] = @PhotoID AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+	ELSE IF @Size = 3
+		SELECT TOP 1 [BytesFull] FROM [Photos] LEFT JOIN [Albums] ON [Albums].[AlbumID] = [Photos].[AlbumID] WHERE [PhotoID] = @PhotoID AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+	ELSE IF @Size = 4
+		SELECT TOP 1 [BytesOriginal] FROM [Photos] LEFT JOIN [Albums] ON [Albums].[AlbumID] = [Photos].[AlbumID] WHERE [PhotoID] = @PhotoID AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+	ELSE
+		SELECT TOP 1 [BytesPoster] FROM [Photos] LEFT JOIN [Albums] ON [Albums].[AlbumID] = [Photos].[AlbumID] WHERE [PhotoID] = @PhotoID AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+RETURN
+GO
+
+CREATE PROCEDURE GetPhotos
+	@AlbumID int,
+	@IsPublic bit
+AS
+	SELECT *
+	FROM [Photos] LEFT JOIN [Albums]
+		ON [Albums].[AlbumID] = [Photos].[AlbumID] 
+	WHERE [Photos].[AlbumID] = @AlbumID
+		AND ([Albums].[IsPublic] = @IsPublic OR [Albums].[IsPublic] = 1)
+RETURN
+GO
+
+CREATE PROCEDURE RemoveAlbum
+	@AlbumID int
+AS
+	DELETE FROM [Albums] WHERE [AlbumID] = @AlbumID
+RETURN
+GO
+
+CREATE PROCEDURE RemovePhoto
+	@PhotoID int
+AS
+	DELETE FROM [Photos]
+	WHERE [PhotoID]	= @PhotoID
+RETURN
+GO
+
+
+SET QUOTED_IDENTIFIER OFF 
+GO
+SET ANSI_NULLS ON 
+GO
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/personal-remove.sql b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/personal-remove.sql
new file mode 100755
index 0000000..b8f570e
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Data/personal-remove.sql
@@ -0,0 +1,55 @@
+if exists (select * from dbo.sysobjects where id = object_id(N'[FK_Photos_Albums]') and OBJECTPROPERTY(id, N'IsForeignKey') = 1)
+ALTER TABLE [Photos] DROP CONSTRAINT FK_Photos_Albums
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[AddAlbum]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [AddAlbum]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[AddPhoto]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [AddPhoto]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[EditAlbum]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [EditAlbum]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[EditPhoto]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [EditPhoto]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[GetAlbums]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [GetAlbums]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[GetFirstPhoto]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [GetFirstPhoto]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[GetNonEmptyAlbums]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [GetNonEmptyAlbums]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[GetPhoto]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [GetPhoto]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[GetPhotos]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [GetPhotos]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[RemoveAlbum]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [RemoveAlbum]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[RemovePhoto]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
+drop procedure [RemovePhoto]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[Albums]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
+drop table [Albums]
+GO
+
+if exists (select * from dbo.sysobjects where id = object_id(N'[Photos]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
+drop table [Photos]
+GO
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Default.css b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Default.css
new file mode 100755
index 0000000..b17e3c1
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Default.css
@@ -0,0 +1,326 @@
+/* 0 BASIC TAGS */
+
+table {
+	font-size: 1em;
+}
+
+h1, h2, h3, h4 {
+	margin: 0;
+	font-family: Tahoma, Arial, Helvetica, sans-serif;
+}
+
+p {
+	line-height: 1.4em;
+}
+
+hr {
+	border: 0;
+	border-top: 1px solid #505050;
+	height: 1px;
+}
+
+a {
+	text-decoration: none;
+	color: #DBB94F;
+}
+
+a:visited {
+	color: #C19B28;
+}
+
+a:hover {
+	text-decoration: underline;
+	color: #E6CD84;
+}
+
+a:active {
+	color: #C19B28;
+}
+
+body {
+	background-color: #656565;
+	background-image: url(Images/background.gif);
+	background-repeat: repeat;
+	margin: 0;
+	padding: 0;
+	text-align: center;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 0.7em;
+	color: #FFFFFF;
+}
+
+img {
+	border-width: 0;
+}
+
+/* 1 HEADER */
+
+.header {
+	background-image: url(Images/header.gif);
+	background-repeat: no-repeat;
+	position: relative;
+	width: 789px;
+	height: 76px;
+	margin: 0 auto 5px auto;
+}
+
+
+h1 {
+	position: absolute;
+	left: 37px;
+	top: 12px;
+	text-transform: uppercase;
+	font-size: 18px;
+}
+
+h2 {
+	position: absolute;
+	left: 37px;
+	top: 45px;
+	font-size: 11px;
+}
+
+.menua {
+	position: absolute;
+	right: 37px;
+	top: 13px;
+	text-transform: uppercase;
+	font-size: 10px;
+}
+
+.nav {
+	position: absolute;
+	right: 37px;
+	top: 51px;
+	text-transform: uppercase;
+	font-size: 10px;
+}
+
+.menua a:visited, .nav a:visited {
+	color: #DBB94F;
+}
+
+/* 1.1 SHIM */
+
+.shim {
+	display: none;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* 2 PAGE */
+
+.page {
+	background-repeat: repeat-y;
+	margin-left: auto;
+	margin-right: auto;
+	text-align: left;
+}
+
+h3 {
+	margin-top: 1.0em;
+	margin-bottom: 1.12em;
+	font-size: 1.5em;
+	font-weight: bold;
+}
+h4 {
+	margin-top: 1.0em;
+	margin-bottom: 1.12em;
+	font-size: 1.3em;
+	font-weight: bold;
+}
+
+/* 2.1 ALL PAGES */
+
+#home, #resume, #links, #albums, #photos, #details, #register, #admin-albums, #admin-photos, #admin-details {
+	
+	position: relative;
+	width: 686px;
+	padding: 0px 37px;
+	padding-top: 1px; /* Weird Mozilla Bug */
+	padding-bottom: 40px; /* Weird Mozilla Bug */
+}
+
+#sidebar {
+	float: left;
+	width: 214px;
+	height: 100%;
+}
+
+#content {
+	margin-left: 256px;
+}
+
+#whatsnew {
+	float: left;
+	width: 200px;
+	height: 100%;
+}
+
+#coollinks {
+	margin-left: 220px;
+}
+
+#resume h4, #links h4 {
+	margin-top: 0;
+	border-top: 1px solid #505050;
+	padding-top: 1.0em;
+	position: absolute;
+	left: 37px;
+	width: 214px;
+}
+
+#resume #photo {
+	position: absolute;
+	left: 37px;
+	top: 20px;
+	width: 214px;
+}
+
+#resume .first {
+	margin-top: 0;
+	border-top: 1px solid #505050;
+	padding-top: 1.5em;
+}
+
+dl {
+	margin-top: 0;
+	margin-bottom: 0;
+	border-top: 1px solid #505050;
+	padding-top: 1.5em;
+	padding-bottom: 1.5em;
+	position: relative;
+}
+
+dt {
+	position: absolute;
+	left: 0;
+}
+
+dd {
+	margin-left: 150px;
+	height: 2.0em;
+}
+
+.emptydata td {
+	padding: 50px;
+	color: #aeaeae;
+}
+
+
+
+
+
+
+
+
+
+
+.view {
+	margin-left: auto;
+	margin-right: auto;
+	width: 686px;
+	text-align: center;
+}
+
+.view .photo-frame {
+	margin-left: auto;
+	margin-right: auto;
+}
+
+.item {
+	padding: 20px 50px;
+	color: #B2B2B2;
+}
+
+.item h4 {
+	margin-bottom: 0.4em;
+}
+
+.nullpanel {
+	padding: 150px;
+	width: auto;
+	text-align: center;
+}
+
+
+
+
+
+
+
+
+
+.buttonbar, .buttonbar-top {
+	width: 686px;
+	height: 36px;
+	background-image: url(Images/photonav.gif);
+	background-repeat: no-repeat;
+	margin-bottom: 5px;
+	text-align: center;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+/* 3 FOOTER */
+
+.footerbg {
+	width: auto;
+	height: 50px;
+	text-align: center;
+}
+
+.footer {
+	background-image: url(images/footer.gif);
+	background-repeat: no-repeat;
+	margin-left: auto;
+	margin-right: auto;
+	padding-bottom: 20px;
+	width: 770px;
+	height: 50px;
+	text-align: center;
+	font-size: 10px;
+	color: #ffffff;
+}
+
+.menub {
+	margin: 8px auto 2px auto;
+	text-transform: uppercase;
+	font-size: 10px;
+}
+
+.menub a:visited {
+	color: #DBB94F;
+}
+
+
+
+/* Inline styles are used because image controls hard code a border property */
+
+.photo_198 {
+	border: 4px solid #FFFFFF;
+}
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Default.skin b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Default.skin
new file mode 100755
index 0000000..3b9c4af
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Default.skin
@@ -0,0 +1,41 @@
+<asp:imagebutton runat="server" Imageurl="Images/button-login.gif" skinid="login" />
+
+<asp:image runat="server" Imageurl="Images/button-create.gif" skinid="create" />
+<asp:image runat="server" ImageUrl="Images/button-download.gif" skinid="download"/>
+<asp:image runat="Server" ImageUrl="images/button-dwn_res.gif" skinid="dwn_res" />
+
+<asp:image runat="Server" ImageUrl="images/button-gallery.jpg" skinid="gallery" />
+<asp:imagebutton runat="server" imageurl="Images/button-tog8.jpg" skinid="tog8"/>
+<asp:imagebutton runat="server" imageurl="Images/button-tog24.jpg" skinid="tog24"/>
+
+<asp:ImageButton runat="server" ImageUrl="Images/button-first.jpg" skinid="first"/>
+<asp:ImageButton runat="server" ImageUrl="images/button-prev.jpg" skinid="prev"/>
+<asp:ImageButton runat="server" ImageUrl="images/button-next.jpg" skinid="next"/>
+<asp:ImageButton runat="server" ImageUrl="Images/button-last.jpg" skinid="last"/>
+
+<asp:image runat="Server" ImageUrl="images/album-l1.gif" skinid="b01" />
+<asp:image runat="Server" ImageUrl="images/album-mtl.gif" skinid="b02" />
+<asp:image runat="Server" ImageUrl="images/album-mtr.gif" skinid="b03" />
+<asp:image runat="Server" ImageUrl="images/album-r1.gif" skinid="b04" />
+<asp:image runat="Server" ImageUrl="images/album-l2.gif" skinid="b05" />
+<asp:image runat="Server" ImageUrl="images/album-r2.gif" skinid="b06" />
+<asp:image runat="Server" ImageUrl="images/album-l3.gif" skinid="b07" />
+<asp:image runat="Server" ImageUrl="images/album-r3.gif" skinid="b08" />
+<asp:image runat="Server" ImageUrl="images/album-l4.gif" skinid="b09" />
+<asp:image runat="Server" ImageUrl="images/album-mbl.gif" skinid="b10" />
+<asp:image runat="Server" ImageUrl="images/album-mbr.gif" skinid="b11" />
+<asp:image runat="Server" ImageUrl="images/album-r4.gif" skinid="b12" />
+
+
+<asp:ImageButton Runat="server" ImageUrl="images/button-add.gif" skinid="add"/>
+
+<asp:gridview runat="server" backcolor="#606060">
+    <AlternatingRowStyle backcolor="#656565" />
+</asp:gridview>
+<asp:image runat="Server" ImageUrl="Images/button-edit.gif" skinid="edit" />
+<asp:ImageButton Runat="server" ImageUrl="Images/button-rename.gif" SkinID="rename" />
+<asp:ImageButton Runat="server" ImageUrl="Images/button-delete.gif" SkinID="delete" />
+<asp:ImageButton Runat="server" ImageUrl="Images/button-save.gif" SkinID="save" />
+<asp:ImageButton Runat="server" ImageUrl="Images/button-cancel.gif" SkinID="cancel" />
+
+<asp:ImageButton Runat="server" ImageUrl="Images/button-import.gif" SkinID="import" />
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-bstretch.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-bstretch.gif
new file mode 100755
index 0000000..a9ba1ad
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-bstretch.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l1.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l1.gif
new file mode 100755
index 0000000..2d230d9
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l1.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l2.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l2.gif
new file mode 100755
index 0000000..296b875
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l2.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l3.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l3.gif
new file mode 100755
index 0000000..3e023a2
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l3.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l4.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l4.gif
new file mode 100755
index 0000000..8c51c31
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-l4.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-lstretch.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-lstretch.gif
new file mode 100755
index 0000000..28ef65f
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-lstretch.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mbl.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mbl.gif
new file mode 100755
index 0000000..80066f1
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mbl.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mbr.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mbr.gif
new file mode 100755
index 0000000..f0cc4b7
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mbr.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mtl.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mtl.gif
new file mode 100755
index 0000000..19365ae
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mtl.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mtr.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mtr.gif
new file mode 100755
index 0000000..4df6d40
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-mtr.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r1.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r1.gif
new file mode 100755
index 0000000..85f722e
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r1.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r2.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r2.gif
new file mode 100755
index 0000000..6c60be8
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r2.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r3.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r3.gif
new file mode 100755
index 0000000..94d3e93
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r3.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r4.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r4.gif
new file mode 100755
index 0000000..06fa4c8
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-r4.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-rstretch.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-rstretch.gif
new file mode 100755
index 0000000..620b6ef
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-rstretch.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-tstretch.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-tstretch.gif
new file mode 100755
index 0000000..0391718
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/album-tstretch.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/background.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/background.gif
new file mode 100755
index 0000000..49b9516
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/background.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/bullet-1.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/bullet-1.gif
new file mode 100755
index 0000000..5ba2d8d
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/bullet-1.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/bullet-2.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/bullet-2.gif
new file mode 100755
index 0000000..684f410
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/bullet-2.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-add.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-add.gif
new file mode 100755
index 0000000..9809ded
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-add.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-cancel.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-cancel.gif
new file mode 100755
index 0000000..09e2617
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-cancel.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-create.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-create.gif
new file mode 100755
index 0000000..4bd68c9
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-create.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-delete.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-delete.gif
new file mode 100755
index 0000000..0fdc307
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-delete.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-download.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-download.gif
new file mode 100755
index 0000000..e72ad02
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-download.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-dwn_res.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-dwn_res.gif
new file mode 100755
index 0000000..e5122dd
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-dwn_res.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-edit.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-edit.gif
new file mode 100755
index 0000000..885ce51
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-edit.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-first.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-first.jpg
new file mode 100755
index 0000000..44c1499
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-first.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-gallery.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-gallery.jpg
new file mode 100755
index 0000000..86e831b
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-gallery.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-import.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-import.gif
new file mode 100755
index 0000000..29c6f67
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-import.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-insert.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-insert.gif
new file mode 100755
index 0000000..f9bcbab
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-insert.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-last.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-last.jpg
new file mode 100755
index 0000000..07cd500
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-last.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-login.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-login.gif
new file mode 100755
index 0000000..f4e444a
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-login.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-next.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-next.jpg
new file mode 100755
index 0000000..a9294f2
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-next.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-play.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-play.jpg
new file mode 100755
index 0000000..f46f067
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-play.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-prev.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-prev.jpg
new file mode 100755
index 0000000..45c977b
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-prev.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-rename.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-rename.gif
new file mode 100755
index 0000000..6e597ce
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-rename.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-save.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-save.gif
new file mode 100755
index 0000000..043b7fe
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-save.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-tog24.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-tog24.jpg
new file mode 100755
index 0000000..c6f1ba6
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-tog24.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-tog8.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-tog8.jpg
new file mode 100755
index 0000000..4c70e2d
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/button-tog8.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/footer.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/footer.gif
new file mode 100755
index 0000000..7b89a85
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/footer.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-bot--x.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-bot--x.gif
new file mode 100755
index 0000000..658b2cb
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-bot--x.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-bot-x-.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-bot-x-.gif
new file mode 100755
index 0000000..781c2cd
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-bot-x-.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-botx--.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-botx--.gif
new file mode 100755
index 0000000..743bd0b
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-botx--.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-mid--x.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-mid--x.gif
new file mode 100755
index 0000000..c6357c8
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-mid--x.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-midx--.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-midx--.gif
new file mode 100755
index 0000000..db14c04
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-midx--.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-top--x.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-top--x.gif
new file mode 100755
index 0000000..6afcaca
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-top--x.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-top-x-.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-top-x-.gif
new file mode 100755
index 0000000..76b8551
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-top-x-.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-topx--.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-topx--.gif
new file mode 100755
index 0000000..2564c8f
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/frame-topx--.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/header.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/header.gif
new file mode 100755
index 0000000..3503faa
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/header.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/photonav.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/photonav.gif
new file mode 100755
index 0000000..62dcf42
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/photonav.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/spacer.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/spacer.gif
new file mode 100755
index 0000000..5bfd67a
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/Images/spacer.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/frame.css b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/frame.css
new file mode 100755
index 0000000..e160cc0
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/Black/frame.css
@@ -0,0 +1,197 @@
+/* Photo Border for All Pages Except the Albums Page */
+
+.photo-frame .topx-- {
+	background-image: url(Images/frame-topx--.gif);
+	background-repeat: no-repeat;
+	width: auto;
+	height: 4px;
+	vertical-align: top;
+}
+.photo-frame .top-x- {
+	background-image: url(Images/frame-top-x-.gif);
+	background-repeat: repeat-x;
+	width: auto;
+	height: 4px;
+}
+.photo-frame .top--x {
+	background-image: url(Images/frame-top--x.gif);
+	background-repeat: no-repeat;
+	width: auto;
+	height: 4px;
+	vertical-align: top;
+}
+
+.photo-frame .midx-- {
+	background-image: url(Images/frame-midx--.gif);
+	background-repeat: repeat-y;
+	width: 4px;
+	height: 100%;
+}
+.photo-frame .mid--x {
+	background-image: url(Images/frame-mid--x.gif);
+	background-repeat: repeat-y;
+	width: 4px;
+	height: 100%;
+}
+
+.photo-frame .botx-- {
+	background-image: url(Images/frame-botx--.gif);
+	background-repeat: no-repeat;
+	width: 4px;
+	height: 4px;
+	vertical-align: top;
+}
+.photo-frame .bot-x- {
+	background-image: url(Images/frame-bot-x-.gif);
+	background-repeat: repeat-x;
+	width: auto;
+	height: 4px;
+}
+.photo-frame .bot--x {
+	background-image: url(Images/frame-bot--x.gif);
+	background-repeat: no-repeat;
+	width: 4px;
+	height: 4px;
+	vertical-align: bottom;
+}
+
+/* Photo Border for the Album Page */
+
+.album-frame .topx----,
+.album-frame .top----x,
+.album-frame .botx----,
+.album-frame .bot----x {
+	height: 14px;
+	width: 14px;
+}
+
+.album-frame .top-x--- {
+	background-image: url(images/album-tstretch.gif);
+	background-repeat: repeat-x;
+	text-align: left;
+	height: 14px;
+	width: auto;
+}
+.album-frame .top--x-- {
+	background-image: url(images/album-tstretch.gif);
+	background-repeat: repeat-x;
+	height: 14px;
+	width: auto;
+}
+.album-frame .top---x- {
+	background-image: url(images/album-tstretch.gif);
+	background-repeat: repeat-x;
+	text-align: right;
+	height: 14px;
+	width: auto;
+}
+
+.album-frame .mtpx---- {
+	background-image: url(images/album-lstretch.gif);
+	background-repeat: repeat-y;
+	vertical-align: top;
+	height: auto;
+	width: 14px;
+}
+.album-frame .mtp----x {
+	background-image: url(images/album-rstretch.gif);
+	background-repeat: repeat-y;
+	vertical-align: top;
+	height: auto;
+	width: 14px;
+}
+
+.album-frame .midx---- {
+	background-image: url(images/album-lstretch.gif);
+	background-repeat: repeat-y;
+	height: auto;
+	width: 14px;
+}
+.album-frame .mid----x {
+	background-image: url(images/album-rstretch.gif);
+	background-repeat: repeat-y;
+	height: auto;
+	width: 14px;
+}
+
+.album-frame .mbtx---- {
+	background-image: url(images/album-lstretch.gif);
+	background-repeat: repeat-y;
+	vertical-align: bottom;
+	height: auto;
+	width: 14px;
+}
+.album-frame .mbt----x {
+	background-image: url(images/album-rstretch.gif);
+	background-repeat: repeat-y;
+	vertical-align: bottom;
+	height: auto;
+	width: 14px;
+}
+
+.album-frame .bot-x--- {
+	background-image: url(images/album-bstretch.gif);
+	background-repeat: repeat-x;
+	text-align: right;
+	height: 14px;
+	width: auto;
+}
+.album-frame .bot--x-- {
+	background-image: url(images/album-bstretch.gif);
+	background-repeat: repeat-x;
+	height: 14px;
+	width: auto;
+}
+.album-frame .bot---x- {
+	background-image: url(images/album-bstretch.gif);
+	background-repeat: repeat-x;
+	text-align: left;
+	height: 14px;
+	width: auto;
+}
+
+/* Form Items */
+
+.textfield {
+	border: 1px solid #000000;
+	vertical-align: middle;
+	padding: 3px;
+	margin: 2px 0 5px 0;
+}
+
+/* Login View */
+
+.login .label {
+    display:block;
+}
+
+.login .textbox {
+	border: 1px solid #000000;
+	width: 140px;
+	vertical-align: middle;
+	padding: 3px;
+	margin: 2px 0 5px 0;
+}
+
+.login .button {
+    display:block;
+    margin-top:8px;
+    margin-bottom:8px;
+}
+
+
+/* LIST */
+
+ul {
+	list-style-type: none;
+	list-style-image:  url(images/bullet-2.gif);
+	list-style-position: outside;
+	line-height: 2.1em;
+	vertical-align: middle;
+	margin-left: 1.25em;
+}
+
+.list_link{
+	list-style-image:  url(images/bullet-1.gif);
+}
+
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Default.css b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Default.css
new file mode 100755
index 0000000..7c6880c
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Default.css
@@ -0,0 +1,325 @@
+/* 0 BASIC TAGS */
+
+table {
+	font-size: 1em;
+}
+
+h1, h2, h3, h4 {
+	margin: 0;
+	font-family: tahoma, arial, helvetica, sans-serif;
+}
+
+p {
+	line-height: 1.4em;
+}
+
+hr {
+	border: 0;
+	border-top: 1px solid #bababa;
+	height: 1px;
+}
+
+a {
+	text-decoration: none;
+	color: #d32525;
+}
+
+a:visited {
+	color: #980000;
+}
+
+a:hover {
+	text-decoration: underline;
+	color: #e05252;
+}
+
+a:active {
+	color: #980000;
+}
+
+body {
+	background-color: #ffffff;
+	background-image: url(images/background.gif);
+	background-repeat: repeat-x;
+	margin: 0;
+	padding: 0;
+	text-align: center;
+	font-family: verdana, arial, helvetica, sans-serif;
+	font-size: 0.7em;
+	color: #666666;
+}
+
+img {
+	border-width: 0;
+}
+
+/* 1 HEADER */
+
+.header {
+	background-image: url(Images/header.gif);
+	background-repeat: no-repeat;
+	position: relative;
+	width: 760px;
+	height: 81px;
+	margin-left: auto;
+	margin-right: auto;
+}
+
+h1 {
+	position: absolute;
+	left: 37px;
+	top: 12px;
+	text-transform: uppercase;
+	font-size: 18px;
+}
+
+h2 {
+	position: absolute;
+	left: 37px;
+	top: 60px;
+	font-size: 11px;
+}
+
+.menua {
+	position: absolute;
+	right: 37px;
+	top: 17px;
+	text-transform: uppercase;
+	font-size: 10px;
+}
+
+.nav {
+	position: absolute;
+	right: 37px;
+	top: 60px;
+	text-transform: uppercase;
+	font-size: 10px;
+}
+
+.menua a:visited, .nav a:visited {
+	color: #d32525;
+}
+
+/* 1.1 SHIM */
+
+.shim {
+	background-repeat: no-repeat;
+	margin-left: auto;
+	margin-right: auto;
+	width: 760px;
+	height: 8px;
+	font-size: 0;
+}
+
+.column {
+	background-image: url(images/content-shim.gif);
+}
+
+.gradient {
+	background-image: url(images/content-shim-photo.gif);
+}
+
+.solid {
+	background-image: url(images/content-shim-none.gif);
+}
+
+/* 2 PAGE */
+
+.page {
+	background-repeat: repeat-y;
+	margin-left: auto;
+	margin-right: auto;
+	text-align: left;
+}
+
+h3 {
+	margin-top: 1.0em;
+	margin-bottom: 1.12em;
+	font-size: 1.5em;
+	font-weight: bold;
+}
+h4 {
+	margin-top: 1.0em;
+	margin-bottom: 1.12em;
+	font-size: 1.3em;
+	font-weight: bold;
+}
+
+/* 2.1 HOME, RESUME, LINKS, REGISTER, ADMIN/ALBUMS, ADMIN/PHOTOS PAGES */
+
+#home, #resume, #links, #register, #admin-albums, #admin-photos {
+	background-image: url(images/body-repeat.gif);
+	position: relative;
+	width: 686px;
+	padding: 0px 37px;
+	padding-top: 1px; /* Weird Mozilla Bug */
+	padding-bottom: 40px; /* Weird Mozilla Bug */
+}
+
+#sidebar {
+	float: left;
+	width: 214px;
+	height: 100%;
+}
+
+#content {
+	margin-left: 256px;
+}
+
+#whatsnew {
+	float: left;
+	width: 200px;
+	height: 100%;
+}
+
+#coollinks {
+	margin-left: 220px;
+}
+
+#resume h4, #links h4 {
+	margin-top: 0;
+	border-top: 1px solid #bababa;
+	padding-top: 1.0em;
+	position: absolute;
+	left: 37px;
+	width: 214px;
+}
+
+#resume #photo {
+	position: absolute;
+	left: 37px;
+	top: 20px;
+	width: 214px;
+}
+
+#resume .first {
+	margin-top: 0;
+	border-top: 1px solid #bababa;
+	padding-top: 1.5em;
+}
+
+dl {
+	margin-top: 0;
+	margin-bottom: 0;
+	border-top: 1px solid #bababa;
+	padding-top: 1.5em;
+	padding-bottom: 1.5em;
+	position: relative;
+}
+
+dt {
+	position: absolute;
+	left: 0;
+}
+
+dd {
+	margin-left: 150px;
+	height: 2.0em;
+}
+
+.emptydata td {
+	padding: 50px;
+	color: #aeaeae;
+}
+
+/* 2.2 ALBUMS PAGE */
+
+#albums {
+	background-image: url(images/body-repeat-photo.gif);
+	padding: 0px 37px;
+	padding-bottom: 40px;
+	width: 686px;
+}
+
+.view {
+	margin-left: auto;
+	margin-right: auto;
+	width: 686px;
+	text-align: center;
+}
+
+.view .photo-frame {
+	margin-left: auto;
+	margin-right: auto;
+}
+
+.item {
+	padding: 20px 50px;
+	color: #B2B2B2;
+}
+
+.item h4 {
+	margin-bottom: 0.4em;
+}
+
+.nullpanel {
+	padding: 150px;
+	width: auto;
+	text-align: center;
+}
+
+/* 2.3 PHOTOS, DETAILS, ADMIN/DETAILS PAGE */
+
+#photos, #details, #admin-details {
+	background-image: url(images/body-repeat-photo.gif);
+	padding: 0;
+	width: 760px;
+}
+
+.buttonbar {
+	background-image: url(images/photonav-bg.gif);
+	background-repeat: repeat-x;
+	margin-left: auto;
+	margin-right: auto;
+	padding-top: 4px;
+	width: 744px;
+	height: 33px;
+	text-align: center;
+}
+
+.buttonbar-top {
+	background-image: url(images/photonav-top-bg.gif);
+}
+
+#photos .view, #admin-details .view {
+	margin-top: 20px;
+	margin-bottom: 20px;
+}
+
+/* 3 FOOTER */
+
+.footerbg {
+	background-image: url(images/footer-side.gif);
+	background-repeat: repeat-x;
+	width: auto;
+	height: 75px;
+	text-align: center;
+}
+.footer {
+	background-image: url(images/footer.gif);
+	background-repeat: no-repeat;
+	margin-left: auto;
+	margin-right: auto;
+	width: 760px;
+	height: 75px;
+	text-align: center;
+	font-size: 10px;
+}
+
+.menub {
+	margin: 12px auto 5px auto;
+	text-transform: uppercase;
+	font-size: 10px;
+}
+
+.menub a:visited {
+	color: #d32525;
+}
+
+
+
+/* Inline styles are used because image controls hard code a border property */
+
+.photo_198 {
+	border: 4px solid #FFFFFF;
+}
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Default.skin b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Default.skin
new file mode 100755
index 0000000..453056e
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Default.skin
@@ -0,0 +1,40 @@
+<asp:imagebutton runat="server" Imageurl="Images/button-login.gif" skinid="login" />
+
+<asp:image runat="server" Imageurl="Images/button-create.gif" skinid="create" />
+<asp:image runat="server" ImageUrl="Images/button-download.gif" skinid="download"/>
+<asp:image runat="Server" ImageUrl="images/button-dwn_res.gif" skinid="dwn_res" />
+
+<asp:image runat="Server" ImageUrl="images/button-gallery.gif" skinid="gallery" />
+<asp:imagebutton runat="server" imageurl="Images/button-tog8.gif" skinid="tog8"/>
+<asp:imagebutton runat="server" imageurl="Images/button-tog24.gif" skinid="tog24"/>
+
+<asp:ImageButton runat="server" ImageUrl="Images/button-first.gif" skinid="first"/>
+<asp:ImageButton runat="server" ImageUrl="images/button-prev.gif" skinid="prev"/>
+<asp:ImageButton runat="server" ImageUrl="images/button-next.gif" skinid="next"/>
+<asp:ImageButton runat="server" ImageUrl="Images/button-last.gif" skinid="last"/>
+
+<asp:image runat="Server" ImageUrl="images/album-l1.gif" skinid="b01" />
+<asp:image runat="Server" ImageUrl="images/album-mtl.gif" skinid="b02" />
+<asp:image runat="Server" ImageUrl="images/album-mtr.gif" skinid="b03" />
+<asp:image runat="Server" ImageUrl="images/album-r1.gif" skinid="b04" />
+<asp:image runat="Server" ImageUrl="images/album-l2.gif" skinid="b05" />
+<asp:image runat="Server" ImageUrl="images/album-r2.gif" skinid="b06" />
+<asp:image runat="Server" ImageUrl="images/album-l3.gif" skinid="b07" />
+<asp:image runat="Server" ImageUrl="images/album-r3.gif" skinid="b08" />
+<asp:image runat="Server" ImageUrl="images/album-l4.gif" skinid="b09" />
+<asp:image runat="Server" ImageUrl="images/album-mbl.gif" skinid="b10" />
+<asp:image runat="Server" ImageUrl="images/album-mbr.gif" skinid="b11" />
+<asp:image runat="Server" ImageUrl="images/album-r4.gif" skinid="b12" />
+
+<asp:ImageButton Runat="server" ImageUrl="images/button-add.gif" skinid="add"/>
+
+<asp:gridview runat="server" backcolor="#ececec">
+    <AlternatingRowStyle backcolor="white" />
+</asp:gridview>
+<asp:image runat="Server" ImageUrl="Images/button-edit.gif" skinid="edit" />
+<asp:ImageButton Runat="server" ImageUrl="Images/button-rename.gif" SkinID="rename" />
+<asp:ImageButton Runat="server" ImageUrl="Images/button-delete.gif" SkinID="delete" />
+<asp:ImageButton Runat="server" ImageUrl="Images/button-save.gif" SkinID="save" />
+<asp:ImageButton Runat="server" ImageUrl="Images/button-cancel.gif" SkinID="cancel" />
+
+<asp:ImageButton Runat="server" ImageUrl="Images/button-import.gif" SkinID="import" />
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Frame.css b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Frame.css
new file mode 100755
index 0000000..3ae71a6
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Frame.css
@@ -0,0 +1,194 @@
+/* Photo Border for All Pages Except the Albums Page */
+
+.photo-frame .topx-- {
+	background-image: url(Images/frame-topx--.gif);
+	background-repeat: no-repeat;
+	width: auto;
+	height: 4px;
+	vertical-align: top;
+}
+.photo-frame .top-x- {
+	background-image: url(Images/frame-top-x-.gif);
+	background-repeat: repeat-x;
+	width: auto;
+	height: 4px;
+}
+.photo-frame .top--x {
+	background-image: url(Images/frame-top--x.gif);
+	background-repeat: no-repeat;
+	width: auto;
+	height: 4px;
+	vertical-align: top;
+}
+
+.photo-frame .midx-- {
+	background-image: url(Images/frame-midx--.gif);
+	background-repeat: repeat-y;
+	width: 4px;
+	height: auto;
+}
+.photo-frame .mid--x {
+	background-image: url(Images/frame-mid--x.gif);
+	background-repeat: repeat-y;
+	width: 4px;
+	height: auto;
+}
+
+.photo-frame .botx-- {
+	background-image: url(Images/frame-botx--.gif);
+	background-repeat: no-repeat;
+	width: 4px;
+	height: 4px;
+	vertical-align: top;
+}
+.photo-frame .bot-x- {
+	background-image: url(Images/frame-bot-x-.gif);
+	background-repeat: repeat-x;
+	width: auto;
+	height: 4px;
+}
+.photo-frame .bot--x {
+	background-image: url(Images/frame-bot--x.gif);
+	background-repeat: no-repeat;
+	width: 4px;
+	height: 4px;
+	vertical-align: bottom;
+}
+
+/* Photo Border for the Album Page */
+
+.album-frame .topx----,
+.album-frame .top----x,
+.album-frame .botx----,
+.album-frame .bot----x {
+	height: 14px;
+	width: 14px;
+}
+
+.album-frame .top-x--- {
+	background-image: url(images/album-tstretch.gif);
+	background-repeat: repeat-x;
+	text-align: left;
+	height: 14px;
+	width: auto;
+}
+.album-frame .top--x-- {
+	background-image: url(images/album-tstretch.gif);
+	background-repeat: repeat-x;
+	height: 14px;
+	width: auto;
+}
+.album-frame .top---x- {
+	background-image: url(images/album-tstretch.gif);
+	background-repeat: repeat-x;
+	text-align: right;
+	height: 14px;
+	width: auto;
+}
+
+.album-frame .mtpx---- {
+	background-image: url(images/album-lstretch.gif);
+	background-repeat: repeat-y;
+	vertical-align: top;
+	height: auto;
+	width: 14px;
+}
+.album-frame .mtp----x {
+	background-image: url(images/album-rstretch.gif);
+	background-repeat: repeat-y;
+	vertical-align: top;
+	height: auto;
+	width: 14px;
+}
+
+.album-frame .midx---- {
+	background-image: url(images/album-lstretch.gif);
+	background-repeat: repeat-y;
+	height: auto;
+	width: 14px;
+}
+.album-frame .mid----x {
+	background-image: url(images/album-rstretch.gif);
+	background-repeat: repeat-y;
+	height: auto;
+	width: 14px;
+}
+
+.album-frame .mbtx---- {
+	background-image: url(images/album-lstretch.gif);
+	background-repeat: repeat-y;
+	vertical-align: bottom;
+	height: auto;
+	width: 14px;
+}
+.album-frame .mbt----x {
+	background-image: url(images/album-rstretch.gif);
+	background-repeat: repeat-y;
+	vertical-align: bottom;
+	height: auto;
+	width: 14px;
+}
+
+.album-frame .bot-x--- {
+	background-image: url(images/album-bstretch.gif);
+	background-repeat: repeat-x;
+	text-align: right;
+	height: 14px;
+	width: auto;
+}
+.album-frame .bot--x-- {
+	background-image: url(images/album-bstretch.gif);
+	background-repeat: repeat-x;
+	height: 14px;
+	width: auto;
+}
+.album-frame .bot---x- {
+	background-image: url(images/album-bstretch.gif);
+	background-repeat: repeat-x;
+	text-align: left;
+	height: 14px;
+	width: auto;
+}
+
+/* Form Items */
+
+.textfield {
+	border: 1px solid #929292;
+	vertical-align: middle;
+	padding: 3px;
+	margin: 2px 0 5px 0;
+}
+
+/* Login View */
+
+.login .label {
+	display:block;
+}
+
+.login .textbox {
+	border: 1px solid #929292;
+	width: 140px;
+	vertical-align: middle;
+	padding: 3px;
+	margin: 2px 0 5px 0;
+}
+
+.login .button {
+	display:block;
+	margin-top:8px;
+	margin-bottom:8px;
+}
+
+/* LIST */
+
+ul {
+	list-style-type: none;
+	list-style-image: url(images/bullet-2.gif);
+	list-style-position: outside;
+	line-height: 2.1em;
+	vertical-align: middle;
+	margin-left: 1.25em;
+}
+.link {
+	list-style-image: url(images/bullet-1.gif);
+}
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-bstretch.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-bstretch.gif
new file mode 100755
index 0000000..3388588
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-bstretch.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l1.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l1.gif
new file mode 100755
index 0000000..e1dcff9
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l1.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l2.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l2.gif
new file mode 100755
index 0000000..c3091c0
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l2.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l3.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l3.gif
new file mode 100755
index 0000000..7348294
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l3.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l4.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l4.gif
new file mode 100755
index 0000000..1da7d1e
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-l4.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-lstretch.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-lstretch.gif
new file mode 100755
index 0000000..88e931b
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-lstretch.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mbl.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mbl.gif
new file mode 100755
index 0000000..c853b00
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mbl.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mbr.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mbr.gif
new file mode 100755
index 0000000..ca710fa
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mbr.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mtl.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mtl.gif
new file mode 100755
index 0000000..c2e0838
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mtl.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mtr.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mtr.gif
new file mode 100755
index 0000000..34c90d6
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-mtr.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r1.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r1.gif
new file mode 100755
index 0000000..5f5d614
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r1.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r2.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r2.gif
new file mode 100755
index 0000000..8c550ef
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r2.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r3.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r3.gif
new file mode 100755
index 0000000..5396f7e
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r3.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r4.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r4.gif
new file mode 100755
index 0000000..088d5d3
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-r4.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-rstretch.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-rstretch.gif
new file mode 100755
index 0000000..03c75d0
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-rstretch.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-tstretch.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-tstretch.gif
new file mode 100755
index 0000000..b9d31bd
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/album-tstretch.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/background.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/background.gif
new file mode 100755
index 0000000..b46632f
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/background.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/body-repeat-photo.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/body-repeat-photo.gif
new file mode 100755
index 0000000..fc46be8
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/body-repeat-photo.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/body-repeat.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/body-repeat.gif
new file mode 100755
index 0000000..fb1b277
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/body-repeat.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/bullet-1.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/bullet-1.gif
new file mode 100755
index 0000000..1bf5fdb
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/bullet-1.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/bullet-2.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/bullet-2.gif
new file mode 100755
index 0000000..44111e7
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/bullet-2.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-add.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-add.gif
new file mode 100755
index 0000000..45357b7
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-add.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-cancel.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-cancel.gif
new file mode 100755
index 0000000..b7f9c4c
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-cancel.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-create.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-create.gif
new file mode 100755
index 0000000..c465990
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-create.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-delete.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-delete.gif
new file mode 100755
index 0000000..24e2550
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-delete.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-download.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-download.gif
new file mode 100755
index 0000000..77c2fd0
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-download.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-dwn_res.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-dwn_res.gif
new file mode 100755
index 0000000..e2154cc
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-dwn_res.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-edit.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-edit.gif
new file mode 100755
index 0000000..e6de10b
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-edit.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-first.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-first.gif
new file mode 100755
index 0000000..133119a
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-first.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-gallery.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-gallery.gif
new file mode 100755
index 0000000..f4f8ce4
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-gallery.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-import.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-import.gif
new file mode 100755
index 0000000..90b8620
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-import.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-insert.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-insert.gif
new file mode 100755
index 0000000..402d135
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-insert.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-last.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-last.gif
new file mode 100755
index 0000000..35d0e9a
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-last.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-login.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-login.gif
new file mode 100755
index 0000000..f1e8d3f
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-login.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-next.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-next.gif
new file mode 100755
index 0000000..88575e7
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-next.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-play.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-play.gif
new file mode 100755
index 0000000..d988da7
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-play.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-prev.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-prev.gif
new file mode 100755
index 0000000..4b0257f
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-prev.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-rename.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-rename.gif
new file mode 100755
index 0000000..3fc79c5
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-rename.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-save.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-save.gif
new file mode 100755
index 0000000..70cbba5
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-save.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-tog24.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-tog24.gif
new file mode 100755
index 0000000..6e05de1
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-tog24.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-tog8.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-tog8.gif
new file mode 100755
index 0000000..0b9e941
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/button-tog8.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim-none.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim-none.gif
new file mode 100755
index 0000000..3f9bca6
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim-none.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim-photo.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim-photo.gif
new file mode 100755
index 0000000..4608fe8
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim-photo.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim-stretch.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim-stretch.gif
new file mode 100755
index 0000000..4a27486
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim-stretch.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim.gif
new file mode 100755
index 0000000..f5d88f7
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/content-shim.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/footer-side.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/footer-side.gif
new file mode 100755
index 0000000..0d3dd8e
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/footer-side.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/footer.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/footer.gif
new file mode 100755
index 0000000..3b37c6c
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/footer.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-bot--x.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-bot--x.gif
new file mode 100755
index 0000000..0d54dc3
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-bot--x.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-bot-x-.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-bot-x-.gif
new file mode 100755
index 0000000..29dd27b
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-bot-x-.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-botx--.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-botx--.gif
new file mode 100755
index 0000000..ee4ad6e
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-botx--.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-mid--x.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-mid--x.gif
new file mode 100755
index 0000000..a2c5f23
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-mid--x.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-midx--.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-midx--.gif
new file mode 100755
index 0000000..a9c87a8
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-midx--.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-top--x.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-top--x.gif
new file mode 100755
index 0000000..ab1292b
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-top--x.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-top-x-.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-top-x-.gif
new file mode 100755
index 0000000..5948471
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-top-x-.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-topx--.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-topx--.gif
new file mode 100755
index 0000000..710b1d6
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/frame-topx--.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/header.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/header.gif
new file mode 100755
index 0000000..f09f418
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/header.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/photonav-bg.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/photonav-bg.gif
new file mode 100755
index 0000000..dd3e07f
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/photonav-bg.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/photonav-top-bg.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/photonav-top-bg.gif
new file mode 100755
index 0000000..b114040
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/photonav-top-bg.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/spacer.gif b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/spacer.gif
new file mode 100755
index 0000000..5bfd67a
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/App_Themes/White/Images/spacer.gif differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.aspx
new file mode 100755
index 0000000..8427fd0
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.aspx
@@ -0,0 +1,100 @@
+<%@	Page Language="F#" MasterPageFile="~/Default.master" Title="Your Name Here | Home"
+	CodeFile="Default.aspx.fs" Inherits="PersonalWebSite.Default_aspx" %>
+
+<asp:content contentplaceholderid="Main" runat="server">
+
+	<div class="shim column"></div>
+	
+	<div class="page" id="home">
+		<div id="sidebar">
+			<asp:loginview runat="server" id="LoginArea">
+				<AnonymousTemplate>
+					<asp:login runat="server" id="Login1">
+						<layouttemplate>
+							<div class="login">
+								<h4>Login to Site</h4>
+								<asp:label runat="server" id="UserNameLabel" CssClass="label" associatedcontrolid="UserName">User Name</asp:label>
+								<asp:textbox runat="server"	id="UserName" cssclass="textbox" accesskey="u" />
+								<asp:requiredfieldvalidator	runat="server" id="UserNameRequired" controltovalidate="UserName" validationgroup="Login1" errormessage="User Name is required." tooltip="User Name	is required." >*</asp:requiredfieldvalidator>
+								<asp:label runat="server" id="PasswordLabel" CssClass="label" associatedcontrolid="Password">Password</asp:label>
+								<asp:textbox runat="server"	id="Password" textmode="Password" cssclass="textbox" accesskey="p" />
+								<asp:requiredfieldvalidator	runat="server" id="PasswordRequired" controltovalidate="Password" validationgroup="Login1" tooltip="Password is	required." >*</asp:requiredfieldvalidator>
+								<div><asp:checkbox runat="server" id="RememberMe" text="Remember me	next time"/></div>
+								<asp:imagebutton runat="server"	id="LoginButton" CommandName="Login" AlternateText="login" skinid="login" CssClass="button"/>
+								or
+								<a href="register.aspx"	class="button"><asp:image id="Image1" runat="server"  AlternateText="create	a new account" skinid="create"/></a>
+								<p><asp:literal	runat="server" id="FailureText"	enableviewstate="False"></asp:literal></p>
+							</div>
+						</layouttemplate>
+					</asp:login>
+				</anonymoustemplate>
+				<LoggedInTemplate>
+					<h4><asp:loginname id="LoginName1" runat="server" formatstring="Welcome	{0}!" /></h4>
+				</LoggedInTemplate>
+			</asp:loginview>
+			<hr />
+			<asp:formview id="FormView1" runat="server" datasourceid="ObjectDataSource1" ondatabound="Randomize" cellpadding="0" borderwidth="0" enableviewstate="false">
+				<ItemTemplate>
+					<h4>Photo of the Day</h4>
+					<table border="0" cellpadding="0" cellspacing="0" class="photo-frame">
+						<tr>
+							<td class="topx--"></td>
+							<td class="top-x-"></td>
+							<td class="top--x"></td>
+						</tr>
+						<tr>
+							<td class="midx--"></td>
+							<td><a href='Details.aspx?AlbumID=<%# base.Eval("PhotoAlbumID") %>&Page=<%# (box Container.DataItemIndex) %>'>
+								<img src="Handler.ashx?PhotoID=<%# base.Eval("PhotoID") %>&Size=M" class="photo_198" style="border:4px solid white" alt='Photo Number <%# base.Eval("PhotoID") %>' /></a></td>
+							<td class="mid--x"></td>
+						</tr>
+						<tr>
+							<td class="botx--"></td>
+							<td class="bot-x-"></td>
+							<td class="bot--x"></td>
+						</tr>
+					</table>
+					<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod </p>
+					<p><a href='Download.aspx?AlbumID=<%# base.Eval("PhotoAlbumID") %>&Page=<%# (box Container.DataItemIndex) %>'>
+						<asp:image runat="Server" id="DownloadButton" AlternateText="download photo" skinid="download"/></a></p>
+					<p>See <a href="Albums.aspx">more photos </a></p>
+					<hr />
+				</ItemTemplate>
+			</asp:formview>
+			<h4>My Latest Piece of Work</h4>
+			<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut	laoreet	dolore magna aliquam erat volutpat.</p>
+		</div>
+		<div id="content">
+			<h3>Welcome	to My Site</h3>
+			<p>This	is my personal site. In	it you will find lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam	nonummy	nibh euismod tincidunt ut laoreet dolore magna aliquam erat	volutpat. Ut wisi enim ad minim	veniam.	</p>
+			<hr	/>
+			<div id="whatsnew">
+				<h4>What's New</h4>
+				<p>Lorem <a href="#">ipsum</a> dolor sit amet, consectetuer	adipiscing elit, sed diam nonummy nibh euismod.</p>
+				<p>Lorem <a href="#">ipsum</a> dolor sit amet, consectetuer	adipiscing elit, sed diam nonummy nibh euismod.</p>
+			</div>
+			<div id="coollinks">
+				<h4>Cool Links</h4>
+				<ul	class="link">
+					<li><a href="#">Lorem ipsum dolositionr</a></li>
+					<li><a href="#">Lorem ipsum dolositionr</a></li>
+					<li><a href="#">Lorem ipsum dolositionr</a></li>
+					<li><a href="#">Lorem ipsum dolositionr</a></li>
+					<li><a href="#">Lorem ipsum dolositionr</a></li>
+				</ul>
+			</div>
+			<hr	/>
+			<h4>What's Up Lately </h4>
+			<p>Lorem ipsum dolor sit amet, <a href="#">consectetuer</a>	adipiscing elit, sed diam nonummy nibh euismod tincidunt ut	laoreet	dolore magna aliquam erat volutpat.	Ut wisi	enim ad	minim veniam, quis nostrud exercitation	consequat. Duis	autem veleum iriure	dolor in hendrerit in vulputate	velit esse molestie	consequat, vel willum.</p>
+			<p>Lorem ipsum dolor sit amet, consectetuer	adipiscing elit, sed diam nonummy nibh <a href="#">euismod tincidunt ut</a>	laoreet	dolore magna aliquam erat volutpat.	Ut wisi	enim ad	minim veniam, quis nostrud exercitation	consequat. Duis	autem veleum iriure	dolor in hendrerit in vulputate	velit esse molestie	consequat, vel willum.</p>
+			<p>Lorem<a href="#"> ipsum dolor sit amet</a>, consectetuer	adipiscing elit, sed diam nonummy nibh euismod tincidunt ut	laoreet	dolore magna aliquam erat volutpat.	Ut wisi	enim ad	minim veniam, quis nostrud exercitation	consequat. Duis	autem veleum iriure	dolor in hendrerit in vulputate	velit esse molestie	consequat, vel willum.</p>
+			<p>Lorem ipsum dolor sit amet, consectetuer	adipiscing elit, sed diam nonummy nibh euismod tincidunt ut	laoreet	dolore magna aliquam erat volutpat.	Ut wisi	enim ad	minim veniam, quis nostrud exercitation	consequat. <a href="#">Duis	autem veleum</a> iriure	dolor in hendrerit in vulputate	velit esse molestie	consequat, vel willum.</p>
+			<p>Lorem ipsum dolor sit amet, consectetuer	adipiscing elit, sed diam nonummy nibh euismod tincidunt ut	laoreet	dolore magna aliquam erat volutpat.	Ut wisi	enim ad	minim veniam, quis nostrud exercitation	consequat. <a href="#">Duis	autem veleum</a> iriure	dolor in hendrerit in vulputate	velit esse molestie	consequat, vel willum.</p>
+		</div>
+	</div>
+
+	<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server" TypeName="PersonalWebSite.PhotoManager" 
+		SelectMethod="GetRandomPhotos">
+	</asp:ObjectDataSource>
+
+</asp:content>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.aspx.fs
new file mode 100755
index 0000000..d2b3d2c
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.aspx.fs
@@ -0,0 +1,26 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Default_aspx = class
+    inherit System.Web.UI.Page 
+
+    val mutable ObjectDataSource1 : ObjectDataSource;
+    val mutable FormView1 : FormView;
+    val mutable LoginArea : LoginView
+    
+    new () = { ObjectDataSource1=null; FormView1=null; LoginArea=null; }
+      
+    member t.Randomize ((sender:obj),(e:EventArgs)) =
+        let r = new Random();
+        t.FormView1.PageIndex <- r.Next(t.FormView1.PageCount);
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.master b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.master
new file mode 100755
index 0000000..6a81426
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.master
@@ -0,0 +1,50 @@
+<%@	Master Language="F#" CodeFile="Default.master.fs" Inherits="PersonalWebSite.Default_master"	%>
+
+<!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" xml:lang="en" >
+<head runat="server">
+	<title></title>
+</head>
+<body>
+
+	<form runat="server">
+
+		<div class="header">
+			<h1>Your Name Here</h1>
+			<h2>My Personal Site</h2>
+			<asp:menu runat="server" 
+				datasourceid="SiteMapDataSource1" 
+				cssclass="menua" 
+				orientation="Horizontal" 
+				maximumdynamicdisplaylevels="0" 
+				skiplinktext="" 
+				staticdisplaylevels="2" />
+			<div class="nav">
+				<asp:SiteMapPath runat="Server" PathSeparator=" > " RenderCurrentNodeAsLink="true" />
+				  |  
+				<asp:LoginStatus Runat="server" />
+			</div>
+		</div>
+
+		<asp:contentplaceholder id="Main" runat="server" />
+
+		<div class="footerbg">
+			<div class="footer">
+				<asp:menu runat="server" 
+					datasourceid="SiteMapDataSource1" 
+					cssclass="menub"
+					orientation="Horizontal" 
+					maximumdynamicdisplaylevels="0" 
+					skiplinktext="" 
+					staticdisplaylevels="2" />
+				Copyright © 2005 Your Name here.
+			</div>
+		</div>
+
+		<asp:sitemapdatasource id="SiteMapDataSource1" runat="server" startingnodeoffset="0" />
+	
+	</form>
+	
+</body>
+</html>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.master.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.master.fs
new file mode 100755
index 0000000..b05fb92
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Default.master.fs
@@ -0,0 +1,19 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Default_master = class
+  inherit System.Web.UI.MasterPage
+  val mutable SiteMapDataSource1 : SiteMapDataSource
+  val mutable Main : ContentPlaceHolder
+  new () = { SiteMapDataSource1 = null; Main = null }
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Details.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Details.aspx
new file mode 100755
index 0000000..4a53a0a
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Details.aspx
@@ -0,0 +1,61 @@
+<%@	Page Language="F#" MasterPageFile="~/Default.master" Title="Your Name Here | Picture Details"
+	CodeFile="Details.aspx.fs" Inherits="PersonalWebSite.Details_aspx" %>
+
+<asp:content id="Content1" contentplaceholderid="Main" runat="server">
+
+	<div class="shim solid"></div>
+	
+	<div class="page" id="details">
+		<asp:formview id="FormView1" runat="server"	datasourceid="ObjectDataSource1" cssclass="view"
+			borderstyle="none" borderwidth="0" CellPadding="0" cellspacing="0" EnableViewState="false" AllowPaging="true">
+			<itemtemplate>
+			
+				<div class="buttonbar buttonbar-top">
+					<a href="Albums.aspx"><asp:image ID="Image1" runat="Server"	 skinid="gallery" /></a>
+					    
+					<asp:ImageButton ID="ImageButton9" Runat="server" CommandName="Page" CommandArgument="First" skinid="first"/>
+					<asp:ImageButton ID="ImageButton10"	Runat="server" CommandName="Page" CommandArgument="Prev" skinid="prev"/>
+					<asp:ImageButton ID="ImageButton11"	Runat="server" CommandName="Page" CommandArgument="Next" skinid="next"/>
+					<asp:ImageButton ID="ImageButton12"	Runat="server" CommandName="Page" CommandArgument="Last" skinid="last"/>
+				</div>
+				<p><%# box (this.Server.HtmlEncode(base.Eval("PhotoCaption").ToString())) %></p>
+				<table border="0" cellpadding="0" cellspacing="0" class="photo-frame">
+					<tr>
+						<td class="topx--"></td>
+						<td class="top-x-"></td>
+						<td class="top--x"></td>
+					</tr>
+					<tr>
+						<td class="midx--"></td>
+						<td><img src="Handler.ashx?PhotoID=<%# base.Eval("PhotoID") %>&Size=L" class="photo_198" style="border:4px solid white" alt='Photo Number <%# base.Eval("PhotoID") %>' /></a></td>
+						<td class="mid--x"></td>
+					</tr>
+					<tr>
+						<td class="botx--"></td>
+						<td class="bot-x-"></td>
+						<td class="bot--x"></td>
+					</tr>
+				</table>
+				<p><a href='Download.aspx?AlbumID=<%# base.Eval("PhotoAlbumID") %>&Page=<%# box Container.DataItemIndex %>'>
+					<asp:image runat="Server" id="DownloadButton" AlternateText="download this photo" skinid="download" /></a></p>
+				<div class="buttonbar">
+					<a href="Albums.aspx"><asp:image ID="Image2" runat="Server"	 skinid="gallery" /></a>
+					    
+					<asp:ImageButton ID="ImageButton1" Runat="server" CommandName="Page" CommandArgument="First" skinid="first"/>
+					<asp:ImageButton ID="ImageButton2" Runat="server" CommandName="Page" CommandArgument="Prev" skinid="prev"/>
+					<asp:ImageButton ID="ImageButton3" Runat="server" CommandName="Page" CommandArgument="Next" skinid="next"/>
+					<asp:ImageButton ID="ImageButton4" Runat="server" CommandName="Page" CommandArgument="Last" skinid="last"/>
+				</div>
+
+			</itemtemplate>
+		</asp:formview>
+	</div>
+	
+	<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server" TypeName="PersonalWebSite.PhotoManager" 
+		SelectMethod="GetPhotos">
+		<SelectParameters>
+			<asp:QueryStringParameter Name="AlbumID" Type="Int32" QueryStringField="albumID" DefaultValue="0"/>
+		</SelectParameters>
+	</asp:ObjectDataSource>
+	
+</asp:content>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Details.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Details.aspx.fs
new file mode 100755
index 0000000..dd3589b
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Details.aspx.fs
@@ -0,0 +1,26 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Details_aspx = class
+  inherit System.Web.UI.Page 
+  
+  val mutable FormView1 : FormView
+  val mutable ObjectDataSource1 : ObjectDataSource
+  new () = { FormView1 = null; ObjectDataSource1 = null; }
+  
+  member this.Page_Load (sender:obj, e:EventArgs) =
+    this.Page.MaintainScrollPositionOnPostBack <- true;
+    if (not this.IsPostBack) then
+      let i = Convert.ToInt32(this.Request.QueryString.get_Item("Page"));
+      if (i >= 0) then this.FormView1.PageIndex <- i;
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Doc.html b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Doc.html
new file mode 100755
index 0000000..968594d
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Doc.html
@@ -0,0 +1,41 @@
+<html>
+
+<head>
+<title>Personal WebSite StarterKit in F#</title>
+
+  <link type="text/css" rel="Stylesheet" href="../../../../../doc/rmcstyle-copy.css">
+  <link type="text/css" rel="Stylesheet" href="../../../../../doc/groupStyle-copy.css">
+
+  <style type="text/css">
+  TT { font-weight: bold; color: blue; font-size: 10pt; }
+  PRE { font-weight: bold; color: blue; font-size: 10pt;  }
+  </style>
+  
+</head>
+
+<body>
+
+<h1>Personal WebSite StarterKit in F#</h1>
+
+  <p> Links: <a href="../Doc.html">Up</a></p>
+
+  <p>This sample shows how to use F# for developing ASP.NET 2.0 data-driven web application.
+    The sample uses ASP.NET Membership and Roles for managing users of the website and custom database for
+    storing albums and photos.</p>
+
+  <p>NOTE: you will need to follow the instructions in <a href="Welcome.html">Welcome.html</a>, e.g. install SQL Server Management Studio Express and run the <tt>personal-add.sql</tt> SQL script in that tool.</p>
+  
+  <p>The data-access core of the application and declaration of the data structures can be found in <a href="App_Code/PhotoManager.fs">PhotoManager.fs</a>.
+    Note that we use F# record type to represent the data loaded from a database. For example:</p>
+
+  <pre>
+  type Album = { AlbumID:int; Count:int; Caption:string; IsPublic:bool }
+  type Photo = { PhotoID:int; PhotoAlbumID:int; PhotoCaption:string; }
+  </pre>    
+<p>The rest of the application logic is implemented in the pages, <code>*.aspx</code> file represents a ASP.NET markup with 
+  control declarations and <code>*.aspx.fs</code> implements a page logic in F#. The site also contains <code>Admin</code>
+  directory which contains pages for uploading photos and creating albums, which can be accessed only by the administrator.</p>
+<p>For more information about configuring the sample, see the sample <a href="Welcome.html">Welcome page</a>.</p>
+
+</body>
+</html>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Download.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Download.aspx
new file mode 100755
index 0000000..44bb347
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Download.aspx
@@ -0,0 +1,40 @@
+<%@ Page Language="F#" MasterPageFile="" Title="Your Name Here | Download" 
+    CodeFile="Download.aspx.fs" Inherits="PersonalWebSite.Download_aspx" %>
+
+<!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>Untitled Page</title>
+    <style type="text/css">
+    body {
+        margin:0;
+        padding:0;
+        }
+    p {
+        font:11px verdana;
+        padding:15px 0 0 6px;
+        }
+    </style>
+</head>
+<body>
+    <form runat="server">
+    <div>
+
+		<p>Right-click and select "Save Picture As.." to download the picture.</p>
+		<asp:formview id="FormView1" runat="server" datasourceid="ObjectDataSource1" borderstyle="none" borderwidth="0" CellPadding="0" cellspacing="0">
+			<itemtemplate>
+				<img src="Handler.ashx?PhotoID=<%# base.Eval("PhotoID") %>" alt='Photo Number <%# base.Eval("PhotoID") %>' /></itemtemplate>
+		</asp:formview>
+
+		<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server" TypeName="PersonalWebSite.PhotoManager" 
+			SelectMethod="GetPhotos">
+			<SelectParameters>
+				<asp:QueryStringParameter Name="AlbumID" Type="Int32" QueryStringField="AlbumID" DefaultValue="0"/>
+			</SelectParameters>
+		</asp:ObjectDataSource>
+
+    </div>
+    </form>
+</body>
+</html>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Download.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Download.aspx.fs
new file mode 100755
index 0000000..de30972
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Download.aspx.fs
@@ -0,0 +1,26 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Download_aspx = class
+  inherit System.Web.UI.Page
+
+  val mutable FormView1 : FormView
+  val mutable ObjectDataSource1 : ObjectDataSource
+  
+  new() = { FormView1 = null; ObjectDataSource1 = null; }
+  
+  member this.Page_Load (sender:obj, e:EventArgs) =
+    if (not this.IsPostBack) then 
+      let i = Convert.ToInt32(this.Request.QueryString.get_Item("Page"));
+      if (i >= 0) then this.FormView1.PageIndex <- i;
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Global.asax b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Global.asax
new file mode 100755
index 0000000..2ccc6f3
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Global.asax
@@ -0,0 +1,20 @@
+<%@ Application Language="F#" %>
+<script runat="server">
+
+    member this.Application_Start (sender:obj, e:EventArgs) =
+        SiteMap.add_SiteMapResolve(new SiteMapResolveEventHandler(this.AppendQueryString));
+        if (not (Roles.RoleExists("Administrators"))) then Roles.CreateRole("Administrators");
+        if (not (Roles.RoleExists("Friends"))) then Roles.CreateRole("Friends");
+    
+    member this.AppendQueryString (o:obj) (e:SiteMapResolveEventArgs) =
+        if (SiteMap.CurrentNode <> null) then
+            let temp = SiteMap.CurrentNode.Clone(true);
+            let u = new Uri(e.Context.Request.Url.ToString());
+            temp.Url <- temp.Url + u.Query;
+            if (temp.ParentNode <> null) then
+                temp.ParentNode.Url <- temp.ParentNode.Url + u.Query;
+            temp;
+        else 
+            null;
+    
+</script>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Handler.ashx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Handler.ashx
new file mode 100755
index 0000000..0692b48
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Handler.ashx
@@ -0,0 +1,50 @@
+<%@ WebHandler Language="F#" Class="PersonalWebSite.Handler" %>
+#light
+namespace PersonalWebSite
+
+open System;
+open System.IO;
+open System.Web;
+open PersonalWebSite
+
+type Handler = class 
+  new () = {}
+  interface IHttpHandler with
+    member this.IsReusable 
+      with get() = true;
+
+    member this.ProcessRequest (context:HttpContext) =
+      // Set up the response settings
+      context.Response.ContentType <- "image/jpeg";
+      context.Response.Cache.SetCacheability(HttpCacheability.Public);
+      context.Response.BufferOutput <- false;
+            
+      // Setup the Size Parameter
+      let size = 
+        match (context.Request.QueryString.get_Item("Size")) with
+          | "S" -> PhotoSize.Small
+          | "M" -> PhotoSize.Medium
+          | "L" -> PhotoSize.Large
+          | _ ->   PhotoSize.Original 
+
+      // Setup the PhotoID Parameter
+      let stream =
+        if (context.Request.QueryString.get_Item("PhotoID") <> null && context.Request.QueryString.get_Item("PhotoID") <> "") then
+          let id = Convert.ToInt32(context.Request.QueryString.get_Item("PhotoID")) in 
+          ((PhotoManager.GetPhoto id size) :> Stream)
+        else
+          let id = Convert.ToInt32(context.Request.QueryString.get_Item("AlbumID")) in
+          ((PhotoManager.GetFirstPhoto id size) :> Stream)
+            
+      // Get the photo from the database, if nothing is returned, get the default "placeholder" photo
+      let stream = (if (stream = null) then ((PhotoManager.GetDefaultPhoto size) :> Stream) else stream)
+            
+      // Write image stream to the response stream
+      let buffersize = 1024 * 16;
+      let (buffer:byte[]) = Array.zero_create buffersize;
+      let mutable count = stream.Read(buffer, 0, buffersize);
+      while (count > 0) do
+        context.Response.OutputStream.Write(buffer, 0, count)
+        count <- stream.Read(buffer, 0, buffersize)
+  end
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/placeholder-100.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/placeholder-100.jpg
new file mode 100755
index 0000000..f21b633
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/placeholder-100.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/placeholder-200.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/placeholder-200.jpg
new file mode 100755
index 0000000..d4f9905
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/placeholder-200.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/placeholder-600.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/placeholder-600.jpg
new file mode 100755
index 0000000..9715279
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/placeholder-600.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/resume-photo.jpg b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/resume-photo.jpg
new file mode 100755
index 0000000..d4f9905
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Images/resume-photo.jpg differ
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Links.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Links.aspx
new file mode 100755
index 0000000..17a3e71
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Links.aspx
@@ -0,0 +1,71 @@
+<%@ Page Language="F#" MasterPageFile="~/Default.master" Title="Your Name Here | Links"
+    CodeFile="Links.aspx.fs" Inherits="PersonalWebSite.Links_aspx" %>
+
+<asp:content id="Content1" contentplaceholderid="Main" runat="server">
+
+    <div class="shim column"></div>
+    
+    <div class="page" id="links">
+        <div id="content">
+            <h3>About the Links</h3>
+            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod 
+            tincidunt ut laoreet dolore magna erat volutpat.</p>
+            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod 
+            tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis 
+            nostrud exercitation consequat. esse molestie consequat, vel willum.</p>
+            <h4>Top 5</h4>
+            <dl>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+				<dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+            </dl>
+            <h4>Cool Site Designs</h4>
+            <dl>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+				<dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+            </dl>
+            <h4>Photo Sites</h4>
+            <dl>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+				<dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+            </dl>
+            <h4>Resources</h4>
+            <dl>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+                <dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+				<dt><a href="#">Linked site name</a></dt>
+                <dd>A description of the web site goes here.</dd>
+            </dl>
+        </div>
+    </div>
+      
+</asp:content>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Links.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Links.aspx.fs
new file mode 100755
index 0000000..9f5d7f5
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Links.aspx.fs
@@ -0,0 +1,17 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Links_aspx = class
+  inherit System.Web.UI.Page
+  new () = {}
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/PersonalWebSite.sln b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/PersonalWebSite.sln
new file mode 100755
index 0000000..b76aac1
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/PersonalWebSite.sln
@@ -0,0 +1,35 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "PersonalWebSite", ".", "{7477325E-F27A-4481-B8A1-0A0EECAB9A11}"
+	ProjectSection(WebsiteProperties) = preProject
+		TargetFramework = "3.5"
+		Debug.AspNetCompiler.VirtualPath = "/PersonalWebSite"
+		Debug.AspNetCompiler.PhysicalPath = "..\PersonalWebSite\"
+		Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\PersonalWebSite\"
+		Debug.AspNetCompiler.Updateable = "true"
+		Debug.AspNetCompiler.ForceOverwrite = "true"
+		Debug.AspNetCompiler.FixedNames = "false"
+		Debug.AspNetCompiler.Debug = "True"
+		Release.AspNetCompiler.VirtualPath = "/PersonalWebSite"
+		Release.AspNetCompiler.PhysicalPath = "..\PersonalWebSite\"
+		Release.AspNetCompiler.TargetPath = "PrecompiledWeb\PersonalWebSite\"
+		Release.AspNetCompiler.Updateable = "true"
+		Release.AspNetCompiler.ForceOverwrite = "true"
+		Release.AspNetCompiler.FixedNames = "false"
+		Release.AspNetCompiler.Debug = "False"
+		VWDPort = "57404"
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|.NET = Debug|.NET
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{7477325E-F27A-4481-B8A1-0A0EECAB9A11}.Debug|.NET.ActiveCfg = Debug|.NET
+		{7477325E-F27A-4481-B8A1-0A0EECAB9A11}.Debug|.NET.Build.0 = Debug|.NET
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Photos.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Photos.aspx
new file mode 100755
index 0000000..61dbbb1
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Photos.aspx
@@ -0,0 +1,51 @@
+<%@	Page Language="F#" MasterPageFile="~/Default.master" Title="Your Name Here | Photos"
+	CodeFile="Photos.aspx.fs" Inherits="PersonalWebSite.Photos_aspx" %>
+
+<asp:content contentplaceholderid="Main" runat="server">
+	
+	<div class="shim solid"></div> 
+	  
+	<div class="page" id="photos">
+		<div class="buttonbar buttonbar-top">
+			<a href="Albums.aspx"><asp:image runat="Server" skinid="gallery" /></a>
+		</div>
+		<asp:DataList ID="DataList1" runat="Server"	cssclass="view"	dataSourceID="ObjectDataSource1" 
+			repeatColumns="4" repeatdirection="Horizontal" onitemdatabound="DataList1_ItemDataBound" EnableViewState="false">
+			<ItemTemplate>
+				<table border="0" cellpadding="0" cellspacing="0" class="photo-frame">
+					<tr>
+						<td class="topx--"></td>
+						<td class="top-x-"></td>
+						<td class="top--x"></td>
+					</tr>
+					<tr>
+						<td class="midx--"></td>
+						<td><a href='Details.aspx?AlbumID=<%# base.Eval("PhotoAlbumID") %>&Page=<%# box Container.ItemIndex %>'>
+							<img src="Handler.ashx?PhotoID=<%# base.Eval("PhotoID") %>&Size=S" class="photo_198" style="border:4px solid white" alt='Thumbnail of Photo Number <%# base.Eval("PhotoID") %>' /></a></td>
+						<td class="mid--x"></td>
+					</tr>
+					<tr>
+						<td class="botx--"></td>
+						<td class="bot-x-"></td>
+						<td class="bot--x"></td>
+					</tr>
+				</table>
+				<p><%# box (this.Server.HtmlEncode(base.Eval("PhotoCaption").ToString())) %></p>
+			</ItemTemplate>
+			<FooterTemplate>
+			</FooterTemplate>
+		</asp:DataList>
+		<asp:panel id="Panel1" runat="server" visible="false" CssClass="nullpanel">There are currently no pictures in this album.</asp:panel>
+		<div class="buttonbar">
+			<a href="Albums.aspx"><asp:image id="gallery" runat="Server" skinid="gallery" /></a>
+		</div>
+	</div>
+	
+	<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server" TypeName="PersonalWebSite.PhotoManager" 
+		SelectMethod="GetPhotos">
+		<SelectParameters>
+			<asp:QueryStringParameter Name="AlbumID" Type="Int32" QueryStringField="albumID" DefaultValue="0"/>
+		</SelectParameters>
+	</asp:ObjectDataSource>
+	
+</asp:content>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Photos.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Photos.aspx.fs
new file mode 100755
index 0000000..cf22436
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Photos.aspx.fs
@@ -0,0 +1,28 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Photos_aspx = class
+  inherit System.Web.UI.Page 
+ 
+  val mutable gallery : Image  
+  val mutable DataList1 : DataList
+  val mutable Panel1 : Panel
+  val mutable ObjectDataSource1 : ObjectDataSource
+  
+  new () = { DataList1 = null; Panel1 = null; ObjectDataSource1 = null; gallery = null; }
+  
+  member this.DataList1_ItemDataBound (sender:obj, e:DataListItemEventArgs) =
+    if (e.Item.ItemType = ListItemType.Footer) then
+      if (this.DataList1.Items.Count = 0) then this.Panel1.Visible <- true;
+      
+end      
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Register.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Register.aspx
new file mode 100755
index 0000000..23cba99
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Register.aspx
@@ -0,0 +1,21 @@
+<%@ Page Language="F#" MasterPageFile="~/Default.master" Title="Your Name Here | Register"
+    CodeFile="Register.aspx.fs" Inherits="PersonalWebSite.Register_aspx" %>
+
+<asp:Content ID="Content1" ContentPlaceHolderID="Main" Runat="server">
+
+    <div class="shim column"></div>
+
+    <div class="page" id="register">
+		<div id="content">
+            <h3>Request an Account</h3>
+            <p>Accounts will be activated pending the approval of the Administrator.</p>
+            <asp:CreateUserWizard Runat="server" 
+				ContinueDestinationPageUrl="default.aspx"
+                DisableCreatedUser="True"
+                EmailRegularExpression="\S+@\S+\.\S+"
+                EmailRegularExpressionErrorMessage="The email format is invalid.">
+            </asp:CreateUserWizard>
+        </div>
+    </div>
+
+</asp:Content>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Register.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Register.aspx.fs
new file mode 100755
index 0000000..44d1b99
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Register.aspx.fs
@@ -0,0 +1,17 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Register_aspx = class
+  inherit System.Web.UI.Page
+  new () = {}
+end;
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Resume.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Resume.aspx
new file mode 100755
index 0000000..70ca965
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Resume.aspx
@@ -0,0 +1,79 @@
+<%@ Page Language="F#" MasterPageFile="~/Default.master" Title="Your Name Here | Resume"
+    CodeFile="Resume.aspx.fs" Inherits="PersonalWebSite.Resume_aspx" %>
+
+<asp:content id="Content1" contentplaceholderid="Main" runat="server">
+
+    <div class="shim column"></div>
+    
+    <div class="page" id="resume">
+        <div id="content" class="resume">
+			<table border="0" cellpadding="0" cellspacing="0" class="photo-frame" id="photo">
+				<tr>
+					<td class="topx--"></td>
+					<td class="top-x-"></td>
+					<td class="top--x"></td>
+				</tr>
+				<tr>
+					<td class="midx--"></td>
+					<td><img src="images/resume-photo.jpg" class="photo_198" style="border:4px solid white" alt="Resume Photo"/></td>
+					<td class="mid--x"></td>
+				</tr>
+				<tr>
+					<td class="botx--"></td> 
+					<td class="bot-x-"></td>
+					<td class="bot--x"></td>
+				</tr>
+			</table>
+			<h3>Your Name Here </h3>
+			<p>resume 1/23/04</p>
+			<p>555-555-1212 fax<br />
+			555-555-1212 voice<br />
+			someone at example.com<br />
+			www.example.com<br />
+			City, State  Country</p>
+			<p><a href="#"><asp:image runat="Server" AlternateText="download resume in word format" skinid="dwn_res" /></a></p>
+			<h4>Objective</h4>
+			<p class="first">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
+			<h4>Experience</h4>
+			<p class="first">1999 - 2004  Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br />
+				Sed diam nonummy nibh euismod </p>
+			<ul>
+				<li>Ttincidunt ut laoreet dolore magna aliquam erat volutpat. </li>
+				<li>Ut wisi enim ad minim veniam, quis nostrud exercitation consequat. </li>
+				<li>Duis autem veleum iriure dolor in hendrerit in vel willum.</li>
+			</ul>
+			<p>1995 - 1999   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br />
+				Sed diam nonummy nibh euismod </p>
+			<ul>
+				<li>Ttincidunt ut laoreet dolore magna aliquam erat volutpat. </li>
+				<li>Ut wisi enim ad minim veniam, quis nostrud exercitation consequat. </li>
+				<li>Duis autem veleum iriure dolor in hendrerit in vel willum.</li>
+			</ul>
+			<p>1993 - 1995   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br />
+				Sed diam nonummy nibh euismod </p>
+			<ul>
+				<li>Ttincidunt ut laoreet dolore magna aliquam erat volutpat. </li>
+				<li>Ut wisi enim ad minim veniam, quis nostrud exercitation consequat. </li>
+				<li>Duis autem veleum iriure dolor in hendrerit in vel willum.</li>
+			</ul>
+			<p>1987 - 1993   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br />
+				Sed diam nonummy nibh euismod </p>
+			<ul>
+				<li>Ttincidunt ut laoreet dolore magna aliquam erat volutpat. </li>
+				<li>Ut wisi enim ad minim veniam, quis nostrud exercitation consequat. </li>
+				<li>Duis autem veleum iriure dolor in hendrerit in vel willum.</li>
+			</ul>
+			<h4>Education</h4>
+			<p class="first">1984 - 1987   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br />
+			Sed diam nonummy nibh euismod </p>
+			<ul>
+				<li>Ttincidunt ut laoreet dolore magna aliquam erat volutpat. </li>
+				<li>Ut wisi enim ad minim veniam, quis nostrud exercitation consequat.</li>
+			</ul>
+			<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
+	        
+			</div>
+        
+    </div>
+      
+</asp:content>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Resume.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Resume.aspx.fs
new file mode 100755
index 0000000..31cf11d
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Resume.aspx.fs
@@ -0,0 +1,17 @@
+#light
+namespace PersonalWebSite
+
+open System;
+open System.Data;
+open System.Configuration;
+open System.Web;
+open System.Web.Security;
+open System.Web.UI;
+open System.Web.UI.WebControls;
+open System.Web.UI.WebControls.WebParts;
+open System.Web.UI.HtmlControls;
+
+type Resume_aspx = class
+  inherit System.Web.UI.Page
+  new () = {}
+end
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Welcome.html b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Welcome.html
new file mode 100755
index 0000000..0a8d283
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/Welcome.html
@@ -0,0 +1,304 @@
+<!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>
+    <title>Welcome</title>
+    <style type="text/css">
+
+body {
+    font-family: verdana;
+    font-size:9pt;
+    line-height:16pt;
+    margin:50px;
+    }
+    
+h1 {
+    font-family: verdana;
+    font-size:16pt;
+    font-weight:bold;
+    }
+    
+h2 {
+    font-family: verdana;
+    font-size:12pt;
+    font-weight:bold;
+    color: #666;
+    }
+
+h3 {
+    font-family: verdana;
+    font-size:12pt;
+    font-weight:bold;
+    color: #999;
+    }
+
+pre, code { font-family: consolas; padding:0px; margin-top:4px; margin-bottom:4px; }
+</style>
+</head>
+<body>
+    <h1>Personal Web Site Starter Kit - in F#!</h1>
+    <p>
+        Congratulations! You have created your own Personal Web Site, which includes a home
+        page, resume, and photo album. You can use the site as-is with some small customizations, such as adding your own
+        content. In addition, you can add pages to the site. The following sections explain
+        how to use the Personal Web Site. First we will mention
+      a few important topics regarding the application and database configuration:</p>
+    <ul>
+        <li>Configuring F# to work with ASP.NET <span style="color: red">(important)</span>
+        </li>
+      <li>Creating and Configuring Databases <span style="color: red">(important)</span></li>
+      <li>Creating a new F# page </li>
+    </ul>
+  <p>
+    In the rest of the document we will describe several actions that you can do when
+    the application is correctly configured:</p>
+  <ul>
+      <li>Creating an Administrative User </li>
+        <li>Managing the Personal Web Site</li>
+        <li>Working with Photo Albums</li>
+        <li>Publishing Your Web Site</li>
+    </ul>
+  <p>
+    <strong>NOTE: </strong>Sections marked <span style="color: red">important</span>,
+    have to be followed before you can start the application!</p>
+  <h2>Configuring F# to Work with ASP.NET</h2>
+  <p>
+    For F# to work correctly with ASP.NET it is needed to configure a CodeDOM provider
+    in the <code>web.config</code> file. The file already includes section with the
+    configuration, but you need to update the assembly version to match the F# version
+    you installed (if you don't know the version, you can start <strong>FSI</strong>,
+    which prints the version when starting). Find the<code> compiler</code> node in
+    the <code>web.config</code> file and set the right version number (e.g. 1.9.2.2): </p>
+  <pre><?xml version="1.0"?>
+<configuration>
+  <system.web>
+    <compilation debug="true">  
+      <compilers>
+        <compiler language="F#;f#;fs;fsharp" extension=".fs" type="Microsoft.FSharp.Compiler.CodeDom.FSharpAspNetCodeProvider, 
+                            FSharp.Compiler.CodeDom, Version=<strong><version number></strong>, Culture=neutral, PublicKeyToken=a19089b1c74d0809"/>
+      </compilers>
+    </compilation>
+  </system.web>
+</configuration>
+</pre>
+  <p>
+    If you want to configure a different ASP.NET project to use F#, you need to include
+    the <span style="font-family: Consolas">compiler </span>section from this code snippet.</p>
+    <h2>Creating and Configuring Databases</h2>
+  <p>
+    Before you can start using the application, you need to configure a database. This
+    application uses two separate databases - one to store user information managed
+    by the ASP.NET and second to store custom application data (Photos and Albums).
+    We describe two possible situations - you can either use SQL Server 2005 Express
+    edition and keep your database files in <code>App_Data</code> directory or you can use different
+    SQL Server edition.</p>
+  <p>
+    <strong>To use SQL Server 2005 Express</strong></p>
+  <ol>
+  <li>You can get <strong>SQL Server 2005 Express</strong> for free from Microsoft website: <a href="http://msdn.microsoft.com/vstudio/express/sql">
+    http://msdn.microsoft.com/vstudio/express/sql</a>
+  </li>
+    <li>You need to create the database to store custom data manually. To do this right
+      click <strong>App_Data</strong> folder, select <strong>Add New Item...</strong>,
+      select <strong>SQL Database</strong> and call it <strong>Personal.mdf</strong>.</li>
+    <li>Open <code>web.config</code> file and modify the connectionStrings section to include the following:
+    <pre><connectionStrings>
+  <add name="Personal" providerName="System.Data.SqlClient" connectionString=
+       "Data Source=.\SQLExpress;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|Personal.mdf" />
+  <remove name="LocalSqlServer"/>
+  <add name="LocalSqlServer" connectionString=
+       "Data Source=.\SQLExpress;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|aspnetdb.mdf" />
+</connectionStrings>   </pre>
+    </li>
+    <li>Now we created and configured the database, but we still need to create database
+      tables required by the application. The database and database tables reqired by
+      ASP.NET will be created automatically (including the <strong>AspNetDB.mdf </strong>
+      file), so you don't need to configure it manually.</li>
+    <li>To configure the custom database (<strong>Personal.mdf</strong>) we will
+      need <strong>SQL Server Management Studio Express</strong>, which can be downloaded
+      from the same URL as <strong>SQL Server 2005 Express</strong>. Open <strong>SQL Server
+        Management Studio Express</strong>, connect to the created database file (right
+      click on <strong>Databases </strong>in the <strong>Object Explorer </strong>and
+      select <strong>Attach...</strong>), copy contents of the <span style="font-family: Consolas">
+        personal-add.sql</span> file in the <strong>App_Data</strong> to new query window
+      and execute it. </li>
+    <li>You are now ready to start using the application, to open the home page press
+      Ctrl+F5! </li>
+  </ol>
+  <p>
+    <strong>To use other SQL Server 2005 edition</strong></p>
+  <ol>
+    <li>First we will configure ASP.NET database. To do this run the <strong>ASP.NET SQL
+      Server Setup wizard tool</strong>:<br />
+      <code>C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql.exe</code></li>
+    <li>In the wizard select <strong>Configure SQL Server for application services</strong>,
+      select authentication method (you can leave Windows authentication if your windows
+      account has the rights to create databases), enter a database name (e.g. <strong>PWS_AspNetDb</strong>)
+      and click <strong>Finish</strong>. If you want to create databse in different than
+      the default location, than you need to open <strong>SQL Server Management Studio</strong>
+      and create the database before running the wizard.</li>
+    <li>Now we configured ASP.NET database and we will create the application database
+      to store Photos and Albums. To do this open <strong>SQL Server Management Studio </strong>
+      connect to the SQL Server instance and create a new databse (e.g. <strong>PWS_Personal</strong>)
+      open a new query window, copy SQL commands from the <code>personal-add.sql</code> file in
+      the <strong>App_Data</strong> directory and execute them to create database tables.</li>
+    <li>Open <code>web.config</code> file and modify the connectionStrings section to
+      include the following (note: this sample uses Windows authentication, to use different
+      authentication method you will need to modify the connection strings):
+      <pre><connectionStrings>
+  <add name="Personal" providerName="System.Data.SqlClient" connectionString=
+       "Data Source=.;Integrated Security=True;Database=PWS_WebPersonal" />
+  <remove name="LocalSqlServer"/>
+  <add name="LocalSqlServer" connectionString=
+       "Data Source=.;Integrated Security=True;Database=PWS_AspNetDb" />
+</connectionStrings>   </pre>
+    </li>
+    <li>You are now ready to start using the application, to open the home page press
+      Ctrl+F5!  </li>
+  </ol>
+  <h2>
+    Creating a New F# Page</h2>
+  <p>
+    F# distribution currently doesn't supply F# page template, so if you want to create
+    a new page you'll have to workaround this limitation. The easiest way to do so is
+    to create a new text file (right click on the project, select <strong>Add New Item</strong>,
+    select <strong>Text File</strong>). Once you created two empty files (<code>NewPage.aspx</code>
+    and <code>NewPage.aspx.fs</code>), you can copy the following code and start programming
+    ASP.NET applications in F#!</p>
+  <p>
+    <strong>NewPage.aspx</strong></p>
+  <pre>
+<%@ Page Language="F#" AutoEventWireup="true"  CodeFile="NewPage.aspx.fs" Inherits="FSharpWeb.NewPage" %>
+<!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>New Page</title>
+</head><body><br />  <form runat="server"><div>
+    <h1>New Page</h1>
+    <!-- ASP.NET button with event handler declared in code-behind file -->
+    <asp:Button id="btnClickMe" runat="server" click="ButtonClicked" Text="Click me!" />
+  </div></form>
+</body></html> </pre>
+<p>
+    <strong>NewPage.aspx.fs</strong></p>
+  <pre>
+#light
+namespace FSharpWeb
+
+open System
+open System.Web
+open System.Web.UI
+open System.Web.UI.WebControls
+
+type NewPage = 
+  inherit System.Web.UI.Page 
+  val mutable btnClickMe : Button
+
+  // initialize all controls to a null value
+  new() = 
+    let init() = (Array.zeroCreate 1).[0]
+    { btnClickMe = init(); } 
+  override this.OnLoad(e) =
+    base.OnLoad(e);
+  // Event handler for the button
+  member this.ButtonClicked(sender, e) =
+    this.btnClickMe.Text <- "Clicked!"</pre>
+  <p>
+    <strong>NOTE: </strong>Since F# doesn't currently support partial classes, you have
+    to declare all controls manually in the code-behind file. This means that every
+    control with <strong>runat </strong>attribute set to <strong>server </strong>and
+    with <strong>id</strong> attribute must have corresponding field in the F# code-behind
+    file. In this example the only control used is a <strong>btnClickMe</strong>.</p>
+  <h2>
+    Creating an Administrative User</h2>
+    <p>
+        The first step you must take is to create an administrative user. The administrative
+        user has permission to upload photos and create albums.</p>
+    <p>
+        <b>To create an administrative user</b></p>
+    <ol>
+        <li>Run the site at least once before proceeding. This ensures the initialization of the Membership
+        and Roles databases.</li>
+        <li>In the <b>Website</b> menu, click <b>ASP.NET Configuration</b>.</li><li>Click the
+        <b>Security</b> tab.</li><li>Click <b>Create user</b>.</li><li>In the <b>Create User</b>
+        box, type a user name, password, and e-mail address for the administrator user. You
+        must also provide a security question and answer that is used to help you recover your
+        password, if necessary.</li><li>In the <b>Roles</b> box, select both the <b>Administrators</b>
+        and <b>Friends</b> check boxes to make the user into an administrator and a member of
+        the Friends role.</li><li>Click <b>Create User</b>.</li><li>Close the Web Site Administration
+        Tool window.</li>
+    </ol>
+    <h2>Managing the Personal Web Site</h2>
+    <p>
+        The following sections provide basic information about how to administer the site.</p>
+    <h3>Designating Guest Users as Friends</h3>
+    <p>
+        Visitors to your site can register themselves on your site. You can make registered
+        users into Friends, which gives them permission to view private photo albums.</p>
+    <p>
+        <b>To give users permission to view private photo albums</b></p>
+    <ol>
+        <li>In the <b>Website</b> menu, click <b>ASP.NET Configuration</b>.</li><li>Click the
+        <b>Security</b> tab.</li>
+        <li>Under <b>Users,</b> click <b>Manage users.</b> </li>
+        <li>In the user list, click <b>Edit roles</b> for the guest. (If you do not see the
+        user's name, use the search box.)</li>
+        <li>Under <b>Roles</b>, select <b>Friends</b>. </li>
+        <li>Close the Web Administration Tool window.</li>
+    </ol>
+    <h3>Working with Photo Albums</h3>
+    <p>
+        The photo album feature allows you to:</p>
+    <ul>
+        <li>Create albums that act as collections of photos.</li>
+        <li>Upload photos individually into an album.</li>
+        <li>Bulk upload a collection of photos into an album. This feature is useful for creating
+        an album from a collection of photos, such as your vacation pictures.</li>
+    </ul>
+    <p>
+        <b>To create an album and add photos</b></p>
+    <ol>
+        <li>Login to the site as an administrator.</li>
+        <li>In the menu, click <b>Manage</b>. </li>
+        <li>Under <b>Add New Album</b>, type a name.</li>
+        <li>If you want everyone to be able to see your photos, select <b>Make this album public</b>.
+        If you leave this check box unselected, only users who are registered as friends can
+        view the album.</li>
+        <li>Click <b>Add</b> to create the album. </li>
+        <li>Under <b>Your Albums</b>, click the blank photo for the new album.</li>
+        <li>Under <b>Add Photos</b>, type or select the photo file name, type a caption, and
+        click <b>Insert</b>. </li>
+        <li>Repeat Step 4 for each photo you want to add to the album.</li>
+    </ol>
+    <p>
+        <b>To bulk upload photos into an album</b></p>
+    <ol>
+        <li>Copy your photos to the Upload folder in the Web site.</li>
+        <li>In the menu, click <b>Manage</b>. </li>
+        <li>In the album list, click the photo of the album to use. (Create a new album first,
+        if necessary.)</li>
+        <li>Click <b>Import</b>. All the photos in the Upload folder are added to the album.</li>
+    </ol>
+    <h2>Publishing your Site</h2>
+    <p>
+        When you are ready to share your Web site with others, you can copy it to your Web
+        server. You need to know the File Transfer Protocol (FTP) address of your server,
+        and if required, the user name and password you use.</p>
+    <ol>
+        <li>In the <b>Website</b> menu, click <b>Copy Web Site</b>. The Copy Web Site tool displays
+        the files from your Web site under <b>Source Web Site</b>. </li>
+        <li>In the <b>Connect to</b> box, click <b>Connect to</b> ....</li>
+        <li>In the <b>Open Web Site</b> dialog box, click the <b>FTP Sites</b> tab.</li>
+        <li>Type the FTP address of your server, and if required, the user name and password
+        that your hosting site has provided. The FTP URL usually has a format like this:
+        <pre>ftp://ftp.servername/foldername</pre></li>
+        <li>Click <b>Open</b>. The files on the Web server are displayed under <b>Remote Web
+        Site</b>.<br />
+        <b>Note:</b> If you have trouble connecting to the server, contact the server administrator.</li>
+        <li>In the <b>Move Files</b> list, click <b>All source files to remote Web site</b>.
+        </li>
+        <li>Click the <b>Copy Web Site</b> button. The files from your Personal Web Site are
+        copied to the server.</li>
+    </ol>
+</body>
+</html>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/web.config b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/web.config
new file mode 100755
index 0000000..fcb9165
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/web.config
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+<configuration>
+	<configSections>
+		<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+			<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+				<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+				<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+					<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
+					<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+					<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+					<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/></sectionGroup></sectionGroup></sectionGroup></configSections><connectionStrings>
+		<add name="Personal" providerName="System.Data.SqlClient" connectionString="Data Source=.\SQLExpress;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|Personal.mdf"/>
+		<remove name="LocalSqlServer"/>
+		<add name="LocalSqlServer" connectionString="Data Source=.\SQLExpress;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|aspnetdb.mdf"/>
+	</connectionStrings>
+	<system.web>
+		<pages styleSheetTheme="White">
+			<controls>
+				<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+				<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></controls></pages>
+		<customErrors mode="RemoteOnly"/>
+		<compilation debug="true">
+			<assemblies>
+				<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+				<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+				<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+				<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/></assemblies></compilation>
+		<authentication mode="Forms">
+			<forms loginUrl="Default.aspx" protection="Validation" timeout="300"/>
+		</authentication>
+		<authorization>
+			<allow users="*"/>
+		</authorization>
+		<globalization requestEncoding="utf-8" responseEncoding="utf-8"/>
+		<roleManager enabled="true"/>
+		<siteMap defaultProvider="XmlSiteMapProvider" enabled="true">
+			<providers>
+				<add name="XmlSiteMapProvider" description="SiteMap provider which reads in .sitemap XML files." type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" siteMapFile="web.sitemap" securityTrimmingEnabled="true"/>
+			</providers>
+		</siteMap>
+		<httpHandlers>
+			<remove verb="*" path="*.asmx"/>
+			<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+			<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+			<add verb="GET,HEAD" path="ScriptResource.axd" validate="false" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></httpHandlers>
+		<httpModules>
+			<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></httpModules></system.web>
+	<system.codedom>
+		<compilers>
+			<compiler language="F#;f#;fs;fsharp" extension=".fs" type="Microsoft.FSharp.Compiler.CodeDom.FSharpAspNetCodeProvider, FSharp.Compiler.CodeDom, Version=1.9.9.9, Culture=neutral, PublicKeyToken=a19089b1c74d0809"/>
+				<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider,System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
+					<providerOption name="CompilerVersion" value="v3.5"/>
+					<providerOption name="WarnAsError" value="false"/></compiler>
+				<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
+					<providerOption name="CompilerVersion" value="v3.5"/>
+					<providerOption name="OptionInfer" value="true"/>
+					<providerOption name="WarnAsError" value="false"/></compiler></compilers>
+	</system.codedom>
+	<location path="Admin">
+		<system.web>
+			<authorization>
+				<allow roles="Administrators"/>
+				<deny users="*"/>
+			</authorization>
+		</system.web>
+	</location>
+	<system.webServer>
+			<validation validateIntegratedModeConfiguration="false"/>
+		<modules>
+			<remove name="ScriptModule"/>
+			<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></modules>
+		<handlers>
+			<remove name="WebServiceHandlerFactory-Integrated"/>
+			<remove name="ScriptHandlerFactory"/>
+			<remove name="ScriptHandlerFactoryAppServices"/>
+			<remove name="ScriptResource"/>
+			<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+			<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+			<add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></handlers></system.webServer>
+	<runtime>
+		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+			<dependentAssembly>
+				<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
+				<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/></dependentAssembly>
+			<dependentAssembly>
+				<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
+				<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/></dependentAssembly></assemblyBinding></runtime></configuration>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/web.sitemap b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/web.sitemap
new file mode 100755
index 0000000..72bbcf4
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/PersonalWebSite/web.sitemap
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<siteMap>
+	<siteMapNode title="Home" url="Default.aspx">
+		<siteMapNode title="Resume" url="Resume.aspx" />
+		<siteMapNode title="Links" url="Links.aspx" />
+		<siteMapNode title="Albums" url="Albums.aspx" >
+			<siteMapNode title="Photos" url="Photos.aspx" >
+				<siteMapNode title="Details" url="Details.aspx" />
+			</siteMapNode>
+		</siteMapNode>
+		<siteMapNode title="Register" url="Register.aspx" />
+		<siteMapNode title="Manage" url="Admin/Albums.aspx" >
+			<siteMapNode title="Photos" url="Admin/Photos.aspx" >
+				<siteMapNode title="Details" url="Admin/Details.aspx" />
+			</siteMapNode>
+		</siteMapNode>
+	</siteMapNode>
+</siteMap>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/Time/AsyncTime.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/AsyncTime.aspx
new file mode 100755
index 0000000..3a51490
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/AsyncTime.aspx
@@ -0,0 +1,88 @@
+<%@ Page Language="F#" Async="true"  %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<script language="F#" runat="server" >
+     /// F# scripts embedded in ASPX pages must be a set of 'member' declarations.
+     /// ASP.NET inserts these into the code generated for the page object type.
+
+     /// This member is invoked on the server when the page is loaded. It tests
+     /// whether the page was loaded for the first time and updates the content of
+     /// this.Time control.
+    member page.AddOnPreRenderCompleteAsync(p) = 
+        let beginMeth, endMeth, cancelMeth = Async.AsBeginEnd p 
+
+        page.AddOnPreRenderCompleteAsync
+            ((fun obj ev cb state -> beginMeth(ev,cb,state)),
+             (fun iar -> endMeth iar));
+
+    member page.RegisterAsyncTask(p) = 
+        let beginMeth, endMeth, cancelMeth = p |> Async.AsBeginEnd
+
+        page.RegisterAsyncTask
+            (PageAsyncTask((fun obj ev cb state -> beginMeth(ev,cb,state)),
+                           (fun iar -> endMeth iar),
+                           (fun iar -> cancelMeth iar),
+                           null));
+
+    member page.Form1_Load(sender: obj, e: EventArgs) =
+        if not page.Page.IsPostBack then
+            page.AddOnPreRenderCompleteAsync(fun e -> 
+                // This is the asynchronous program that runs when during PreRender of the initial load
+                async { 
+
+                    // Start the two children
+                    let text1 = "<br> Process1 Started at " + DateTime.Now.ToLongTimeString(); 
+                    let! p1 = Async.Sleep(500) |> Async.StartChild
+                    let text2 = "<br> Process2 Started at " + DateTime.Now.ToLongTimeString(); 
+                    let! p2 = Async.Sleep(500) |> Async.StartChild
+                    // Wait for the two children
+                    let! res1 = p1
+                    let text3 = "<br> Process1 Responded at least before " + DateTime.Now.ToLongTimeString(); 
+                    let! res2 = p2
+                    let text4 = "<br> Process2 Responded at least before " + DateTime.Now.ToLongTimeString(); 
+                    let text5 = "<br> All Done at " + DateTime.Now.ToLongTimeString();
+                    // Update the display
+                    page.Time.Text <- text1+text2+text3+text4+text5 })
+
+        //if not page.Page.IsPostBack then
+        //    page.Time.Text <- DateTime.Now.ToString()
+
+    member page.Reload_Click(sender: obj, e: EventArgs) =
+        page.RegisterAsyncTask(fun e -> 
+            // This is the asynchronous program that runs in response to user action
+            async { 
+
+                // Start the two children
+                let text1 = "<br> Process1 Started at " + DateTime.Now.ToLongTimeString(); 
+                let! p1 = Async.Sleep(500) |> Async.StartChild
+                let text2 = "<br> Process2 Started at " + DateTime.Now.ToLongTimeString(); 
+                let! p2 = Async.Sleep(500) |> Async.StartChild
+                // Wait for the two children
+                let! res1 = p1
+                let text3 = "<br> Process1 Responded at least before " + DateTime.Now.ToLongTimeString(); 
+                let! res2 = p2
+                let text4 = "<br> Process2 Responded at least before " + DateTime.Now.ToLongTimeString(); 
+                let text5 = "<br> All Done at " + DateTime.Now.ToLongTimeString();
+                // Update the display
+                page.Time.Text <- "(Reload)" + text1+text2+text3+text4+text5 })
+
+</script> 
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head id="Head1" runat="server">
+   <title>Current time</title>
+   <style type="text/css">
+      body { font-family:calibri,verdana,sans-serif; }
+   </style>
+</head>
+<body>
+   <form id="Form1" runat="server" OnLoad="Form1_Load">
+      The current time is:
+      <asp:Label  runat="server" id="Time" />
+      <asp:Button runat="server" id="Reload" text="Reload" OnClick="Reload_Click" />
+   </form>
+</body>
+</html>
+
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/Time/AsyncTime2.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/AsyncTime2.aspx
new file mode 100755
index 0000000..e207c75
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/AsyncTime2.aspx
@@ -0,0 +1,28 @@
+<!-- --------------------------
+   Listing 14-4.
+-->
+
+<%@ Page Language="F#" 
+         AutoEventWireup="true" 
+         CodeFile="AsyncTime2.aspx.fs" 
+         Inherits="FSharpWeb.Time2"
+         Async="true"  %>
+
+<!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>Current time</title>
+    <style type="text/css">
+        body { font-family:calibri,verdana,sans-serif; }
+    </style>
+</head>
+<body>
+    <form runat="server">
+      The current time is:
+      <asp:Label  runat="server" id="Time" />
+      <asp:Button runat="server" id="Reload" text="Reload" OnClick="Reload_Click" />
+    </form>
+</body>
+</html>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/Time/AsyncTime2.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/AsyncTime2.aspx.fs
new file mode 100755
index 0000000..8290948
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/AsyncTime2.aspx.fs
@@ -0,0 +1,90 @@
+// ----------------------------
+//  Listing 14-5.
+
+namespace FSharpWeb
+
+open System
+open System.Web
+open System.Web.UI
+open System.Web.UI.WebControls
+open Microsoft.FSharp.Control.WebExtensions
+
+[<AutoOpen>]
+module PageExtensions = 
+    type System.Web.UI.Page with 
+        member page.AddOnPreRenderCompleteAsync(p) = 
+            let beginMeth, endMeth, cancelMeth = Async.AsBeginEnd p 
+
+            page.AddOnPreRenderCompleteAsync
+                ((fun obj ev cb state -> beginMeth(ev,cb,state)),
+                 (fun iar -> endMeth iar));
+
+        member page.RegisterAsyncTask(p) = 
+            let beginMeth, endMeth, cancelMeth = p |> Async.AsBeginEnd
+
+            page.RegisterAsyncTask
+                (PageAsyncTask((fun obj ev cb state -> beginMeth(ev,cb,state)),
+                               (fun iar -> endMeth iar),
+                               (fun iar -> cancelMeth iar),
+                               null));
+
+
+type Time2() =
+    inherit Page()
+    
+    [<DefaultValue>]
+    val mutable Time : Label
+    [<DefaultValue>]
+    val mutable Reload : Button
+
+    member page.Page_Load(sender: obj, e: EventArgs) =
+        if not page.Page.IsPostBack then
+            page.AddOnPreRenderCompleteAsync(fun e -> 
+                // This is the asynchronous program that runs when during PreRender of the initial load
+                async {
+
+                    // Start the two children
+                    let text1 = "<br> Process1 Started at " + DateTime.Now.ToLongTimeString(); 
+                    let! p1 = Async.Sleep 5000 |> Async.StartChild
+                    let text2 = "<br> Process2 Started at " + DateTime.Now.ToLongTimeString(); 
+                    let! p2 = Async.Sleep 5000 |> Async.StartChild
+                    // Wait for the two children
+                    let! res1 = p1
+                    let text3 = "<br> Process1 Responded at least before " + DateTime.Now.ToLongTimeString(); 
+                    let! res2 = p2
+                    let text4 = "<br> Process2 Responded at least before " + DateTime.Now.ToLongTimeString(); 
+                    let text5 = "<br> All Done at " + DateTime.Now.ToLongTimeString();
+                    // Update the display
+                    page.Time.Text <- text1+text2+text3+text4+text5 })
+
+        //if not page.Page.IsPostBack then
+        //    page.Time.Text <- DateTime.Now.ToString()
+
+    member page.Reload_Click(sender: obj, e: EventArgs) =
+        page.RegisterAsyncTask(fun e -> 
+            // This is the asynchronous program that runs in response to user action
+            async { 
+
+                // Start the two children
+                let text1 = "<br> Process1 Started at " + DateTime.Now.ToLongTimeString(); 
+                let! p1 = Async.Sleep 1000 |> Async.StartChild
+                let text2 = "<br> Process2 Started at " + DateTime.Now.ToLongTimeString(); 
+                let! p2 = Async.Sleep 1000 |> Async.StartChild
+                // Wait for the two children
+                let! res1 = p1
+                let text3 = "<br> Process1 Responded at least before " + DateTime.Now.ToLongTimeString(); 
+                let! res2 = p2
+                let text4 = "<br> Process2 Responded at least before " + DateTime.Now.ToLongTimeString(); 
+                let text5 = "<br> All Done at " + DateTime.Now.ToLongTimeString();
+                // Update the display
+                page.Time.Text <- "(Reload)" + text1 + text2 + text3 + text4 + text5  })
+
+        //page.Time.Text <- "(R) " + DateTime.Now.ToString()
+
+(*
+
+    protected void Page_PreRenderComplete(object sender, EventArgs e) {
+        Label1.Text = _ws1Result;
+        Label2.Text = _ws2Result;
+    }
+*)
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Time.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Time.aspx
new file mode 100755
index 0000000..6b46225
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Time.aspx
@@ -0,0 +1,37 @@
+<%@ Page Language="F#" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<script language="F#" runat="server">
+     /// F# scripts embedded in ASPX pages must be a set of 'member' declarations.
+     /// ASP.NET inserts these into the code generated for the page object type.
+
+     /// This member is invoked on the server when the page is loaded. It tests
+     /// whether the page was loaded for the first time and updates the content of
+     /// this.Time control.
+     member this.Form1_Load(sender: obj, e: EventArgs) =
+         if not this.Page.IsPostBack then
+             this.Time.Text <- DateTime.Now.ToString()
+
+     /// This member is invoked on the server when the Reload button is clicked.
+     member this.Reload_Click(sender: obj, e: EventArgs) =
+         this.Time.Text <- "(R) " + DateTime.Now.ToString()
+</script> 
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+   <title>Current time</title>
+   <style type="text/css">
+      body { font-family:calibri,verdana,sans-serif; }
+   </style>
+</head>
+<body>
+   <form id="Form1" runat="server" OnLoad="Form1_Load">
+      The current time is:
+      <asp:Label  runat="server" id="Time" />
+      <asp:Button runat="server" id="Reload" text="Reload" OnClick="Reload_Click" />
+   </form>
+</body>
+</html>
+
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Time2.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Time2.aspx
new file mode 100755
index 0000000..68d1663
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Time2.aspx
@@ -0,0 +1,27 @@
+<!-- --------------------------
+   Listing 14-4.
+-->
+
+<%@ Page Language="F#" 
+         AutoEventWireup="true" 
+         CodeFile="Time2.aspx.fs" 
+         Inherits="FSharpWeb.Time2" %>
+
+<!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>Current time</title>
+    <style type="text/css">
+        body { font-family:calibri,verdana,sans-serif; }
+    </style>
+</head>
+<body>
+    <form runat="server">
+      The current time is:
+      <asp:Label  runat="server" id="Time" />
+      <asp:Button runat="server" id="Reload" text="Reload" OnClick="Reload_Click" />
+    </form>
+</body>
+</html>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Time2.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Time2.aspx.fs
new file mode 100755
index 0000000..2d9d45a
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Time2.aspx.fs
@@ -0,0 +1,25 @@
+// ----------------------------
+//  Listing 14-5.
+
+#light
+namespace FSharpWeb
+
+open System
+open System.Web
+open System.Web.UI
+open System.Web.UI.WebControls
+
+type Time2() =
+    inherit Page()
+    
+    [<DefaultValue>]
+    val mutable Time : Label
+    [<DefaultValue>]
+    val mutable Reload : Button
+
+    member this.Page_Load(sender: obj, e: EventArgs) =
+        if not this.Page.IsPostBack then
+            this.Time.Text <- DateTime.Now.ToString()
+
+    member this.Reload_Click(sender: obj, e: EventArgs) =
+        this.Time.Text <- "(R) " + DateTime.Now.ToString()
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Web.config b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Web.config
new file mode 100755
index 0000000..e3b1916
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/Time/Web.config
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<configuration>
+  <system.web>
+    <compilation debug="true" />
+  </system.web>
+
+  <system.codedom>
+    <compilers>
+      <compiler language="F#;f#;fs;fsharp" extension=".fs" type="Microsoft.FSharp.Compiler.CodeDom.FSharpAspNetCodeProvider, FSharp.Compiler.CodeDom, Version=1.9.9.9, Culture=neutral, PublicKeyToken=a19089b1c74d0809"/>
+    </compilers>
+  </system.codedom>
+</configuration>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/App_Code/CodeBehind.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/App_Code/CodeBehind.fs
new file mode 100755
index 0000000..4f9f390
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/App_Code/CodeBehind.fs
@@ -0,0 +1,11 @@
+module N.Module
+
+type C(y:int) =  member this.Factorial (u) =
+                    let rec f x = if x <= 1 then 1 else x * (f (x - 1))
+                    f u
+
+                 static member NetFxVersion = System.Environment.Version
+                 
+                 member this.TestList n = [1 .. n] |> List.map this.Factorial
+                                                   |> List.sum
+                                             
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/Default.aspx b/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/Default.aspx
new file mode 100755
index 0000000..430ccf2
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/Default.aspx
@@ -0,0 +1,6 @@
+<%@ Page Language="F#" AutoEventWireup="true" CodeFile="Default.aspx.fs" Inherits="N.Default" %>
+
+<html>
+<head><title>Simple F# ASP.Net</title></head>
+<body><form runat="server"></form></body>
+</html>
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/Default.aspx.fs b/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/Default.aspx.fs
new file mode 100755
index 0000000..c24f254
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/Default.aspx.fs
@@ -0,0 +1,17 @@
+namespace N
+
+open System
+open System.Web
+open System.Web.UI
+open System.Web.UI.WebControls
+
+type public Default() =
+  inherit Page()
+  member this.Page_Load(sender : obj, e : System.EventArgs) = 
+    let o = new N.Module.C(10)
+    let a1 = N.Module.C.NetFxVersion.ToString()
+    let a2 = o.TestList(5).ToString()
+    this.Response.AppendHeader("NetFxVer", a1)
+    this.Response.AppendHeader("Sum", a2)
+    this.Response.Write("<P>NetFxVer:" + a1)
+    this.Response.Write("<P>Sum:" + a2)
diff --git a/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/web.config b/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/web.config
new file mode 100755
index 0000000..1e380a6
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ASP.NET/VerySimple/web.config
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<configuration>
+	<configSections>
+		<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+			<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+				<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+				<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+					<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
+					<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+					<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+					<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/></sectionGroup></sectionGroup></sectionGroup></configSections><system.web>
+		<trace enabled="true"/>
+		<compilation debug="true">
+			<assemblies>
+				<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+				<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+				<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+				<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/></assemblies></compilation>
+		<pages>
+			<controls>
+				<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+				<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></controls></pages>
+		<httpHandlers>
+			<remove verb="*" path="*.asmx"/>
+			<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+			<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+			<add verb="GET,HEAD" path="ScriptResource.axd" validate="false" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></httpHandlers>
+		<httpModules>
+			<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></httpModules></system.web>
+	<system.codedom>
+		<compilers>
+			<compiler language="F#;f#;fs;fsharp" extension=".fs" type="Microsoft.FSharp.Compiler.CodeDom.FSharpAspNetCodeProvider, FSharp.Compiler.CodeDom,  Version=1.9.9.9,  Culture=neutral,   PublicKeyToken=a19089b1c74d0809"/>			
+      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
+				<providerOption name="CompilerVersion" value="v3.5"/>
+				<providerOption name="WarnAsError" value="false"/></compiler>
+			<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
+				<providerOption name="CompilerVersion" value="v3.5"/>
+				<providerOption name="OptionInfer" value="true"/>
+				<providerOption name="WarnAsError" value="false"/></compiler></compilers>
+	</system.codedom>
+	<system.webServer>
+		<validation validateIntegratedModeConfiguration="false"/>
+		<modules>
+			<remove name="ScriptModule"/>
+			<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></modules>
+		<handlers>
+			<remove name="WebServiceHandlerFactory-Integrated"/>
+			<remove name="ScriptHandlerFactory"/>
+			<remove name="ScriptHandlerFactoryAppServices"/>
+			<remove name="ScriptResource"/>
+			<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+			<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+			<add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></handlers></system.webServer>
+	<runtime>
+		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+			<dependentAssembly>
+				<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
+				<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/></dependentAssembly>
+			<dependentAssembly>
+				<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
+				<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/></dependentAssembly></assemblyBinding></runtime></configuration>
diff --git a/src/FSharp.PowerPack.Unittests/AsyncStreamReaderTest.fs b/src/FSharp.PowerPack.Unittests/AsyncStreamReaderTest.fs
new file mode 100755
index 0000000..5e9222f
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/AsyncStreamReaderTest.fs
@@ -0,0 +1,229 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open System
+open System.IO
+open System.Text
+
+[<TestFixture>]
+type AsyncStreamReaderTest() =
+    
+    let utf8Encoding : Encoding = downcast (new UTF8Encoding()).Clone()
+#if FX_NO_UTF32ENCODING
+#else
+    let utf32Encoding : Encoding = downcast (new UTF32Encoding()).Clone()
+#endif
+#if FX_NO_ASCII_ENCODING
+#else
+    let ASCIIEncoding : Encoding = downcast (new ASCIIEncoding()).Clone()
+    let win1251Encoding : Encoding = downcast (Encoding.GetEncoding("windows-1251")).Clone() // Russian
+#endif    
+    let encodings : (Encoding*bool) list = 
+        [   utf8Encoding, true; 
+#if FX_NO_UTF32ENCODING
+#else
+            utf32Encoding, true; 
+#endif
+#if FX_NO_ASCII_ENCODING
+#else
+            ASCIIEncoding,false; 
+            win1251Encoding,false
+#endif
+        ]
+#if FX_NO_ENCODER_FALLBACK    
+#else
+    do encodings |> List.iter (fun (e,_) -> e.EncoderFallback <- new EncoderExceptionFallback())
+#endif
+        
+        
+    let testAllEncodings (s:string) tester = 
+            for (e,detectable) in encodings do
+            let bytes, encodingOk =
+                try
+                    e.GetBytes(s), true
+                with
+                | :? EncoderFallbackException -> [| |], false
+            if encodingOk then
+                let ms = new MemoryStream(bytes)
+                let reader =  new AsyncStreamReader(ms, e)
+                tester reader (e.ToString())
+                if detectable then
+                    let preamble = e.GetPreamble()
+                    let newBytes = [preamble; bytes] |> Array.concat
+                    let ms = new MemoryStream(newBytes)
+                    let reader =  new AsyncStreamReader(ms)
+                    tester reader (sprintf "detectable %A" e)
+
+    let readToEndAndReadCharTest (s:string) =
+        testAllEncodings s
+            (fun (reader:AsyncStreamReader) encodingDescription ->
+                    let result = reader.ReadToEnd() |> Async.RunSynchronously
+                    Assert.AreEqual(s, result, (sprintf "ReadToEnd failure on %s" encodingDescription))
+                    Assert.IsTrue(reader.EndOfStream |> Async.RunSynchronously, "End of stream reached after ReadToEnd")
+                )
+        testAllEncodings s
+            (fun (reader:AsyncStreamReader) encodingDescription ->
+                let rec readAllChars =
+                    let sb = new StringBuilder()
+                    async {
+                        let! eof = reader.EndOfStream
+                        if eof then return sb.ToString()
+                        else
+                            let! c = reader.Read()
+                            sb.Append(c) |> ignore
+                            return! readAllChars
+                    }
+                let result = readAllChars |> Async.RunSynchronously
+                Assert.AreEqual(s, result, (sprintf "Read-all-charsToEnd failure on %s" encodingDescription))
+                Assert.IsTrue(reader.EndOfStream |> Async.RunSynchronously, "End of stream reached after ReadToEnd")
+            )
+        let readAllUsingBufferOfLength fdesc f n =
+            (fun (reader:AsyncStreamReader) encodingDescription ->
+                let rec readAllChars =
+                    let buffer = Array.create (2*n) ' '
+                    let sb = new StringBuilder()
+                    async {
+                        let! eof = reader.EndOfStream
+                        if eof then return sb.ToString()
+                        else
+                            let! count = f reader (buffer, 0, n)
+                            sb.Append(buffer, 0, count) |> ignore
+                            let! count = f reader (buffer, count, n)
+                            sb.Append(buffer, n, count) |> ignore
+                            return! readAllChars
+                    }
+                let result = readAllChars |> Async.RunSynchronously
+                Assert.AreEqual(s, result, (sprintf "%s buffer of length %d failure on %s" fdesc n encodingDescription))
+                Assert.IsTrue(reader.EndOfStream |> Async.RunSynchronously, sprintf "End of stream reached after %s using buffer of length %d" fdesc n)
+             )
+        for (fdesc,f) in [  "Read",         fun (reader:AsyncStreamReader) (buffer,index,count) -> reader.Read(buffer,index,count)
+                            "ReadExactly",  fun (reader:AsyncStreamReader) (buffer,index,count) -> reader.ReadExactly(buffer,index,count) ] do
+            testAllEncodings s (readAllUsingBufferOfLength fdesc f 1)
+            testAllEncodings s (readAllUsingBufferOfLength fdesc f 1024)
+            testAllEncodings s (readAllUsingBufferOfLength fdesc f 1999)
+            testAllEncodings s (readAllUsingBufferOfLength fdesc f s.Length)
+
+    let textBuilders =
+        [
+            yield "default separators",
+                fun (ss:string list) lastLine ->
+                    let sb = new StringBuilder()
+                    ss |> List.iter (fun s -> sb.AppendLine s |> ignore)
+                    sb.Append (lastLine:string) |> ignore
+                    sb.ToString()
+            for separator in ["\r"; "\n"; "\r\n"] do
+                yield separator.Replace("\r",@"\r").Replace("\n",@"\n"),
+                    fun (ss:string list) lastLine ->
+                        let sb = new StringBuilder()
+                        ss |> List.iter (fun s -> sb.Append s |> ignore; sb.Append separator |> ignore)
+                        sb.Append (lastLine:string) |> ignore
+                        sb.ToString()
+        ]
+   
+   
+    let readLinesTest (ss:string list) lastLine =
+        for (descr,textBuilder) in textBuilders do
+            testAllEncodings (textBuilder ss lastLine)
+                (fun (reader:AsyncStreamReader) encodingDescription ->
+                    let rec r acc = 
+                        async {
+                            let! eof = reader.EndOfStream
+                            if eof then return acc |> List.rev
+                            else
+                                let! nextLine = reader.ReadLine()
+                                return! r (nextLine::acc)
+                        }
+                    let result = r [] |> Async.RunSynchronously
+                    let expectedResult =
+                        if String.IsNullOrEmpty lastLine then ss else ss @ [lastLine]
+                            
+                    if expectedResult <> result then
+                        Assert.Fail(sprintf "ReadLinesTest: builder %s string list mismatch on %s" descr encodingDescription)
+                )
+    
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly on empty stream``() =
+        readToEndAndReadCharTest ""
+        
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly on short stream``() =
+        readToEndAndReadCharTest "fooBar"
+        
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly on multiple of buffer size``() =
+        let chars =
+            [| for i in 1..1024 do
+                    yield '0'
+                    yield '1'
+                    yield '2'
+            |] 
+        readToEndAndReadCharTest (new String(chars))
+
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly on non-multiple of buffer size``() =
+        let chars =
+            [| for i in 1..1024 do
+                    yield '0'
+                    yield '1'
+                    yield '2'
+               yield 'a'
+               yield 'b'
+            |] 
+        readToEndAndReadCharTest (new String(chars))
+        
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly on Russian chars``() =
+       readToEndAndReadCharTest "Однажды в студеную зимнюю пору\r\nЯ из лесу вышел\r\nБыл сильный мороз!"
+       
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly with surrogate codepoints``() =
+      let chars =
+        [| for i in 1..4096 do
+            yield 'a'
+            // surrogate pair
+            yield '\uD800' 
+            yield '\uDC00'
+        |]
+      readToEndAndReadCharTest (new String(chars))
+    
+    [<Test>]
+    member this.``ReadLine on empty file``() =
+        readLinesTest [] "" 
+    
+    [<Test>]
+    member this.``ReadLine with end on end of line``() =
+        readLinesTest ["a";"b";"c"] ""
+
+    [<Test>]
+    member this.``ReadLine with end not on end of line``() =
+        readLinesTest ["a";"b";"c"] "d"
+
+    [<Test>]
+    member this.``ReadLine with EOL mark starting at end-of-buffer``() =
+        readLinesTest
+            [ 
+                new String([|for i in 1..1024 do yield 'x'|])
+                new String([|for i in 1..1024 do yield 'y'|])
+                new String([|for i in 1..1024 do yield 'z'|])
+            ]
+            ""
+
+    [<Test>]
+    member this.``ReadLine with EOL mark breaking at end-of-buffer``() =
+        readLinesTest
+            [ 
+                new String([|for i in 1..1023 do yield 'x'|])
+                new String([|for i in 1..1022 do yield 'y'|])
+                new String([|for i in 1..1022 do yield 'z'|])
+            ]
+            ""
+
+    [<Test>]
+    member this.``ReadLine with EOL mark ending at end-of-buffer``() =
+        readLinesTest
+            [ 
+                new String([|for i in 1..1022 do yield 'x'|])
+                new String([|for i in 1..1022 do yield 'y'|])
+                new String([|for i in 1..1022 do yield 'z'|])
+            ]
+            ""
+
diff --git a/src/FSharp.PowerPack.Unittests/BigRationalTests.fs b/src/FSharp.PowerPack.Unittests/BigRationalTests.fs
new file mode 100755
index 0000000..c60b835
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/BigRationalTests.fs
@@ -0,0 +1,611 @@
+
+namespace FSharp.PowerPack.Unittests
+
+open NUnit.Framework
+open System
+open System.Collections
+open System.Collections.Generic
+open System.Numerics
+
+
+[<TestFixture>]
+type public BigRationalTests() =
+
+    // BigRational Tests
+    // =================
+
+    // Notes: What cases to consider?
+    //   For (p,q) cases q=0, q=1, q<>1. [UPDATE: remove (x,0)]
+    //   For (p,q) when q=1 there could be 2 internal representations, either Z or Q.
+    //   For (p,0) this value can be signed, corresponds to +/- infinity point. [Update: remove it]
+    // Hashes on (p,1) for both representations must agree.
+    // For binary operators, try for result with and without HCF (normalisation).
+    // Also: 0/0 is an acceptable representation. See normalisation code. [Update: remove it].
+
+    // Overrides to test:
+    // .ToString()
+    // .GetHashCode()
+    // .Equals()
+    // IComparable.CompareTo()
+
+    // Misc construction.
+    let natA  n   = BigRational.FromInt n       // internally Z
+    let natB  n   = (natA n / natA 7) * natA 7  // internally Q
+    let ratio p q = BigRational.FromInt p / BigRational.FromInt q
+    let (/%)  b c = BigRational.FromBigInt b / BigRational.FromBigInt c
+
+    // Misc test values
+    let q0 = natA 0
+    let q1 = natA 1
+    let q2 = natA 2
+    let q3 = natA 3
+    let q4 = natA 4
+    let q5 = natA 5
+    let minIntI = bigint System.Int32.MinValue
+    let maxIntI = bigint System.Int32.MaxValue
+    let ran = System.Random()
+    let nextZ n = bigint (ran.Next(n))
+
+    // A selection of test points.
+    let points =
+        // A selection of integer and reciprical points
+        let points =
+            [for i in -13I .. 13I -> i,1I] @
+            [for i in -13I .. 13I -> 1I,i]
+        // Exclude x/0
+        let points = [for p,q in points do if q <> 0I then yield p,q ] // PROPOSE: (q,0) never a valid Q value, filter them out of tests...
+        // Scale by various values, including into BigInt range
+        let scale (kp,kq) (p,q) = (p*kp,q*kq)
+        let scales k pqs = List.map (scale k) pqs
+        let points = List.concat [points;
+                                  scales (10000I,1I) points;
+                                  scales (1I,10000I) points;
+                                  scales (maxIntI,1I) points;
+                                  scales (1I,maxIntI) points;
+                                 ]
+        points
+    let pointsNonZero = [for p,q in points do if p<>0I then yield p,q] // non zero points
+
+    let makeQs p q =     
+        if q = 1I && minIntI <= p && p <= maxIntI then
+            // (p,1) where p is int32
+            let p32 = int32 p
+            [natA p32;natB p32;BigRational.FromBigInt p]   // two reprs for int32 
+        else
+            [BigRational.FromBigInt p / BigRational.FromBigInt q]
+            
+    let miscQs = [for p,q in points do yield! makeQs p q]
+
+    let product xs ys = [for x in xs do for y in ys do yield x,y]
+    let vector1s = [for z in points -> z]
+    let vector2s = product points points
+
+    [<Test>]
+    member this.BasicTests1() = 
+        check "generic format h"  "1N" (sprintf "%A" 1N)
+        check "generic format q"  "-1N" (sprintf "%A" (-1N))
+
+        test "vliwe98"   (id -2N = - 2N)
+        test "d3oc002" (LanguagePrimitives.GenericZero<bignum> = 0N)
+        test "d3oc112w" (LanguagePrimitives.GenericOne<bignum> = 1N)
+
+        check "weioj3h" (sprintf "%O" 3N) "3" 
+        check "weioj3k" (sprintf "%O" (3N / 4N)) "3/4"
+        check "weioj3k" (sprintf "%O" (3N / 400000000N)) "3/400000000"
+        check "weioj3l" (sprintf "%O" (3N / 3N))  "1"
+        check "weioj3q" (sprintf "%O" (-3N))  "-3"
+        //check "weioj3w" (sprintf "%O" -3N) "-3"
+        check "weioj3e" (sprintf "%O" (-3N / -3N)) "1"
+
+        // The reason why we do not use hardcoded values is the the representation may change based on the NetFx we are targeting.
+        // For example, when targeting NetFx4.0, the result is "-3E+61" instead of "-3000....0N"
+        let v = -30000000000000000000000000000000000000000000000000000000000000N
+        check "weioj3r" (sprintf "%O" v) ((box v).ToString())
+
+  
+    [<Test>]
+    member this.BasicTests2() = 
+
+
+        // Test arithmetic ops: tests
+        let test2One name f check ((p,q),(pp,qq)) =     
+            // There may be several ways to construct the test rationals
+            let zs        = makeQs p  q
+            let zzs       = makeQs pp qq
+            let results   = [for z in zs do for zz in zzs do yield f (z,zz)]    
+            let refP,refQ = check (p,q) (pp,qq)    
+            let refResult = BigRational.FromBigInt refP / BigRational.FromBigInt refQ
+            let resOK (result:BigRational) = 
+                result.Numerator * refQ = refP * result.Denominator && 
+                BigRational.Equals(refResult,result)
+            match List.tryFind (fun result -> not (resOK result)) results with
+            | None        -> () // ok
+            | Some result -> printf "Test failed. %s (%A,%A) (%A,%A). Expected %A. Observed %A\n" name p q pp qq refResult result
+                             reportFailure "cejkew09"
+
+        let test2All name f check vectors = List.iter (test2One name f check) vectors
+
+        // Test arithmetic ops: call
+        test2All "add" (BigRational.(+))  (fun (p,q) (pp,qq) -> (p*qq + q*pp,q*qq)) vector2s
+        test2All "sub" (BigRational.(-))  (fun (p,q) (pp,qq) -> (p*qq - q*pp,q*qq)) vector2s
+        test2All "mul" (BigRational.(*))  (fun (p,q) (pp,qq) -> (p*pp,q*qq))        vector2s // *) <-- for EMACS
+        test2All "div" (BigRational.(/))  (fun (p,q) (pp,qq) -> (p*qq,q*pp))        (product points pointsNonZero)
+
+
+  
+    [<Test>]
+    member this.RangeTests() = 
+        // Test x0 .. dx .. x1
+        let checkRange3 (x0:BigRational) dx x1 k =
+            let f (x:BigRational) = x * BigRational.FromBigInt k |> BigRational.ToBigInt
+            let rangeA = {x0 .. dx .. x1} |> Seq.map f
+            let rangeB = {f x0 .. f dx .. f x1}
+            //printf "Length=%d\n" (Seq.length rangeA)
+            let same = Seq.forall2 (=) rangeA rangeB
+            check (sprintf "Range3 %A .. %A .. %A scaled to %A" x0 dx x1 k) same true
+            
+        checkRange3 (0I /% 1I)  (1I /% 7I) (100I /% 1I)  (7I*1I)
+        checkRange3 (0I /% 1I)  (1I /% 7I) (100I /% 11I) (7I*11I)
+        checkRange3 (1I /% 13I) (1I /% 7I) (100I /% 11I) (7I*11I*13I)
+        for i = 0 to 1000 do
+            let m = 1000 // max steps is -m to m in steps of 1/m i.e. 2.m^2
+            let p0,q0 = nextZ m     ,nextZ m + 1I
+            let p1,q1 = nextZ m     ,nextZ m + 1I
+            let pd,qd = nextZ m + 1I,nextZ m + 1I
+            checkRange3 (p0 /% q0) (pd /% qd) (p1 /% q1) (q0 * q1 * qd)
+
+
+        // Test x0 .. x1
+        let checkRange2 (x0:BigRational) x1 =
+            let z0  = BigRational.ToBigInt x0
+            let z01 = BigRational.ToBigInt (x1 - x0)    
+            let f (x:BigRational) = x |> BigRational.ToBigInt
+            let rangeA = [x0 .. x1] |> List.map f       // range with each item rounded down
+            let rangeB = [z0 .. z0 + z01]               // range of same length from the round down start point
+            check (sprintf "Range2: %A .. %A" x0 x1) rangeA rangeB
+
+        checkRange2 (0I /% 1I)  (100I /% 1I)  
+        checkRange2 (0I /% 1I)  (100I /% 11I) 
+        checkRange2 (1I /% 13I) (100I /% 11I) 
+        for i = 0 to 1000 do
+            let m = 10000 // max steps is -m to m in steps of 1 i.e. 2.m
+            let p0,q0 = nextZ m     ,nextZ m + 1I
+            let p1,q1 = nextZ m     ,nextZ m + 1I
+            checkRange2 (p0 /% q0) (p1 /% q1) //(q0 * q1 * qd)
+
+        // ToString()
+        // Cases: integer, computed integer, rational<1, rational>1, +/-infinity, nan
+        (natA 1).ToString()     |> check "ToString" "1" 
+        (natA 0).ToString()     |> check "ToString"  "0"
+        (natA (-12)).ToString() |> check "ToString" "-12"
+        (natB 1).ToString()     |> check "ToString" "1"
+        (natB 0).ToString()     |> check "ToString" "0"
+        (natB (-12)).ToString() |> check "ToString" "-12"
+        (1I /% 3I).ToString()   |> check "ToString" "1/3"
+        (12I /% 5I).ToString()  |> check "ToString" "12/5"
+        //(13I /% 0I).ToString()  |> check "ToString" "1/0"     // + 1/0. Plan to make this invalid value
+        //(-13I /% 0I).ToString() |> check "ToString" "1/0"     // - 1/0. Plan to make this invalid value
+        //(0I /% 0I).ToString()   |> check "ToString" "0/0"     //   0/0. Plan to make this invalid value
+
+        // GetHashCode
+        // Cases: zero, integer, computed integer, computed by multiple routes.
+        let checkSameHashGeneric a b                      = check (sprintf "GenericHash     %A %A" a b) (a.GetHashCode()) (b.GetHashCode())
+        let checkSameHash (a:BigRational) (b:BigRational) = check (sprintf "BigRationalHash %A %A" a b)  (a.GetHashCode()) (b.GetHashCode()); checkSameHashGeneric a b
+
+        List.iter (fun n -> checkSameHash (natA n) (natB n)) [-10 .. 10]
+        List.iter (fun n -> checkSameHash n ((n * q3 + n * q2) / q5)) miscQs
+
+        // bug 3488: should non-finite values be supported?
+        //let x = BigRational.FromBigInt (-1I) / BigRational.FromBigInt 0I
+        //let q2,q3,q5 = BigRational.FromInt 2,BigRational.FromInt 3,BigRational.FromInt 5
+        //let x2 = (x * q2 + x * q3) / q5
+        //x,x2,x = x2
+
+        // Test: Zero,One?
+        check "ZeroA" BigRational.Zero (natA 0)
+        check "ZeroA" BigRational.Zero (natA 0)
+        check "OneA"  BigRational.One  (natB 1)
+        check "OneB"  BigRational.One  (natB 1)
+
+    [<Test>]
+    member this.BinaryAndUnaryOperators() = 
+        // Test: generic bop
+        let testR2One name f check ((p,q),(pp,qq)) =     
+            // There may be several ways to construct the test rationals
+            let zs        = makeQs p  q
+            let zzs       = makeQs pp qq
+            let resultRef = check (p,q) (pp,qq) // : bool    
+            let args      = [for z in zs do for zz in zzs do yield (z,zz)]    
+            match List.tryFind (fun (z,zz) -> resultRef <> f (z,zz)) args with
+            | None        -> () // ok
+            | Some (z,zz) -> printf "Test failed. %s (%A,%A) (%A,%A) = %s %A %A. Expected %A.\n" name p q pp qq name z zz resultRef
+                             reportFailure "cknwe9"
+
+        // Test: generic uop
+        let testR1One name f check (p,q) =     
+            // There may be several ways to construct the test rationals
+            let zs        = makeQs p  q    
+            let resultRef = check (p,q) //: bool        
+            match List.tryFind (fun z -> resultRef <> f z) zs with
+            | None   -> () // ok
+            | Some z -> printf "Test failed. %s (%A,%A) = %s %A. Expected %A.\n" name p q name z resultRef
+                        reportFailure "vekjkrejvre0"
+                             
+        let testR2All name f check vectors = List.iter (testR2One name f check) vectors
+        let testR1All name f check vectors = List.iter (testR1One name f check) vectors
+
+        // Test: relations
+        let sign (i:BigInteger) = BigInteger(i.Sign)
+        testR2All "="  BigRational.(=)           (fun (p,q) (pp,qq) -> (p*qq =  q*pp)) vector2s
+        testR2All "="  BigRational.op_Equality   (fun (p,q) (pp,qq) -> (p*qq =  q*pp)) vector2s
+        testR2All "!=" BigRational.op_Inequality (fun (p,q) (pp,qq) -> (p*qq <> q*pp)) vector2s
+        //     p/q < pp/qq
+        // iff (p * sign q) / (q  * sign q)  < (pp * sign qq) / (qq * sign qq)
+        // iff (p * sign q) * (qq * sign qq) < (pp * sign qq) * (q  * sign q)           since q*sign q is always +ve.
+        testR2All "<"  BigRational.(<)  (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) < (pp * sign qq) * (q * sign q)) vector2s
+        testR2All ">"  BigRational.(>)  (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) > (pp * sign qq) * (q * sign q)) vector2s
+        testR2All "<=" BigRational.(<=) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) <= (pp * sign qq) * (q * sign q)) vector2s
+        testR2All ">=" BigRational.(>=) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) >= (pp * sign qq) * (q * sign q)) vector2s
+
+        // System.IComparable tests
+        let BigRationalCompareTo (p:BigRational,q:BigRational) = (p :> System.IComparable).CompareTo(q)
+        testR2All "IComparable.CompareTo" BigRationalCompareTo (fun (p,q) (pp,qq) -> compare ((p * sign q) * (qq * sign qq)) ((pp * sign qq) * (q * sign q))) vector2s
+
+        // Test: is negative, is positive
+        testR1All "IsNegative" (fun (x:BigRational) -> x.IsNegative) (fun (p,q) -> sign p * sign q = -1I) vector1s
+        testR1All "IsPositive" (fun (x:BigRational) -> x.IsPositive) (fun (p,q) -> sign p * sign q =  1I) vector1s
+        testR1All "IsZero"     (fun (x:BigRational) -> x = q0)       (fun (p,q) -> sign p = 0I)           vector1s
+
+
+        let test1One name f check (p,q) =     
+            // There may be several ways to construct the test rationals
+            let zs        = makeQs p  q    
+            let results   = [for z in zs -> f z]
+            let refP,refQ = check (p,q)   
+            let refResult = BigRational.FromBigInt refP / BigRational.FromBigInt refQ
+            let resOK (result:BigRational) = 
+               result.Numerator * refQ = refP * result.Denominator && 
+               BigRational.Equals(refResult,result)
+            match List.tryFind (fun result -> not (resOK result)) results with
+            | None        -> () // ok
+            | Some result -> printf "Test failed. %s (%A,%A). Expected %A. Observed %A\n" name p q refResult result
+                             reportFailure "klcwe09wek"
+
+        let test1All name f check vectors = List.iter (test1One name f check) vectors
+  
+        test1All "neg" (BigRational.(~-)) (fun (p,q)         -> (-p,q))             vector1s
+        test1All "pos" (BigRational.(~+)) (fun (p,q)         -> (p,q))              vector1s // why have ~+ ???
+
+        // Test: Abs,Sign
+        test1All  "Abs"         (BigRational.Abs)     (fun (p,q) -> (abs p,abs q)) vector1s
+        testR1All "Sign"        (fun (x:BigRational) -> x.Sign)    (fun (p,q) -> check "NonZeroDenom" (sign q <> 0I) true; (sign p * sign q) |> int32) vector1s
+
+        // Test: PowN
+        test1All  "PowN(x,2)"   (fun x -> BigRational.PowN(x,2))   (fun (p,q) -> (p*p,q*q)) vector1s
+        test1All  "PowN(x,1)"   (fun x -> BigRational.PowN(x,1))   (fun (p,q) -> (p,q)) vector1s
+        test1All  "PowN(x,0)"   (fun x -> BigRational.PowN(x,0))   (fun (p,q) -> (1I,1I)) vector1s
+
+        // MatteoT: moved to numbersVS2008\test.ml
+        //test1All  "PowN(x,200)" (fun x -> BigRational.PowN(x,200)) (fun (p,q) -> (BigInteger.Pow(p,200I),BigInteger.Pow(q,200I))) vector1s
+
+        // MatteoT: moved to numbersVS2008\test.ml
+        //let powers = [0I .. 100I]
+        //powers |> List.iter (fun i -> test1All  "PowN(x,i)" (fun x -> BigRational.PowN(x,int i)) (fun (p,q) -> (BigInteger.Pow(p,i),BigInteger.Pow(q,i))) vector1s)
+
+        // Test: PowN with negative powers - expect exception
+        testR1All  "PowN(x,-1)"  (fun x -> throws (fun () -> BigRational.PowN(x,-1))) (fun (p,q) -> true) vector1s
+        testR1All  "PowN(x,-4)"  (fun x -> throws (fun () -> BigRational.PowN(x,-4))) (fun (p,q) -> true) vector1s
+
+
+
+[<TestFixture>]
+type BigNumType() =
+    let g_positive1 = 1000000000000000000000000000000000018N
+    let g_positive2 = 1000000000000000000000000000000000000N
+    let g_negative1 = -1000000000000000000000000000000000018N
+    let g_negative2 = -1000000000000000000000000000000000000N
+    let g_negative3 = -1000000000000000000000000000000000036N
+    let g_zero      = 0N
+    let g_normal    = 88N
+    let g_bigintpositive    = 1000000000000000000000000000000000018I
+    let g_bigintnegative    = -1000000000000000000000000000000000018I
+    
+    // Interfaces
+    [<Test>]
+    member this.IComparable() =        
+        // Legit IC
+        let ic = g_positive1 :> IComparable    
+        Assert.AreEqual(ic.CompareTo(g_positive1),0) 
+        checkThrowsArgumentException( fun () -> ic.CompareTo(g_bigintpositive) |> ignore)
+    
+    // Base class methods
+    [<Test>]
+    member this.ObjectToString() =
+    
+        // Currently the CLR 4.0 and CLR 2.0 behavior of BigInt.ToString is different, causing this test to fail.
+        
+        Assert.AreEqual(g_positive1.ToString(),
+                        "1000000000000000000000000000000000018")
+        Assert.AreEqual(g_zero.ToString(),"0") 
+        Assert.AreEqual(g_normal.ToString(),"88")
+        
+        
+    [<Test; Ignore("Bug 5286 - Differences between CLR 2.0 BigInt and CLR 4.0 BigInt")>]
+    member this.System_Object_GetHashCode() =
+        Assert.AreEqual(g_negative1.GetHashCode(),1210897093)
+        Assert.AreEqual(g_normal.GetHashCode(),89)
+        Assert.AreEqual(g_zero.GetHashCode(),1)
+        ()
+    
+    // Static methods    
+    [<Test>]
+    member this.Abs() =
+        Assert.AreEqual(bignum.Abs(g_negative1), g_positive1)
+        Assert.AreEqual(bignum.Abs(g_negative2), g_positive2)
+        Assert.AreEqual(bignum.Abs(g_positive1), g_positive1)
+        Assert.AreEqual(bignum.Abs(g_normal),    g_normal)
+        Assert.AreEqual(bignum.Abs(g_zero),      g_zero)
+        ()
+        
+    [<Test>]
+    member this.FromBigInt() =
+        Assert.AreEqual(bignum.FromBigInt(g_bigintpositive),
+                        g_positive1)
+        Assert.AreEqual(bignum.FromBigInt(g_bigintnegative),
+                        g_negative1)
+        Assert.AreEqual(bignum.FromBigInt(0I),g_zero)
+        Assert.AreEqual(bignum.FromBigInt(88I),g_normal)
+        ()
+    
+    [<Test>]
+    member this.FromInt() =
+        Assert.AreEqual(bignum.FromInt(2147483647),   2147483647N)
+        Assert.AreEqual(bignum.FromInt(-2147483648), -2147483648N)
+        Assert.AreEqual(bignum.FromInt(0),   0N)
+        Assert.AreEqual(bignum.FromInt(88), 88N)
+        ()
+        
+    [<Test>]
+    member this.One() =
+        Assert.AreEqual(bignum.One,1N)
+        ()
+    
+    [<Test>]
+    member this.Parse() =
+        Assert.AreEqual(bignum.Parse("100"),   100N)
+        Assert.AreEqual(bignum.Parse("-100"), -100N)
+        Assert.AreEqual(bignum.Parse("0"),     g_zero)
+        Assert.AreEqual(bignum.Parse("88"),    g_normal)
+        ()
+        
+    [<Test>]
+    member this.PowN() =
+        Assert.AreEqual(bignum.PowN(100N,2), 10000N)
+        Assert.AreEqual(bignum.PowN(-3N,3),  -27N)
+        Assert.AreEqual(bignum.PowN(g_zero,2147483647), 0N)
+        Assert.AreEqual(bignum.PowN(g_normal,0),        1N)
+        ()
+        
+        
+    [<Test>]
+    member this.Sign() =
+        Assert.AreEqual(g_positive1.Sign,  1)
+        Assert.AreEqual(g_negative1.Sign, -1)
+        Assert.AreEqual(g_zero.Sign,   0)
+        Assert.AreEqual(g_normal.Sign, 1)
+        ()
+        
+    
+        
+    [<Test>]
+    member this.ToBigInt() =
+        Assert.AreEqual(bignum.ToBigInt(g_positive1), g_bigintpositive)
+        Assert.AreEqual(bignum.ToBigInt(g_negative1), g_bigintnegative)
+        Assert.AreEqual(bignum.ToBigInt(g_zero),   0I)
+        Assert.AreEqual(bignum.ToBigInt(g_normal), 88I)
+        ()
+        
+    
+        
+    [<Test>]
+    member this.ToDouble() =
+        Assert.AreEqual(bignum.ToDouble(179769N*1000000000000000N),   1.79769E+20)
+        Assert.AreEqual(bignum.ToDouble(-179769N*1000000000000000N), -1.79769E+20)
+        Assert.AreEqual(bignum.ToDouble(0N),0.0)
+        Assert.AreEqual(bignum.ToDouble(88N),88.0)
+        Assert.AreEqual(double(179769N*1000000000000000N),   1.79769E+20)
+        Assert.AreEqual(double(-179769N*1000000000000000N), -1.79769E+20)
+        Assert.AreEqual(double(0N),0.0)
+        Assert.AreEqual(double(88N),88.0)
+        ()
+        
+        
+    [<Test>]
+    member this.ToInt32() =
+        Assert.AreEqual(bignum.ToInt32(2147483647N),   2147483647)
+        Assert.AreEqual(bignum.ToInt32(-2147483648N), -2147483648)
+        Assert.AreEqual(bignum.ToInt32(0N),  0)
+        Assert.AreEqual(bignum.ToInt32(88N), 88)
+        Assert.AreEqual(int32(2147483647N),   2147483647)
+        Assert.AreEqual(int32(-2147483648N), -2147483648)
+        Assert.AreEqual(int32(0N),  0)
+        Assert.AreEqual(int32(88N), 88)
+        
+    
+        
+    [<Test>]
+    member this.Zero() =
+        Assert.AreEqual(bignum.Zero,0N)
+        ()
+       
+    // operator methods  
+    [<Test>]
+    member this.test_op_Addition() =
+        
+        Assert.AreEqual(100N + 200N, 300N)
+        Assert.AreEqual((-100N) + (-200N), -300N)
+        Assert.AreEqual(g_positive1 + g_negative1, 0N)
+        Assert.AreEqual(g_zero + g_zero,0N)
+        Assert.AreEqual(g_normal + g_normal, 176N)
+        Assert.AreEqual(g_normal + g_normal, 176N)
+        ()
+        
+        
+        
+    [<Test>]
+    member this.test_op_Division() =
+        Assert.AreEqual(g_positive1 / g_positive1, 1N)
+        Assert.AreEqual(-100N / 2N, -50N)
+        Assert.AreEqual(g_zero / g_positive1, 0N)
+        ()
+        
+    [<Test>]
+    member this.test_op_Equality() =
+        
+        Assert.IsTrue((g_positive1 = g_positive1))
+        Assert.IsTrue((g_negative1 = g_negative1))
+        Assert.IsTrue((g_zero = g_zero))
+        Assert.IsTrue((g_normal = g_normal))
+        ()
+        
+    [<Test>]
+    member this.test_op_GreaterThan() = 
+        Assert.AreEqual((g_positive1 > g_positive2), true)
+        Assert.AreEqual((g_negative1 > g_negative2), false)
+        Assert.AreEqual((g_zero > g_zero), false)
+        Assert.AreEqual((g_normal > g_normal), false)
+        
+        
+        ()
+    [<Test>]
+    member this.test_op_GreaterThanOrEqual() = 
+        Assert.AreEqual((g_positive1 >= g_positive2), true)
+        Assert.AreEqual((g_positive2 >= g_positive1), false)                                             
+        Assert.AreEqual((g_negative1 >= g_negative1), true)
+        Assert.AreEqual((0N >= g_zero), true)
+        
+        ()
+    [<Test>]  
+    member this.test_op_LessThan() = 
+        Assert.AreEqual((g_positive1 < g_positive2), false)
+        Assert.AreEqual((g_negative1 < g_negative3), false)
+        Assert.AreEqual((0N < g_zero), false)
+        
+        ()
+    [<Test>]
+    member this.test_op_LessThanOrEqual() = 
+        Assert.AreEqual((g_positive1 <= g_positive2), false)
+        Assert.AreEqual((g_positive2 <= g_positive1), true)                                             
+        Assert.AreEqual((g_negative1 <= g_negative1), true)
+        Assert.AreEqual((0N <= g_zero), true)
+       
+        ()
+    
+    [<Test>]
+    member this.test_op_Multiply() = 
+        Assert.AreEqual(3N * 5N, 15N)
+        Assert.AreEqual((-3N) * (-5N), 15N)
+        Assert.AreEqual((-3N) * 5N, -15N)
+        Assert.AreEqual(0N * 5N, 0N)
+        
+        ()
+        
+    [<Test>]
+    member this.test_op_Range() = 
+        let resultPos = [0N .. 2N]
+        let seqPos    = [0N; 1N; 2N]                                                                
+        verifySeqsEqual resultPos seqPos
+        
+        let resultNeg = [-2N .. 0N]                                       
+        let seqNeg =  [-2N; -1N; 0N]  
+        verifySeqsEqual resultNeg seqNeg
+        
+        let resultSmall = [0N ..5N]
+        let seqSmall = [0N; 1N; 2N; 3N; 4N; 5N]        
+        verifySeqsEqual resultSmall seqSmall
+           
+        ()
+        
+        
+    [<Test>]
+    member this.test_op_RangeStep() = 
+        let resultPos = [0N .. 3N .. 6N]
+        let seqPos    = [0N; 3N; 6N]                                                                
+        verifySeqsEqual resultPos seqPos
+        
+        let resultNeg = [-6N .. 3N .. 0N]                                        
+        let seqNeg =  [-6N; -3N; 0N]  
+        verifySeqsEqual resultNeg seqNeg
+        
+        let resultSmall = [0N .. 3N .. 9N]
+        let seqSmall = [0N; 3N; 6N; 9N]        
+        verifySeqsEqual resultSmall seqSmall
+                   
+        ()
+        
+    [<Test>]
+    member this.test_op_Subtraction() = 
+        Assert.AreEqual(g_positive1 - g_positive2,18N)
+        Assert.AreEqual(g_negative1 - g_negative3,18N)
+        Assert.AreEqual(0N-g_positive1, g_negative1)
+        ()
+        
+    [<Test>]
+    member this.test_op_UnaryNegation() = 
+        Assert.AreEqual(-g_positive1, g_negative1)
+        Assert.AreEqual(-g_negative1, g_positive1)
+        Assert.AreEqual(-0N,0N) 
+        
+        ()
+        
+    [<Test>]
+    member this.test_op_UnaryPlus() = 
+        Assert.AreEqual(+g_positive1,g_positive1)
+        Assert.AreEqual(+g_negative1,g_negative1)
+        Assert.AreEqual(+0N, 0N)
+        
+        ()
+    
+    // instance methods
+    [<Test>]
+    member this.Denominator() = 
+        Assert.AreEqual(g_positive1.Denominator, 1I)
+        Assert.AreEqual(g_negative1.Denominator, 1I)
+        Assert.AreEqual(0N.Denominator, 1I)
+        
+        ()       
+    
+    [<Test>]
+    member this.IsNegative() = 
+        Assert.IsFalse(g_positive1.IsNegative)
+        Assert.IsTrue(g_negative1.IsNegative)
+
+        Assert.IsFalse( 0N.IsNegative)
+        Assert.IsFalse(-0N.IsNegative)
+        
+        () 
+        
+        
+    [<Test>]
+    member this.IsPositive() = 
+
+        Assert.IsTrue(g_positive1.IsPositive)
+        Assert.IsFalse(g_negative1.IsPositive)
+
+        Assert.IsFalse( 0N.IsPositive)
+        Assert.IsFalse(-0N.IsPositive)
+        
+        ()     
+        
+    [<Test>]
+    member this.Numerator() = 
+        Assert.AreEqual(g_positive1.Numerator, g_bigintpositive)
+        Assert.AreEqual(g_negative1.Numerator, g_bigintnegative)
+        Assert.AreEqual(0N.Numerator, 0I)
+        
+        ()  
+        
+    
+        
+        
+   
diff --git a/src/FSharp.PowerPack.Unittests/ColllectionTests.fs b/src/FSharp.PowerPack.Unittests/ColllectionTests.fs
new file mode 100755
index 0000000..15e0f96
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ColllectionTests.fs
@@ -0,0 +1,185 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+
+
+[<TestFixture>]
+type public ResizeArrayTests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+        let ra = ResizeArray.ofList
+        let (=?) a b = ResizeArray.toList a = b
+
+        test "ra_exists2_a" <| ResizeArray.exists2 (=)
+            (ra [1; 2; 3; 4; 5; 6])
+            (ra [2; 3; 4; 5; 6; 6])
+
+        test "exists2_b" <| not (ResizeArray.exists2 (=)
+            (ra [1; 2; 3; 4; 5; 6])
+            (ra [2; 3; 4; 5; 6; 7]))
+
+        test "ra_findIndex_a"
+            (ResizeArray.findIndex (fun i -> i >= 4) (ra [0..10]) = 4)
+
+        test "ra_findIndex_b"
+            (try ResizeArray.findIndex (fun i -> i >= 20) (ra [0..10]) |> ignore; false
+             with _ -> true)
+       
+        test "ra_find_indexi_a"
+            (ResizeArray.findIndexi (=) (ra [1; 2; 3; 3; 2; 1]) = 3)
+
+        test "ra_find_indexi_b"
+            (try ResizeArray.findIndexi (=) (ra [1..10]) |> ignore; false
+             with _ -> true)
+
+        test "ra_forall2_a"
+            (ResizeArray.forall2 (=) (ra [1..10]) (ra [1..10]))
+
+        test "ra_forall2_b" <| not
+            (ResizeArray.forall2 (=) (ra [1;2;3;4;5]) (ra [1;2;3;0;5]))
+
+        test "ra_isEmpty_a"
+            (ResizeArray.isEmpty (ra []))
+
+        test "ra_isEmpty_b" <| not
+            (ResizeArray.isEmpty (ra [1; 2]))
+
+        test "ra_mapi2"
+            (ResizeArray.mapi2 (fun i j k -> i+j+k) (ra [1..10]) (ra [1..10]) =? [2..+3..29])
+
+        test "ra_mapi2_b"
+            (try ResizeArray.mapi2 (fun i j k -> i+j+k) (ra []) (ra [1..10]) |> ignore; false
+             with _ -> true)
+
+        let c = ref 0
+        ResizeArray.iteri2 (fun i j k -> c := !c+i+j+k) (ra [1;2;3]) (ra [10;20;30])
+        test "ra_iteri2" (!c = 6+60+3)
+
+        test "ra_singleton"
+            (ResizeArray.singleton 42 =? [42])
+
+        test "ra_zip"
+            (ResizeArray.zip (ra [1..10]) (ra [1..10]) =? [for i in 1..10 -> i, i])
+
+        let unzip1, unzip2 = ResizeArray.unzip <| ra [for i in 1..10 -> i, i+1]
+        test "ra_unzip" (unzip1 =? [1..10] && unzip2 =? [2..11])
+
+        test "ra_reduce_left"
+            (ResizeArray.reduce (+) (ra [2;2;2;2]) = 8)
+
+        test "ra_reduce_right"
+            (ResizeArray.reduceBack (+) (ra [2;2;2;2]) = 8)
+
+        test "ra_fold2"
+            (ResizeArray.fold2 (fun i j k -> i+j+k) 100 (ra [1;2;3]) (ra [1;2;3]) = 112)
+
+        test "ra_fold2_b"
+            (ResizeArray.fold2 (fun i j k -> i-j-k) 100 (ra [1;2;3]) (ra [1;2;3]) = 100-12)
+
+        test "ra_foldBack2"
+            (ResizeArray.foldBack2 (fun i j k -> i+j+k) (ra [1;2;3]) (ra [1;2;3]) 100 = 112)
+
+        test "ra_foldBack2_b"
+            (ResizeArray.foldBack2 (fun i j k -> k-i-j) (ra [1;2;3]) (ra [1;2;3]) 100 = 100-12)
+
+        test "ra_scan"
+            (ResizeArray.scan (+) 0 (ra [1..5]) =? [0; 1; 3; 6; 10; 15])
+
+        test "ra_scanBack"
+            (ResizeArray.scanBack (+) (ra [1..5]) 0 =? [15; 14; 12; 9; 5; 0])
+
+        test "ra_tryfind_index"
+            (ResizeArray.tryFindIndex (fun x -> x = 4) (ra [0..10]) = Some 4)
+
+        test "ra_tryfind_index_b"
+            (ResizeArray.tryFindIndex (fun x -> x = 42) (ra [0..10]) = None)
+
+        test "ra_tryfind_indexi"
+            (ResizeArray.tryFindIndexi (=) (ra [1;2;3;4;4;3;2;1]) = Some 4)
+
+        test "ra_tryfind_indexi_b"
+            (ResizeArray.tryFindIndexi (=) (ra [1..10]) = None)
+
+        c := -1
+        ResizeArray.iter (fun x -> incr c; test "ra_iter" (x = !c)) (ra [0..100])
+        test "ra_iter" (!c = 100)
+
+        test "ra_map"
+            (ra [1..100] |> ResizeArray.map ((+) 1) =? [2..101])
+
+        test "ra_mapi"
+            (ra [0..100] |> ResizeArray.mapi (+) =? [0..+2..200])
+
+        c := -1
+        ResizeArray.iteri (fun i x -> incr c; test "ra_iteri" (x = !c && i = !c)) (ra [0..100])
+        test "ra_iteri" (!c = 100)
+
+        test "ra_exists"
+            (ra [1..100] |> ResizeArray.exists ((=) 50))
+
+        test "ra_exists b" <| not
+            (ra [1..100] |> ResizeArray.exists ((=) 150))
+
+        test "ra_forall"
+            (ra [1..100] |> ResizeArray.forall (fun x -> x < 150))
+
+        test "ra_forall b" <| not
+            (ra [1..100] |> ResizeArray.forall (fun x -> x < 80))
+
+        test "ra_find"
+            (ra [1..100] |> ResizeArray.find (fun x -> x > 50) = 51)
+
+        test "ra_find b"
+            (try ra [1..100] |> ResizeArray.find (fun x -> x > 180) |> ignore; false
+             with _ -> true)
+
+        test "ra_first"
+            (ra [1..100] |> ResizeArray.tryPick (fun x -> if x > 50 then Some (x*x) else None) = Some (51*51))
+
+        test "ra_first b"
+            (ra [1..100] |> ResizeArray.tryPick (fun x -> None) = None)
+            
+        test "ra_first c"
+            (ra [] |> ResizeArray.tryPick (fun _ -> Some 42) = None)
+
+        test "ra_tryfind"
+            (ra [1..100] |> ResizeArray.tryFind (fun x -> x > 50) = Some 51)
+
+        test "ra_tryfind b"
+            (ra [1..100] |> ResizeArray.tryFind (fun x -> x > 180) = None)
+
+        c := -1
+        ResizeArray.iter2 (fun x y -> incr c; test "ra_iter2" (!c = x && !c = y)) (ra [0..100]) (ra [0..100])
+        test "ra_iter2" (!c = 100)
+
+        test "ra_map2"
+            (ResizeArray.map2 (+) (ra [0..100]) (ra [0..100]) =? [0..+2..200])
+
+        test "ra_choose"
+            (ResizeArray.choose (fun x -> if x % 2 = 0 then Some (x/2) else None) (ra [0..100]) =? [0..50])
+
+        test "ra_filter"
+            (ResizeArray.filter (fun x -> x % 2 = 0) (ra [0..100]) =? [0..+2..100])
+
+        test "ra_filter b"
+            (ResizeArray.filter (fun x -> false) (ra [0..100]) =? [])
+
+        test "ra_filter c"
+            (ResizeArray.filter (fun x -> true) (ra [0..100]) =? [0..100])
+
+        let p1, p2 = ResizeArray.partition (fun x -> x % 2 = 0) (ra [0..100])
+        test "ra_partition"
+            (p1 =? [0..+2..100] && p2 =? [1..+2..100])
+
+        test "ra_rev"
+            (ResizeArray.rev (ra [0..100]) =? [100..-1 ..0])
+
+        test "ra_rev b"
+            (ResizeArray.rev (ra [1]) =? [1])
+
+        test "ra_rev c"
+            (ResizeArray.rev (ra []) =? [])
+
+        test "ra_rev d"
+            (ResizeArray.rev (ra [1; 2]) =? [2; 1])
+
diff --git a/src/FSharp.PowerPack.Unittests/CompatTests.fs b/src/FSharp.PowerPack.Unittests/CompatTests.fs
new file mode 100755
index 0000000..a7de29f
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/CompatTests.fs
@@ -0,0 +1,792 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open System.Collections.Generic
+
+exception Foo
+
+#nowarn "44"
+
+[<TestFixture>]
+type public ArrayTests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+        let test_mem () = 
+          test "array.contains a" (not (Array.contains 3 [| 1; 2; 4 |]))
+          test "array.contains b" (Array.contains 3 [| 1; 3; 4 |])
+
+        let test_make_matrix () = 
+          let arr = Array.createJaggedMatrix 2 3 6 in
+          test "test2931: sdvjk2" (arr.[0].[0] = 6);
+          test "test2931: sdvjk2" (arr.[0].[1] = 6);
+          test "test2931: sdvjk2" (arr.[0].[2] = 6);
+          test "test2931: sdvjk2" (arr.[1].[0] = 6);
+          test "test2931: sdvjk2" (arr.[1].[1] = 6);
+          test "test2931: sdvjk2" (arr.[1].[2] = 6);
+          arr.[0].[0] <- 5;
+          arr.[0].[1] <- 5;
+          arr.[0].[2] <- 5;
+          arr.[1].[0] <- 4;
+          arr.[1].[1] <- 5;
+          arr.[1].[2] <- 5;
+          test "test2931: sdvjk2" (arr.[1].[0] = 4)
+
+        test_make_matrix ()
+        test_mem ()
+
+[<TestFixture>]
+type public ``Byte``() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+
+      test "vwknjewv0" (Byte.zero = 0uy);
+      test "vwknjewv0"  (Byte.add 0uy Byte.one = Byte.one);
+      test  "vwknjewv0" (Byte.add Byte.one 0uy  = Byte.one);
+      test  "vwknjewv0" (Byte.sub Byte.one 0uy  = Byte.one);
+      test  "vwknjewv0" (Byte.sub Byte.one Byte.one  = 0uy);
+      for i = 0 to 255 do 
+        test  "vwknjewv0" (int (byte i) = i);
+      for i = 0 to 255 do 
+        test  "vwknjewv0" (byte i = byte i);
+      stdout.WriteLine "mul i 1";
+      for i = 0 to 255 do 
+        test  "vwknjewv0"  (Byte.mul (byte i) (byte 1) = byte i);
+      stdout.WriteLine "add";
+      for i = 0 to 255 do 
+        for j = 0 to 255 do 
+          test  "vwknjewv0"  (int (Byte.add (byte i) (byte j)) = ((i + j) % 256));
+      stdout.WriteLine "mul i 1";
+      for i = 0 to 49032 do 
+        test  "vwknjewv0"  (int (byte i) = (i % 256));
+      for i = 0 to 255 do 
+        test  "vwknjewv0"  (Byte.div (byte i) (byte 1) = byte i);
+      for i = 0 to 255 do 
+        test  "vwknjewv0"  (Byte.rem (byte i) (byte 1) = byte 0);
+      for i = 0 to 254 do 
+        test  "vwknjewv0"  (Byte.succ (byte i) = Byte.add (byte i) Byte.one);
+      for i = 1 to 255 do 
+        test  "vwknjewv0"  (Byte.pred (byte i) = Byte.sub (byte i) Byte.one);
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test  "vwknjewv0"  (int (Byte.logand (byte i) (byte j)) = (&&&) i j);
+      stdout.WriteLine "logor";
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test  "vwknjewv0"  (int (Byte.logor (byte i) (byte j)) = (|||) i j);
+      stdout.WriteLine "logxor";
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test  "vwknjewv0"  (int (Byte.logxor (byte i) (byte j)) = (^^^) i j);
+      stdout.WriteLine "lognot";
+      for i = 1 to 255 do 
+          test  "vwknjewv0"  (Byte.lognot (byte i) = byte (~~~ i))
+      stdout.WriteLine "shift_left";
+      for i = 0 to 255 do 
+        for j = 0 to 7 do 
+          test  "vwknjewv0"  (Byte.shift_left (byte i) j = byte ( i <<< j))
+      stdout.WriteLine "shift_right";
+      for i = 0 to 255 do 
+        for j = 0 to 7 do 
+          test  "vwknjewv0"  (Byte.shift_right (byte i) j = byte (i >>> j))
+      stdout.WriteLine "to_string";
+      for i = 0 to 255 do 
+          test  "vwknjewv0"  (Byte.to_string (byte i) = sprintf "%d" i)
+      stdout.WriteLine "of_string";
+      for i = 0 to 255 do 
+          test  "vwknjewv0"  (Byte.of_string (string i) = byte i)
+      stdout.WriteLine "done";
+      ()    
+
+
+[<TestFixture>]
+type public Int32Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+      test "test1" (Int32.zero = Int32.zero);
+      test "test2" (Int32.add Int32.zero Int32.one = Int32.one);
+      test "test3" (Int32.add Int32.one Int32.zero  = Int32.one);
+      test "test4" (Int32.sub Int32.one Int32.zero  = Int32.one);
+      test "test5" (Int32.sub Int32.one Int32.one  = Int32.zero);
+      for i = 0 to 255 do 
+        test "test6" (Int32.to_int (Int32.of_int i) = i);
+      done;
+      for i = 0 to 255 do 
+        test "test7" (Int32.of_int i = Int32.of_int i);
+      done;
+      stdout.WriteLine "mul i 1";
+      for i = 0 to 255 do 
+        test "test8" (Int32.mul (Int32.of_int i) (Int32.of_int 1) = Int32.of_int i);
+      done;
+      stdout.WriteLine "add";
+      for i = 0 to 255 do 
+        for j = 0 to 255 do 
+          test "test" (Int32.to_int (Int32.add (Int32.of_int i) (Int32.of_int j)) = (i + j));
+        done;
+      done;
+      stdout.WriteLine "constants: min_int"; stdout.Flush();
+      test "testq" (Int32.min_int = -2147483648);
+      test "testw" (Int32.min_int = -2147483647 - 1);
+
+      stdout.WriteLine "constants: max_int";stdout.Flush();
+      test "teste" (Int32.max_int = 2147483647);
+      test "testr" (Int32.max_int = 2147483646 + 1);
+
+      stdout.WriteLine "constants: string max_int";stdout.Flush();
+      test "testt" (string Int32.max_int = "2147483647");
+      test "testy" (string Int32.min_int = "-2147483648");
+      test "testu" (Int32.to_string Int32.max_int = "2147483647");
+      test "testi" (Int32.to_string Int32.min_int = "-2147483648");
+
+      stdout.WriteLine "constants: max_int - 10";stdout.Flush();
+      test "testa" (Int32.max_int - 10 = 2147483637);
+
+      stdout.WriteLine "min int";stdout.Flush();
+      for i = Int32.min_int to Int32.min_int + 10 do 
+        test "testb" (Int32.to_int (Int32.of_int i) = i);
+      done;
+      stdout.WriteLine "max int";stdout.Flush();
+      for i = Int32.max_int - 10 to Int32.max_int - 1 do 
+        test "testc" (Int32.to_int (Int32.of_int i) = i);
+      done;
+      stdout.WriteLine "div";
+      for i = 0 to 255 do 
+        test "testd" (Int32.div (Int32.of_int i) (Int32.of_int 1) = Int32.of_int i);
+      done;
+      for i = 0 to 255 do 
+        test "teste" (Int32.rem (Int32.of_int i) (Int32.of_int 1) = Int32.of_int 0);
+      done;
+      for i = 0 to 254 do 
+        test "testf" (Int32.succ (Int32.of_int i) = Int32.add (Int32.of_int i) Int32.one);
+      done;
+      for i = 1 to 255 do 
+        test "testg" (Int32.pred (Int32.of_int i) = Int32.sub (Int32.of_int i) Int32.one);
+      done;
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test "testh" (Int32.to_int (Int32.logand (Int32.of_int i) (Int32.of_int j)) = (i &&& j));
+        done;
+      done;
+      stdout.WriteLine "logor";
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test "testj" (Int32.to_int (Int32.logor (Int32.of_int i) (Int32.of_int j)) = (i ||| j));
+        done;
+      done;
+      stdout.WriteLine "logxor";
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test "testkkh" (Int32.to_int (Int32.logxor (Int32.of_int i) (Int32.of_int j)) = (i ^^^ j));
+        done;
+      done;
+      stdout.WriteLine "lognot";
+      for i = 1 to 255 do 
+          test "testqf" (Int32.lognot (Int32.of_int i) = Int32.of_int (~~~i))
+      done;
+      stdout.WriteLine "shift_left";
+      for i = 0 to 255 do 
+        for j = 0 to 7 do 
+          test "testcr4" (Int32.shift_left (Int32.of_int i) j = Int32.of_int (i <<< j))
+        done;
+      done;
+      stdout.WriteLine "shift_right";
+      for i = 0 to 255 do 
+        for j = 0 to 7 do 
+          test "testvt3q" (Int32.shift_right (Int32.of_int i) j = Int32.of_int (i >>> j))
+        done;
+      done;
+      test "testqvt4" (Int32.shift_right 2 1 = 1);
+      test "testvq3t" (Int32.shift_right 4 2 = 1);
+      stdout.WriteLine "shift_right_logical";
+      for i = 0 to 255 do 
+        for j = 0 to 7 do 
+          test "testvq34" (Int32.shift_right_logical (Int32.of_int i) j = Int32.of_int (Pervasives.(lsr) i j))
+        done;
+      done;
+      test "testvq3t" (Int32.shift_right_logical 0xFFFFFFFF 1 = 0x7FFFFFFF);
+      stdout.WriteLine "shift_right_logical (1)";
+      test "testvq3" (Int32.shift_right_logical 0xFFFFFFF2 1 = 0x7FFFFFF9);
+      stdout.WriteLine "shift_right_logical (2)";
+      test "testqvt4" (Int32.shift_right_logical 0x7FFFFFF2 1 = 0x3FFFFFF9);
+      stdout.WriteLine "shift_right_logical (3) ";
+      test "testqv3t" (Int32.shift_right_logical 0xFFFFFFFF 2 = 0x3FFFFFFF);
+      stdout.WriteLine "shift_right_logical (4)";
+      test "testb4y5" (Int32.shift_right_logical 0x80000004 2 = 0x20000001);
+      stdout.WriteLine "to_string";
+      for i = 0 to 255 do 
+          test "testbsyet" (Int32.to_string (Int32.of_int i) = string i)
+      done;
+      stdout.WriteLine "of_string";
+      for i = 0 to 255 do 
+          test "testvq4" (Int32.of_string (string i) = Int32.of_int i)
+      done;
+      stdout.WriteLine "constants (hex)";
+      test "testv4w" (Int32.of_string "0x0" = 0);
+      test "testv35" (Int32.of_string "0x1" = 1);
+      test "testvq3" (Int32.of_string "0x2" = 2);
+      test "testv3qt" (Int32.of_string "0xa" = 10);
+      test "testbwy4" (Int32.of_string "0xff" = 255);
+      stdout.WriteLine "constants (octal)";
+      test "testb4y5" (Int32.of_string "0o0" = 0);
+      test "testb4y" (Int32.of_string "0o1" = 1);
+      test "testby4" (Int32.of_string "0o2" = 2);
+      test "testbw4y" (Int32.of_string "0o7" = 7);
+      test "testb45" (Int32.of_string "0o10" = 8);
+      test "testbw4" (Int32.of_string "0o777" = 7*64 + 7*8 + 7);
+      test "test67n" (Int32.of_string "0o111" = 64 + 8 + 1);
+      stdout.WriteLine "constants (binary)";
+      test "test34q" (Int32.of_string "0b0" = 0);
+      test "testn" (Int32.of_string "0b1" = 1);
+      test "tester" (Int32.of_string "0b10" = 2);
+      test "testeyn" (Int32.of_string "0b11" = 3);
+      test "testynr" (Int32.of_string "0b00000000" = 0);
+      test "testnea" (Int32.of_string "0b11111111" = 0xFF);
+      test "testneayr" (Int32.of_string "0b1111111100000000" = 0xFF00);
+      test "testne" (Int32.of_string "0b11111111000000001111111100000000" = 0xFF00FF00);
+      test "testnaey" (Int32.of_string "0b11111111111111111111111111111111" = 0xFFFFFFFF);
+      test "testny" (Int32.of_string "0x7fffffff" = Int32.max_int);
+
+[<TestFixture>]
+type public UInt32Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+      stdout.WriteLine "constants (hex, unit32)";
+      test "testv4w" (UInt32.of_string "0x0" = 0u);
+      test "testv35" (UInt32.of_string "0x1" = 1u);
+      test "testvq3" (UInt32.of_string "0x2" = 2u);
+      test "testv3qt" (UInt32.of_string "0xa" = 10u);
+      test "testbwy4" (UInt32.of_string "0xff" = 255u);
+      stdout.WriteLine "constants (octal, unit32)";
+      test "testb4y5" (UInt32.of_string "0o0" = 0u);
+      test "testb4y" (UInt32.of_string "0o1" = 1u);
+      test "testby4" (UInt32.of_string "0o2" = 2u);
+      test "testbw4y" (UInt32.of_string "0o7" = 7u);
+      test "testb45" (UInt32.of_string "0o10" = 8u);
+      test "testbw4" (UInt32.of_string "0o777" = 7u*64u + 7u*8u + 7u);
+      test "test67n" (UInt32.of_string "0o111" = 64u + 8u + 1u);
+      stdout.WriteLine "constants (binary, unit32)";
+
+      test "test34q" (UInt32.of_string "0b0" = 0u);
+      test "testn" (UInt32.of_string "0b1" = 1u);
+      test "tester" (UInt32.of_string "0b10" = 2u);
+      test "testeyn" (UInt32.of_string "0b11" = 3u);
+      test "testynr" (UInt32.of_string "0b00000000" = 0u);
+      test "testnea" (UInt32.of_string "0b11111111" = 0xFFu);
+      test "testneayr" (UInt32.of_string "0b1111111100000000" = 0xFF00u);
+
+      test "testne" (UInt32.of_string "0b11111111000000001111111100000000" = 0xFF00FF00u);
+      test "testnaey" (UInt32.of_string "0b11111111111111111111111111111111" = 0xFFFFFFFFu);
+      test "testny" (UInt32.of_string "0xffffffff" = UInt32.max_int);
+
+      stdout.WriteLine "constants (decimal)";
+      test "test" (Int32.of_string "2147483647" = Int32.max_int);
+      test "test" (Int32.of_string "-0x80000000" = Int32.min_int);
+      test "test" (Int32.of_string "-2147483648" = Int32.min_int);
+      stdout.WriteLine "done";
+      ()    
+
+[<TestFixture>]
+type public Int64Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+          test  "vwknw4vkl"  (Int64.zero = Int64.zero);
+          test  "vwknw4vkl"  (Int64.add Int64.zero Int64.one = Int64.one);
+          test  "vwknw4vkl"  (Int64.add Int64.one Int64.zero  = Int64.one);
+          test  "vwknw4vkl"  (Int64.sub Int64.one Int64.zero  = Int64.one);
+          test  "vwknw4vkl"  (Int64.sub Int64.one Int64.one  = Int64.zero);
+          for i = 0 to 255 do 
+            test  "vwknw4vkl"  (Int64.to_int (Int64.of_int i) = i);
+          done;
+          for i = 0 to 255 do 
+            test  "vwknw4vkl"  (Int64.of_int i = Int64.of_int i);
+          done;
+          stdout.WriteLine "mul i 1";
+          for i = 0 to 255 do 
+            test  "vwknw4vkl"  (Int64.mul (Int64.of_int i) (Int64.of_int 1) = Int64.of_int i);
+          done;
+          stdout.WriteLine "add";
+          for i = 0 to 255 do 
+            for j = 0 to 255 do 
+              test  "vwknw4vkl"  (Int64.to_int (Int64.add (Int64.of_int i) (Int64.of_int j)) = (i + j));
+            done;
+          done;
+          stdout.WriteLine "div";
+          for i = 0 to 255 do 
+            test  "vwknw4vkl"  (Int64.div (Int64.of_int i) (Int64.of_int 1) = Int64.of_int i);
+          done;
+          for i = 0 to 255 do 
+            test  "vwknw4vkl"  (Int64.rem (Int64.of_int i) (Int64.of_int 1) = Int64.of_int 0);
+          done;
+          for i = 0 to 254 do 
+            test  "vwknw4vkl"  (Int64.succ (Int64.of_int i) = Int64.add (Int64.of_int i) Int64.one);
+          done;
+          for i = 1 to 255 do 
+            test  "vwknw4vkl"  (Int64.pred (Int64.of_int i) = Int64.sub (Int64.of_int i) Int64.one);
+          done;
+          for i = 1 to 255 do 
+            for j = 1 to 255 do 
+              test  "vwknw4vkl"  (Int64.to_int (Int64.logand (Int64.of_int i) (Int64.of_int j)) = Pervasives.(land) i j);
+            done;
+          done;
+          stdout.WriteLine "logor";
+          for i = 1 to 255 do 
+            for j = 1 to 255 do 
+              test  "vwknw4vkl"  (Int64.to_int (Int64.logor (Int64.of_int i) (Int64.of_int j)) = Pervasives.(lor) i j);
+            done;
+          done;
+          stdout.WriteLine "logxor";
+          for i = 1 to 255 do 
+            for j = 1 to 255 do 
+              test  "vwknw4vkl"  (Int64.to_int (Int64.logxor (Int64.of_int i) (Int64.of_int j)) = i ^^^ j);
+            done;
+          done;
+          stdout.WriteLine "lognot";
+          for i = 1 to 255 do 
+              test  "vwknw4vkl"  (Int64.lognot (Int64.of_int i) = Int64.of_int (~~~ i))
+          done;
+        #if NOTAILCALLS // NOTAILCALLS <-> MONO
+        #else
+          stdout.WriteLine "shift_left";
+          for i = 0 to 255 do 
+            for j = 0 to 7 do 
+              test  "vwknw4vkl"  (Int64.shift_left (Int64.of_int i) j = Int64.of_int (i <<< j))
+            done;
+          done;
+          stdout.WriteLine "shift_right";
+          for i = 0 to 255 do 
+            for j = 0 to 7 do 
+              test  "vwknw4vkl"  (Int64.shift_right (Int64.of_int i) j = Int64.of_int (i >>> j))
+            done;
+          done;
+          stdout.WriteLine "shift_right_logical";
+          for i = 0 to 255 do 
+            for j = 0 to 7 do 
+              test  "vwknw4vkl"  (Int64.shift_right_logical (Int64.of_int i) j = Int64.of_int (Pervasives.(lsr) i j))
+            done;
+          done;
+        #endif
+          stdout.WriteLine "to_string";
+          for i = 0 to 255 do 
+              test  "vwknw4vkl"  (Int64.to_string (Int64.of_int i) = string i)
+          done;
+          stdout.WriteLine "of_string";
+          for i = 0 to 255 do 
+              test  "vwknw4vkl"  (Int64.of_string (string i) = Int64.of_int i)
+          done;
+          stdout.WriteLine "constants (hex)";
+          test  "vwknw4vkl"  (Int64.of_string "0x0" = 0L);
+          test  "vwknw4vkl"  (Int64.of_string "0x1" = 1L);
+          test  "vwknw4vkl"  (Int64.of_string "0x2" = 2L);
+          test  "vwknw4vkl"  (Int64.of_string "0xa" = 10L);
+          test  "vwknw4vkl"  (Int64.of_string "0xff" = 255L);
+          stdout.WriteLine "constants (octal)";
+          test  "vwknw4vkl"  (Int64.of_string "0o0" = 0L);
+          test  "vwknw4vkl"  (Int64.of_string "0o1" = 1L);
+          test  "vwknw4vkl"  (Int64.of_string "0o2" = 2L);
+          test  "vwknw4vkl"  (Int64.of_string "0o7" = 7L);
+          test  "vwknw4vkl"  (Int64.of_string "0o10" = 8L);
+          test  "vwknw4vkl"  (Int64.of_string "0o777" = 7L*64L + 7L*8L + 7L);
+          test  "vwknw4vkl"  (Int64.of_string "0o111" = 64L + 8L + 1L);
+          stdout.WriteLine "constants (binary)";
+          test  "vwknw4vkl"  (Int64.of_string "0b0" = 0L);
+          test  "vwknw4vkl"  (Int64.of_string "0b1" = 1L);
+          test  "vwknw4vkl"  (Int64.of_string "0b10" = 2L);
+          test  "vwknw4vkl"  (Int64.of_string "0b11" = 3L);
+          test  "vwknw4vkl"  (Int64.of_string "0b00000000" = 0L);
+          test  "vwknw4vkl"  (Int64.of_string "0b11111111" = 0xFFL);
+          test  "vwknw4vkl"  (Int64.of_string "0b1111111100000000" = 0xFF00L);
+          test  "vwknw4vkl"  (Int64.of_string "0b11111111000000001111111100000000" = 0xFF00FF00L);
+          test  "vwknw4vkl"  (Int64.of_string "0b11111111111111111111111111111111" = 0xFFFFFFFFL);
+          test  "vwknw4vkl"  (Int64.of_string "0b1111111100000000111111110000000011111111000000001111111100000000" = 0xFF00FF00FF00FF00L);
+          test  "vwknw4vkl"  (Int64.of_string "0b1111111111111111111111111111111111111111111111111111111111111111" = 0xFFFFFFFFFFFFFFFFL);
+
+          stdout.WriteLine "of_string: min_int";
+          test  "vwknw4vkl"  (Int64.of_string "-0x8000000000000000" = Int64.min_int);
+          test  "vwknw4vkl"  (Int64.of_string "-9223372036854775808" = Int64.min_int);
+          test  "vwknw4vkl"  (-9223372036854775808L = Int64.min_int);
+          stdout.WriteLine "done";
+
+          stdout.WriteLine "constants (hex, UInt64)";
+          test  "vwknw4vkl"  (UInt64.of_string "0x0" = 0UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0x1" = 1UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0x2" = 2UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0xa" = 10UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0xff" = 255UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0xffffffffffffffff" = UInt64.max_int);
+          
+          stdout.WriteLine "constants (octal, UInt64)";
+          test  "vwknw4vkl"  (UInt64.of_string "0o0" = 0UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o1" = 1UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o2" = 2UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o7" = 7UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o10" = 8UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o777" = 7UL*64UL + 7UL*8UL + 7UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o111" = 64UL + 8UL + 1UL);
+          
+          stdout.WriteLine "constants (binary, UInt64)";
+          test  "vwknw4vkl"  (UInt64.of_string "0b0" = 0UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b1" = 1UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b10" = 2UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b11" = 3UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b00000000" = 0UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b11111111" = 0xFFUL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b1111111100000000" = 0xFF00UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b11111111000000001111111100000000" = 0xFF00FF00UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b11111111111111111111111111111111" = 0xFFFFFFFFUL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b1111111100000000111111110000000011111111000000001111111100000000" = 0xFF00FF00FF00FF00UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b1111111111111111111111111111111111111111111111111111111111111111" = 0xFFFFFFFFFFFFFFFFUL);
+
+          stdout.WriteLine "done";
+          ()    
+
+
+[<TestFixture>]
+type public ListCompatTests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+        test "List.tryfind_indexi" (List.tryFindIndex ((=) 4) [1;2;3;4;4;3;2;1] = Some 3)
+
+
+
+
+[<TestFixture>]
+type public PervasivesTests() =
+
+    [<Test>]
+    member this.ExceptionMappings() = 
+        check "exception mappings"  true (try int_of_string "A" |> ignore; false with Failure _ -> true | _ -> false)
+        check "exception mappings"  true (try float_of_string "A" |> ignore; false with Failure _ -> true | _ -> false)
+
+    [<Test>]
+    member this.BasicTests() = 
+        test "tefwiu32" (try raise Not_found with Not_found -> true | _ -> false)
+
+        test "tefw38vj" (try raise Out_of_memory with Out_of_memory -> true | _ -> false)
+
+        test "tefw93mvj" (try raise Division_by_zero with Division_by_zero -> true | _ -> false)
+
+        test "tefwfewevj" (try raise Stack_overflow with Stack_overflow -> true | _ -> false)
+
+        test "tefw9ifmevj" (try raise End_of_file with End_of_file -> true | _ -> false)
+
+        test "atefwiu32" (try raise Not_found with Out_of_memory | Division_by_zero | Stack_overflow | End_of_file -> false | Not_found -> true | _ -> false)
+
+        test "btefwiu32" (try raise Out_of_memory with Not_found | Division_by_zero | Stack_overflow | End_of_file -> false | Out_of_memory -> true | _ -> false)
+
+        test "ctefwiu32" (try raise Division_by_zero with Not_found | Out_of_memory | Stack_overflow | End_of_file -> false | Division_by_zero -> true | _ -> false)
+
+        test "dtefwiu32" (try raise Stack_overflow with Not_found | Out_of_memory | Division_by_zero | End_of_file -> false | Stack_overflow -> true | _ -> false)
+
+        test "etefwiu32" (try raise End_of_file with Not_found | Out_of_memory | Division_by_zero |  Stack_overflow -> false | End_of_file -> true | _ -> false)
+
+        test "ftefwiu32" (try raise Foo with Not_found | Out_of_memory | Division_by_zero |  Stack_overflow -> false | Foo -> true | _ -> false)
+
+
+  
+    [<Test>]
+    member this.IO_EndOfLine_Translations() = 
+
+        let checkFileContentsUsingVariousTechniques(filename) =
+            using (open_in_bin filename) (fun is -> 
+                let buf = Array.create 5 0uy in
+                check "cewjk1" (input is buf 0 5) 5;
+                check "cewjk2" buf [|104uy; 101uy; 108uy; 108uy; 111uy|];
+                check "cewjk3" (input is buf 0 2) 2;
+                check "cewjk4" buf [|13uy; 10uy; 108uy; 108uy; 111uy|]);
+
+            using (open_in_bin filename) (fun is2 -> 
+
+                check "cewjk5" (is2.Peek()) 104;
+                check "cewjk6" (is2.Read()) 104;
+                check "cewjk7" (is2.Read()) 101;
+                check "cewjk8" (is2.Read()) 108;
+                check "cewjk9" (is2.Read()) 108;
+                check "cewjk0" (is2.Read()) 111;
+                check "cewjkq" (is2.Read()) 13;
+                check "cewjkw" (is2.Read()) 10;
+                check "cewjke" (is2.Read()) (-1));
+
+            using (open_in_bin filename) (fun is3 -> 
+
+                check "cewjkr" (input_char is3) 'h';
+                check "cewjkt" (input_char is3) 'e';
+                check "cewjky" (input_char is3) 'l';
+                check "cewjku" (input_char is3) 'l';
+                check "cewjki" (input_char is3) 'o';
+                check "cewjko" (input_char is3) '\r';
+                check "cewjkp" (input_char is3) '\n';
+                check "cewjka" (try input_char is3 |> ignore; false with End_of_file -> true) true);
+
+            using (open_in_bin filename) (fun is4 -> 
+
+                let buf4 = Array.create 5 '0' in
+                check "cewjks" (input_chars is4 buf4 0 5) 5;
+                check "cewjkd" (buf4) [|'h'; 'e'; 'l'; 'l'; 'o'; |];
+                check "cewjkf" (input_chars is4 buf4 0 2) 2;
+                check "cewjkd" (buf4) [|'\r'; '\n'; 'l'; 'l'; 'o'; |];
+                check "cewjkh" (input_chars is4 buf4 0 2) 0);
+            
+            using (open_in filename) (fun is5 -> 
+
+                let buf5 = Array.create 5 0uy in
+                check "veswhek1" (input is5 buf5 0 5) 5;
+                check "veswhek2" buf5 [|104uy; 101uy; 108uy; 108uy; 111uy|];
+                check "veswhek3" (input is5 buf5 0 2)  2;
+                check "veswhek4" buf5 [|13uy; 10uy; 108uy; 108uy; 111uy|];
+                check "veswhek5" (input is5 buf5 0 2) 0);
+            
+
+            using (open_in filename) (fun is2 -> 
+
+                check "veswhek6" (is2.Peek()) 104;
+                check "veswhek7" (is2.Read()) 104;
+                check "veswhek8" (is2.Read()) 101;
+                check "veswhek9" (is2.Read()) 108;
+                check "veswhek0" (is2.Read()) 108;
+                check "veswhekq" (is2.Read()) 111;
+                check "veswhekw" (is2.Read()) 13;
+                check "veswheke" (is2.Read()) 10;
+                check "veswhekr" (is2.Read()) (-1));
+
+
+            using (open_in filename) (fun is3 -> 
+
+                check "veswhekt" (input_char is3) 'h';
+                check "veswheky" (input_char is3) 'e';
+                check "veswheku" (input_char is3) 'l';
+                check "veswheko" (input_char is3) 'l';
+                check "veswhekp" (input_char is3) 'o';
+                check "veswheka" (input_char is3) '\r';
+                check "veswheks" (input_char is3) '\n';
+                check "veswhekd" (try input_char is3 |> ignore; false with End_of_file -> true) true)
+
+        using (open_out_bin "test.txt") (fun os -> fprintf os "hello\r\n")
+        checkFileContentsUsingVariousTechniques("test.txt")
+        using (open_out "test.txt") (fun os -> fprintf os "hello\r\n")
+        checkFileContentsUsingVariousTechniques("test.txt")
+        using (open_out "test.txt") (fun os -> os.Write (let s = "hello\r\n" in Array.init s.Length (fun i -> s.[i]) ))
+        checkFileContentsUsingVariousTechniques("test.txt")
+        using (open_out_bin "test.txt") (fun os -> os.Write (let s = "hello\r\n" in Array.init s.Length (fun i -> s.[i]) ))
+        checkFileContentsUsingVariousTechniques("test.txt")
+        using (open_out "test.txt") (fun os -> os.Write "hello\r\n")
+        checkFileContentsUsingVariousTechniques("test.txt")
+        using (open_out_bin "test.txt") (fun os -> os.Write "hello\r\n")
+        checkFileContentsUsingVariousTechniques("test.txt")
+
+#if FX_NO_BINARY_SERIALIZATION
+#else
+    [<Test>]
+    member this.BinarySerialization() = 
+
+        (* Andrez:
+           It appears to me that writing the empty list into a binary channel does not work.
+        *)   
+          
+          let file = open_out_bin "test.txt" in
+          output_value file ([]: int list);
+          close_out file;
+          let file = open_in_bin "test.txt" in
+          if (input_value file : int list) <> [] then (reportFailure "wnwve0ljkvwe");
+          close_in file;
+#endif
+
+
+
+[<TestFixture>]
+type public Filename_Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+        check "Filename.dirname1"  "C:" (Filename.dirname "C:")
+        check "Filename.dirname2"  "C:\\" (Filename.dirname "C:\\")
+        check "Filename.dirname3"  "c:\\" (Filename.dirname "c:\\")
+        check "Filename.dirname2"  "C:/" (Filename.dirname "C:/")
+        check "Filename.dirname3"  "c:/" (Filename.dirname "c:/")
+        check "Filename.dirname4"  "." (Filename.dirname "")
+        check "Filename.dirname5"  "\\" (Filename.dirname "\\")
+        check "Filename.dirname6"  "." (Filename.dirname "a")
+        // F# and OCaml do return different results for this one.
+        // F# preserves the double slashes.  That seems fair enough 
+        // do check "Filename.dirname2"  "\\" (Filename.dirname "\\\\")
+
+        check "is_relative1"  false (Filename.is_relative "C:")
+        check "is_relative2"  false (Filename.is_relative "C:\\")
+        check "is_relative3"  false (Filename.is_relative "c:\\")
+        check "is_relative4"  false (Filename.is_relative "C:/")
+        check "is_relative5"  false (Filename.is_relative "c:/")
+        check "is_relative6"  true (Filename.is_relative "")
+        check "is_relative7"  true (Filename.is_relative ".")
+        check "is_relative8"  true (Filename.is_relative "a")
+        check "is_relative9"  false (Filename.is_relative "\\")
+        check "is_relative10"  false (Filename.is_relative "\\\\")
+
+        check "is_relative8"  true (Filename.is_implicit "a")
+        check "is_relative8"  false (Filename.is_implicit ".\\a")
+        check "is_relative8"  false (Filename.is_implicit "..\\a")
+
+        let has_extension (s:string) = 
+          (String.length s >= 1 && String.get s (String.length s - 1) = '.') 
+          || System.IO.Path.HasExtension(s)
+
+        check "has_extension 1"  false (has_extension "C:")
+        check "has_extension 2"  false (has_extension "C:\\")
+        check "has_extension 3"  false (has_extension "c:\\")
+        check "has_extension 4"  false (has_extension "")
+        check "has_extension 5"  true (has_extension ".")
+        check "has_extension 6"  false (has_extension "a")
+        check "has_extension 7"  true (has_extension "a.b")
+        check "has_extension 8"  true (has_extension ".b")
+        check "has_extension 9"  true (has_extension "c:\\a.b")
+        check "has_extension 10"  true (has_extension "c:\\a.")
+
+
+        check "chop_extension1"  true (try ignore(Filename.chop_extension "C:"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension2"  true (try ignore(Filename.chop_extension "C:\\"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension3"  true (try ignore(Filename.chop_extension "c:\\"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension4"  true (try ignore(Filename.chop_extension "C:/"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension5"  true (try ignore(Filename.chop_extension "c:/"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension6"  true (try ignore(Filename.chop_extension ""); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension7"  true (try ignore(Filename.chop_extension "a"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension8"  true (try ignore(Filename.chop_extension "c:\\a"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension9"  true (try ignore(Filename.chop_extension "c:\\foo.b\\a"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension10"  "" (Filename.chop_extension ".")
+        check "chop_extension11"  "a" (Filename.chop_extension "a.")
+        check "chop_extension12"  "c:\\a" (Filename.chop_extension "c:\\a.")
+
+        check "Filename.dirname1"  "" (Filename.basename "C:")
+        check "Filename.dirname2"  "" (Filename.basename "C:\\")
+        check "Filename.dirname2"  "" (Filename.basename "c:\\")
+        check "Filename.dirname2"  "" (Filename.basename "")
+        check "Filename.dirname2"  "c" (Filename.basename "\\\\c")
+        check "Filename.dirname2"  "" (Filename.basename "\\\\")
+
+#if FX_NO_DOUBLE_BIT_CONVERTER
+#else
+[<TestFixture>]
+type public Float_Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+        check "FloatParse.1" (Float.to_bits (Float.of_string "0.0")) 0L
+        check "FloatParse.0" (Float.to_bits (Float.of_string "-0.0"))      0x8000000000000000L // (-9223372036854775808L)
+        check "FloatParse.2" (Float.to_bits (Float.of_string "-1E-127"))   0xa591544581b7dec2L // (-6516334528322609470L)
+        check "FloatParse.3" (Float.to_bits (Float.of_string "-1E-323"))   0x8000000000000002L // (-9223372036854775806L)
+        check "FloatParse.4" (Float.to_bits (Float.of_string "-1E-324"))   0x8000000000000000L // (-9223372036854775808L)
+        check "FloatParse.5" (Float.to_bits (Float.of_string "-1E-325"))   0x8000000000000000L // (-9223372036854775808L)
+        check "FloatParse.6" (Float.to_bits (Float.of_string "1E-325")) 0L
+        check "FloatParse.7" (Float.to_bits (Float.of_string "1E-322")) 20L
+        check "FloatParse.8" (Float.to_bits (Float.of_string "1E-323")) 2L
+        check "FloatParse.9" (Float.to_bits (Float.of_string "1E-324")) 0L
+        check "FloatParse.A" (Float.to_bits (Float.of_string "Infinity"))  0x7ff0000000000000L // 9218868437227405312L
+        check "FloatParse.B" (Float.to_bits (Float.of_string "-Infinity")) 0xfff0000000000000L // (-4503599627370496L)
+        check "FloatParse.C" (Float.to_bits (Float.of_string "NaN"))       0xfff8000000000000L  // (-2251799813685248L)
+        check "FloatParse.D" (Float.to_bits (Float.of_string "-NaN"))    ( // http://en.wikipedia.org/wiki/NaN
+                                                                  let bit64 = System.IntPtr.Size = 8 in
+                                                                  if bit64 && System.Environment.Version.Major < 4 then
+                                                                      // 64-bit (on NetFx2.0) seems to have same repr for -nan and nan
+                                                                      0xfff8000000000000L // (-2251799813685248L)
+                                                                  else
+                                                                      // 64-bit (on NetFx4.0) and 32-bit (any NetFx) seems to flip the sign bit on negation.
+                                                                      // However:
+                                                                      // it seems nan has the negative-bit set from the start,
+                                                                      // and -nan then has the negative-bit cleared!
+                                                                      0x7ff8000000000000L // 9221120237041090560L
+                                                                )
+#endif
+
+#if FX_NO_COMMAND_LINE_ARGS
+#else
+[<TestFixture>]
+type public Arg_Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+
+      let res = System.Text.StringBuilder()
+      let add (x:string) = res.Append("<"^x^">") |> ignore
+      Microsoft.FSharp.Compatibility.OCaml.Arg.parse_argv (ref 0) [|"main.exe";"otherA";"";"otherB"|] [] add "fred"
+      check "Bug3803" (res.ToString()) "<otherA><><otherB>"
+#endif  
+
+[<TestFixture>]
+type public SysTests() =
+  
+    [<Test>]
+    member this.TestFileExists() = 
+
+        test "dwe098" (not (Sys.file_exists "never-create-me"))
+
+    [<Test>]
+    member this.Test_Sys_remove() = 
+          let os = open_out "remove-me.txt" in
+          close_out os;
+          test "dwe098" (Sys.file_exists "remove-me.txt" && (Sys.remove "remove-me.txt"; not (Sys.file_exists "remove-me.txt")))
+
+    [<Test>]
+    member this.Test_Sys_rename() = 
+          let os = open_out "rename-me.txt" in
+          close_out os;
+          test "dwe098dw" (Sys.file_exists "rename-me.txt" && (Sys.rename "rename-me.txt" "remove-me.txt"; Sys.file_exists "remove-me.txt" && not (Sys.file_exists "rename-me.txt") && (Sys.remove "remove-me.txt"; not (Sys.file_exists "remove-me.txt"))))
+
+#if FX_NO_ENVIRONMENT
+#else
+    [<Test>]
+    member this.Test_Sys_getenv() = 
+          ignore (Sys.getenv "PATH");
+          test "w99ocwkm" (try ignore (Sys.getenv "VERY UNLIKELY VARIABLE"); false; with Not_found -> true)
+#endif
+
+    [<Test>]
+    member this.Test_Sys_getcwd() = 
+            
+          let p1 = Sys.getcwd() in 
+          Sys.chdir "..";
+          let p2 = Sys.getcwd() in 
+          test "eiojk" (p1 <> p2);
+          Sys.chdir p1;
+          let p3 = Sys.getcwd() in 
+          test "eiojk" (p1 = p3)
+
+#if FX_NO_PROCESS_START
+#else
+    [<Test>]
+    member this.Test_Sys_command() = 
+
+          test "ekj" (Sys.command "help.exe" |> ignore; true)
+#endif
+
+    [<Test>]
+    member this.Test_Sys_word_size() = 
+
+          test "ekdwq8uj" (Sys.word_size = 32 || Sys.word_size = 64)
+
+#if FX_NO_PROCESS_DIAGNOSTICS
+#else
+    [<Test>]
+    member this.Test_Sys_time() = 
+
+          let t1 = ref (Sys.time()) in 
+          for i = 1 to 30 do 
+            let t2 = Sys.time() in 
+            test "fe921lk30" (!t1 <= t2);
+            t1 := t2
+          done
+#endif
+
+[<TestFixture>]
+type public FuncConvertTests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+
+        check "dwe098ce1" ((Microsoft.FSharp.Core.FuncConvert.FuncFromTupled(fun (a,b) -> a + b)) 3 4) 7
+        check "dwe098ce2" ((Microsoft.FSharp.Core.FuncConvert.FuncFromTupled(fun (a,b,c) -> a + b + c)) 3 4 5) 12
+        check "dwe098ce3" ((Microsoft.FSharp.Core.FuncConvert.FuncFromTupled(fun (a,b,c,d) -> a + b + c + d)) 3 4 5 5) 17
+        check "dwe098ce4" ((Microsoft.FSharp.Core.FuncConvert.FuncFromTupled(fun (a,b,c,d,e) -> a + b + c + d + e)) 3 4 5 5 5) 22
+
+        check "dwe098ce1" ((Microsoft.FSharp.Core.FuncConvert.ToFSharpFunc(System.Converter(fun a -> a + 1))) 3) 4
+        check "dwe098ce1" ((Microsoft.FSharp.Core.FuncConvert.ToFSharpFunc(System.Action<_>(fun a -> ()))) 3) ()
diff --git a/src/FSharp.PowerPack.Unittests/ControlTests.fs b/src/FSharp.PowerPack.Unittests/ControlTests.fs
new file mode 100755
index 0000000..7bdcae9
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/ControlTests.fs
@@ -0,0 +1,527 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open System
+open System.IO
+open System.Threading
+
+#nowarn "40"
+
+
+module ControlTestUtilities = 
+
+    let syncObj = new obj()
+    let reportFailure s = 
+      lock syncObj (fun () ->
+         Assert.Fail (sprintf "FAILURE: %s failed" s)
+      )
+    let biggerThanTrampoliningLimit = 10000
+
+    let boxed(a:Async<'b>) : Async<obj> = async { let! res = a in return box res }
+        
+    type VStringRef(s) = 
+        [<VolatileField>]
+        let mutable contents : string = s 
+        
+        member x.Contents 
+            with get () = contents
+            and set v = contents <- v
+        
+    let (!) (x : VStringRef) = x.Contents
+    let (:=) (x : VStringRef) s = x.Contents <- s
+    let ref s = VStringRef(s)
+
+    // Useful class: put "checkpoints" in the code.
+    // Check they are called in the right order.
+    type Path(str) =
+        let mutable current = 0
+        member p.Check n = check (str + " #" + string (current+1)) n (current+1)
+                           current <- n
+
+    type Color = Blue | Red | Yellow
+
+    type Message =  Color * AsyncResultCell<Color option>
+
+open ControlTestUtilities
+
+[<TestFixture>]
+type public ZZZ_ControlTests() =
+    let writeAllBytes (path:string,bytes:byte[]) =
+#if FX_NO_FILEWRITEALL
+        use s = System.IO.File.OpenWrite(path)
+        s.Write(bytes,0,bytes.Length)
+#else
+        System.IO.File.WriteAllBytes(path, bytes)
+#endif
+    let writeAllText(path:string,contents:string) =
+#if FX_NO_FILEWRITEALL
+        use s = new System.IO.StreamWriter(path)
+        s.Write(contents)
+#else
+        System.IO.File.WriteAllText(path, contents)
+#endif
+
+
+    [<TestFixtureSetUp>]
+    member this.TestFixtureSetUp() = 
+        System.AppDomain.CurrentDomain.UnhandledException.AddHandler(
+               fun _ (args:System.UnhandledExceptionEventArgs) ->
+                  lock syncObj (fun () ->
+                        reportFailure ((args.ExceptionObject :?> System.Exception).ToString())
+                     )
+        )
+  
+    [<Test>]
+    member this.AsyncOpenReadTests() = 
+
+        // There should be no effects before running, e.g. no attempt to open the file
+        do System.IO.File.AsyncOpenRead "non exist ... file " |> ignore
+        do System.IO.File.AsyncOpenWrite "non exist ... file 2" |> ignore
+
+              
+        
+        check 
+            "c32398u1: AsyncOpenRead/AsyncRead"
+            (let _ = writeAllBytes("tmp.bin", "abcdefg"B)
+             Async.RunSynchronously 
+                 (async { use! is = System.IO.File.AsyncOpenRead "tmp.bin" 
+                          return! is.AsyncRead 5 }))
+            "abcde"B
+
+        do 
+            let n = 10000000
+            let bytes = Array.init n (fun i -> byte i)
+            check 
+                "c32398u1: AsyncOpenRead/AsyncRead"
+                (let _ = writeAllBytes("tmp.bin", bytes)
+                 Async.RunSynchronously 
+                     (async { use! is = System.IO.File.AsyncOpenRead "tmp.bin" 
+                              return! is.AsyncRead n }))
+                bytes
+
+        do 
+            let n = 10000000
+            let bytes = Array.init n (fun i -> byte i)
+            check 
+                "c32398u1: AsyncOpenRead/AsyncRead"
+                (let _ = writeAllBytes("tmp.bin", bytes)
+                 Async.RunSynchronously 
+#if FX_NO_FILE_OPTIONS
+                     (async { use! is = System.IO.File.AsyncOpen("tmp.bin",mode=FileMode.Open)
+#else
+                     (async { use! is = System.IO.File.AsyncOpen("tmp.bin",mode=FileMode.Open,options=FileOptions.Asynchronous)
+#endif
+                              return! is.AsyncRead n }))
+                bytes
+
+    [<Test>]
+    member this.AsyncOpenReadWriteTest1() = 
+        check 
+            "c32398u2: AsyncOpenRead/AsyncRead"
+            (let _ = writeAllBytes("tmp.bin", "abcdefg"B)
+             Async.RunSynchronously 
+                  (async { use! is = System.IO.File.AsyncOpenRead "tmp.bin" 
+                           return! is.AsyncRead 7 }))
+            "abcdefg"B
+
+    [<Test>]
+    member this.AsyncOpenReadWriteTest2() = 
+        check 
+            "c32398u3: AsyncOpenRead/AsyncRead"
+            (let _ = writeAllBytes("tmp.bin", "abcdefg"B)
+             Async.RunSynchronously 
+                 (async { let buffer = Array.zeroCreate<byte>(7)
+                          use! is = System.IO.File.AsyncOpenRead "tmp.bin" 
+                          let! count = is.AsyncRead(buffer,0,7) 
+                          return count, buffer }))
+            (7, "abcdefg"B)
+
+
+    [<Test>]
+    member this.AsyncOpenReadWriteTest3() = 
+        check 
+            "c32398u4: AsyncOpenRead/AsyncRead/AsyncOpenWrite/AsyncWrite"
+            (let _ = writeAllBytes("tmp.bin", "abcdefg"B)
+             Async.RunSynchronously 
+                 (async { do! async { let buffer = "qer"B
+                                      use! is = System.IO.File.AsyncOpenWrite "tmp.bin" 
+                                      do! is.AsyncWrite(buffer,0,3)  }
+                          let buffer = Array.zeroCreate<byte>(7)
+                          use! is = System.IO.File.AsyncOpenRead "tmp.bin" 
+                          let! count = is.AsyncRead(buffer,0,7) 
+                          return count, buffer }))
+            (7, "qerdefg"B)
+
+    [<Test>]
+    member this.AsyncOpenTextTest() = 
+        check 
+            "c32398u5: AsyncOpenText"
+            (let _ = writeAllText("tmp.txt", "abcdefg")
+             Async.RunSynchronously 
+                  (async { use! is = System.IO.File.AsyncOpenText "tmp.txt" 
+                           return is.ReadToEnd() }))
+            "abcdefg"
+
+#if FX_NO_WINDOWSFORMS
+#else
+    [<Test>]
+    member this.AsyncWorkerTest16() = 
+
+        let p = Path "test16 - basic worker"
+        let worker = async {
+            do p.Check 1
+            do! Async.Sleep 400
+            do p.Check 3
+        }
+        AsyncWorker(worker).RunAsync() |> ignore
+        System.Threading.Thread.Sleep 200
+        p.Check 2
+        System.Threading.Thread.Sleep 400
+        System.Windows.Forms.Application.DoEvents()
+        p.Check 4
+
+    [<Test>]
+    member this.AsyncWorkerTest17() = 
+        let p = Path "test17 - worker and completed event"
+        let work = async {
+            do p.Check 1
+            do! Async.Sleep 300
+            do p.Check 3
+            return 4
+        }
+        let worker = AsyncWorker(work)
+        worker.Completed.Add(fun n -> p.Check n)
+        worker.RunAsync() |> ignore
+        System.Threading.Thread.Sleep 100
+        p.Check 2
+        System.Threading.Thread.Sleep 400
+        System.Windows.Forms.Application.DoEvents()
+        p.Check 5
+
+    [<Test>]
+    member this.AsyncWorkerTest18() = 
+        // Worker and canceled event (using group.TriggerCancel)
+        let p = Path "test18 - worker & group.TriggerCancel"
+        let work = async {
+            do p.Check 1
+            do System.Threading.Thread.Sleep 200
+            do p.Check 3
+            let! _ = async { return 1 } 
+            do ()
+        }
+        let group = new System.Threading.CancellationTokenSource()
+        let worker = AsyncWorker(work, group.Token)
+        worker.Canceled.Add(fun e -> p.Check 4)
+        worker.RunAsync() |> ignore
+        System.Threading.Thread.Sleep 100
+        p.Check 2
+        group.Cancel()
+        System.Windows.Forms.Application.DoEvents()
+        System.Threading.Thread.Sleep 500
+        System.Windows.Forms.Application.DoEvents()
+        System.Threading.Thread.Sleep 500
+        p.Check 5
+
+    [<Test>]
+    member this.AsyncWorkerTest19() = 
+        // Worker and canceled event (using worker.CancelAsync)
+        let p = Path "test19 - worker & worker.CancelAsync"
+        let work = async {
+            do p.Check 1
+            do System.Threading.Thread.Sleep 200
+            do p.Check 3
+            let! _ = async { return 1 } 
+            do ()
+        }
+        let group = new System.Threading.CancellationTokenSource()
+        let worker = AsyncWorker(work)
+        worker.Canceled.Add(fun e -> p.Check 4)
+        worker.RunAsync() |> ignore
+        System.Threading.Thread.Sleep 100
+        p.Check 2
+        worker.CancelAsync("hello")
+        System.Threading.Thread.Sleep 500
+        System.Windows.Forms.Application.DoEvents()
+        p.Check 5
+
+
+    [<Test>]
+    member this.AsyncWorkerTest20() = 
+        // Worker and exceptions event
+        let p = Path "test20 - worker and exceptions"
+        let work = async {
+            do p.Check 1
+            do failwith "hello world"
+        }
+        let group = new System.Threading.CancellationTokenSource()
+        let worker = AsyncWorker(work, group.Token)
+        worker.Canceled.Add(fun _ -> p.Check -1)
+        worker.Completed.Add(fun _ -> p.Check -1)
+        worker.Error.Add(fun e -> test "test20" (e.Message = "hello world"); p.Check 2)
+        worker.RunAsync() |> ignore
+        System.Threading.Thread.Sleep 50
+        System.Windows.Forms.Application.DoEvents()
+        System.Threading.Thread.Sleep 50
+        p.Check 3
+
+    [<Test>]
+    member this.AsyncWorkerTest21() = 
+        // Worker and report progress
+        let p = Path "test21 - worker & report progress"
+        let rec work = async {
+            for i in 1 .. 49 do
+                do worker.ReportProgress i
+                do printfn "report %d" i
+                do System.Threading.Thread.Sleep 1
+          }
+        and worker: AsyncWorker<_> = AsyncWorker(work)
+        worker.ProgressChanged.Add(fun n -> p.Check n)
+        worker.RunAsync() |> ignore
+        for i in 1 .. 150 do
+            System.Threading.Thread.Sleep 10
+            System.Windows.Forms.Application.DoEvents()
+        p.Check 50
+
+(*
+    [<Test>]
+    member this.AsyncWorkerTest21() = 
+        let form = new System.Windows.Forms.Form()
+        form.Load.Add(fun _ ->
+            test16(); 
+            // ToDo: 7/25/2008: Disabled because of probable timing issue.  QA needs to re-enable post-CTP.
+            // Tracked by bug FSharp 1.0:2891
+            //test17(); 
+            test18(); 
+            test19(); 
+            test20(); 
+            test21()
+            System.Windows.Forms.Application.Exit())
+        System.Windows.Forms.Application.Run(form)
+        // Set the synchronization context back to its original value
+        System.Threading.SynchronizationContext.SetSynchronizationContext(null);
+*)
+
+#endif
+    [<Test>]
+    member this.AsyncResultCellTests() = 
+
+        
+        let doWait(e1 : WaitHandle) (e2 : WaitHandle) s1 s2 =
+            if e2.WaitOne() then
+                if e1.WaitOne() then
+                    (!s1) + (!s2)
+                else "e2WaitFailed"
+            else "e1WaitFailed"
+        
+        do 
+            for i in 1..50 do
+                check
+                    (sprintf "hdfegdfyw6732: AsyncResultCell %d" i)
+                    (let cell = new AsyncResultCell<string>()
+                     use e1 = new ManualResetEvent(false)
+                     let s1 = ref ""
+                     use e2 = new ManualResetEvent(false)
+                     let s2 = ref ""
+                     async { 
+                        do! Async.Sleep(100)
+                        let! result = cell.AsyncResult 
+                        //printfn "Here we are!(1)"
+                        s1 := result; e1.Set() |> ignore 
+                     } |> Async.Start
+                     async { 
+                        let! result = cell.AsyncResult 
+                        //printfn "Here we are!(2)"
+                        s2 := result; e2.Set() |> ignore 
+                     } |> Async.Start
+                     ThreadPool.QueueUserWorkItem(fun _ -> cell.RegisterResult(AsyncOk "hello")) |> ignore
+                     doWait e1 e2 s1 s2
+                    )
+                    "hellohello"
+
+
+        
+        do 
+            for i in 1..50 do
+                check
+                    (sprintf "hdfegdfyw6732: AsyncResultCell w/exception %d" i)
+                    (let cell = new AsyncResultCell<string>()
+                     use e1 = new ManualResetEvent(false)
+                     let s1 = ref ""
+                     use e2 = new ManualResetEvent(false)
+                     let s2 = ref ""
+                     let asyncToRun s (e:ManualResetEvent)=
+                        async {
+                            try 
+                                let! result = cell.AsyncResult in 
+                                s := result 
+                            with 
+                            |   ex -> s := ex.Message
+                            e.Set() |> ignore 
+                        }
+                     asyncToRun s1 e1 |> Async.Start
+                     asyncToRun s2 e2 |> Async.Start
+                     ThreadPool.QueueUserWorkItem(fun _ -> cell.RegisterResult(System.Exception("exn") |> AsyncException))  |> ignore
+                     doWait e1 e2 s1 s2        
+                    )
+                    "exnexn"
+
+        do check
+            "hdfegdfyw6732: AsyncResultCell + set result before wait starts"
+            (let cell = new AsyncResultCell<string>()
+             use e1 = new ManualResetEvent(false)
+             let s1 = ref ""
+             use e2 = new ManualResetEvent(false)
+             let s2 = ref ""
+             cell.RegisterResult(AsyncOk "hello") 
+             async { let! result = cell.AsyncResult in s1 := result; e1.Set() |> ignore } |> Async.Start
+             async { let! result = cell.AsyncResult in s2 := result; e2.Set() |> ignore } |> Async.Start
+             doWait e1 e2 s1 s2
+            )
+            "hellohello"
+            
+        do check
+            "hdfegdfyw6732: AsyncResultCell w/exception + set result before wait starts"
+            (let cell = new AsyncResultCell<string>()
+             use e1 = new ManualResetEvent(false)
+             let s1 = ref ""
+             use e2 = new ManualResetEvent(false)
+             let s2 = ref ""
+             let asyncToRun s (e:ManualResetEvent) =
+                async {
+                    try 
+                        let! result = cell.AsyncResult in 
+                        s := result 
+                    with 
+                    |  e -> s := e.Message
+                    e.Set() |> ignore 
+                }
+             cell.RegisterResult(Exception("exn") |> AsyncException) 
+             asyncToRun s1 e1 |> Async.Start
+             asyncToRun s2 e2 |> Async.Start
+             doWait e1 e2 s1 s2
+            )
+            "exnexn"
+
+    [<Test>]
+    member this.AsyncResultCellAgents() = 
+
+        let complement = function
+            | (Red, Yellow) | (Yellow, Red) -> Blue
+            | (Red, Blue) | (Blue, Red) -> Yellow
+            | (Yellow, Blue) | (Blue, Yellow) -> Red
+            | (Blue, Blue) -> Blue
+            | (Red, Red) -> Red
+            | (Yellow, Yellow) -> Yellow
+
+
+        let chameleon (meetingPlace : MailboxProcessor<Message>) initial = 
+            let rec loop c meets = async  {
+                    let resultCell = new AsyncResultCell<_>()
+                    meetingPlace.Post (c, resultCell)
+                    let! reply = resultCell.AsyncResult
+                    match reply with     
+                    | Some(newColor) -> return! loop newColor (meets + 1)
+                    | None -> return meets
+                }
+            loop initial 0
+            
+
+        let meetingPlace chams n = MailboxProcessor.Start(fun (processor : MailboxProcessor<Message>)->
+            let rec fadingLoop total = 
+                async   {
+                    if total <> 0 then
+                        let! (_, reply) = processor.Receive()
+                        reply.RegisterResult (AsyncOk None)
+                        return! fadingLoop (total - 1)
+                    else
+                        printfn "Done"
+                }
+            let rec mainLoop curr = 
+                async   {
+                    if (curr > 0) then
+                        let! (color1, reply1) = processor.Receive()
+                        let! (color2, reply2) = processor.Receive()
+                        let newColor = complement (color1, color2)
+                        reply1.RegisterResult(AsyncOk(Some(newColor)))
+                        reply2.RegisterResult(AsyncOk(Some(newColor)))
+                        return! mainLoop (curr - 1)
+                    else
+                        return! fadingLoop chams
+                }
+            mainLoop n
+            ) 
+            
+
+
+        let meetings = 100000
+        
+        let colors = [Blue; Red; Yellow; Blue]    
+        let mp = meetingPlace (colors.Length) meetings
+        let meets = 
+                colors 
+                    |> List.map (chameleon mp) 
+                    |> Async.Parallel 
+                    |> Async.RunSynchronously 
+
+        check "Chamenos" (Seq.sum meets) (meetings*2)
+
+    [<Test>]
+    member this.AsyncResultCellLightweightAgents() = 
+        let complement = function
+            | (Red, Yellow) | (Yellow, Red) -> Blue
+            | (Red, Blue) | (Blue, Red) -> Yellow
+            | (Yellow, Blue) | (Blue, Yellow) -> Red
+            | (Blue, Blue) -> Blue
+            | (Red, Red) -> Red
+            | (Yellow, Yellow) -> Yellow
+
+        let chameleon (meetingPlace : MailboxProcessor<Message>) initial = 
+            let rec loop c meets = async  {
+                    let resultCell = new AsyncResultCell<_>()
+                    meetingPlace.Post (c, resultCell)
+                    let! reply = resultCell.AsyncResult
+                    match reply with     
+                    | Some(newColor) -> return! loop newColor (meets + 1)
+                    | None -> return meets
+                }
+            loop initial 0
+            
+
+        let meetingPlace chams n = MailboxProcessor.Start(fun (processor : MailboxProcessor<Message>)->
+            let rec fadingLoop total = 
+                async   {
+                    if total <> 0 then
+                        let! (_, reply) = processor.Receive()
+                        reply.RegisterResult (AsyncOk None)
+                        return! fadingLoop (total - 1)
+                    else
+                        printfn "Done"
+                }
+            let rec mainLoop curr = 
+                async   {
+                    if (curr > 0) then
+                        let! (color1, reply1) = processor.Receive()
+                        let! (color2, reply2) = processor.Receive()
+                        let newColor = complement (color1, color2)
+                        reply1.RegisterResult(AsyncOk(Some(newColor)), reuseThread=true)
+                        reply2.RegisterResult(AsyncOk(Some(newColor)), reuseThread=true)
+                        return! mainLoop (curr - 1)
+                    else
+                        return! fadingLoop chams
+                }
+            mainLoop n
+            ) 
+
+
+
+        let meetings = 100000
+        
+        let colors = [Blue; Red; Yellow; Blue]    
+        let mp = meetingPlace (colors.Length) meetings
+        let meets = 
+                colors 
+                    |> List.map (chameleon mp) 
+                    |> Async.Parallel 
+                    |> Async.RunSynchronously 
+
+        check "Chamenos" (Seq.sum meets) (meetings*2)
+
diff --git a/src/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj b/src/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj
new file mode 100755
index 0000000..95a97fe
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <TOOLS Condition=" '$(TOOLS)' == '' ">>..\..\tools</TOOLS>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E2A0F944-E76E-4C53-B037-A050FDF7378A}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>FSharp.PowerPack.Unittests</RootNamespace>
+    <AssemblyName>FSharp.PowerPack.Unittests</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <StrongName>false</StrongName>
+    <!--->ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB}</ProjectTypeGuids-->
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>62</NoWarn>
+    <OtherFlags>--mlcompatibility</OtherFlags>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>62</NoWarn>
+    <OtherFlags>--mlcompatibility</OtherFlags>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Condition="'$(TargetFramework)' == 'Silverlight'" Include="NUnitFrameworkShims.fs" />    
+    <Compile Include="Utilities.fs" />
+    <Compile Include="HashtblTests.fs" />
+    <Compile Include="MatrixVectorTests.fs" />
+    <Compile Include="LazyListTests.fs" />
+    <Compile Include="CompatTests.fs" />
+    <Compile Include="ColllectionTests.fs" />
+    <Compile Include="ControlTests.fs" />
+    <Compile Include="SetMapTests.fs" />
+    <Compile Include="PermutationTests.fs" />
+    <Compile Condition="'$(TargetFramework)' == ''" Include="NativeArrayTests.fs" />
+    <Compile Include="BigRationalTests.fs" />
+    <Compile Include="QuotationEvalTests.fs" />
+    <Compile Include="StructuredFormatTests.fs" />
+    <Compile Condition="'$(TargetFramework)' == ''" Include="MetadataTests.fs" />
+    <Compile Condition="'$(TargetFramework)' == ''" Include="QueryTests.fs" />
+    <Compile Include="AsyncStreamReaderTest.fs" />
+    <Compile Condition="'$(TargetFramework)' == ''" Include="ASP.NET\AspNetTester.fs">
+      <Link>AspNetTester.fs</Link>
+    </Compile>
+    <None Include="blas.dll" />
+    <None Include="LAPACK.dll" />
+    <None Condition="'$(TargetFramework)' == ''" Include="NORTHWND.MDF">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Condition="'$(TargetFramework)'=='Silverlight'" Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.Common.targets"/>
+  <ItemGroup>    
+    <Reference Condition="'$(TargetFramework)' == ''" Include="northwnd">
+      <HintPath>northwnd.dll</HintPath>
+    </Reference>
+    <Reference Condition="'$(TargetFramework)' == ''" Include="nunit.framework">
+      <HintPath>$(TOOLS)\NUnit\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="mscorlib" />    
+    <Reference Include="System" />
+    <Reference Include="System.Core"/>
+    <Reference Include="System.Numerics" Condition="'$(TargetFrameworkVersion)' == 'v4.0'" />
+    <Reference Condition="'$(TargetFramework)' == ''" Include="System.Data" />
+    <Reference Condition="'$(TargetFramework)' == ''" Include="System.Data.Linq" />
+    <Reference Condition="'$(TargetFramework)' == ''" Include="System.Drawing" />
+    <Reference Condition="'$(TargetFramework)' == ''" Include="System.Windows.Forms" />
+    <ProjectReference Condition="'$(TargetFramework)' == ''"  Include="..\FSharp.Compiler.CodeDom\Fsharp.Compiler.CodeDom.fsproj">
+      <Project>{9EF49218-FD64-43A8-922B-84B1FF576773}</Project>
+      <Name>Fsharp.Compiler.CodeDom</Name>
+    </ProjectReference>
+    <ProjectReference Condition="'$(TargetFramework)' == ''"  Include="..\FSharp.PowerPack.Build.Tasks\FSharp.PowerPack.Build.Tasks.fsproj">
+      <Project>{A9566921-4193-4EC8-83FB-F5A0DC257678}</Project>
+      <Name>FSharp.PowerPack.Build.Tasks</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\FSharp.PowerPack.Compatibility\FSharp.PowerPack.Compatibility.fsproj">
+      <Name>FSharp.PowerPack.Compatibility</Name>
+      <Project>{6fc3b299-23cb-4098-998d-06c014431807}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\FSharp.PowerPack.Linq\FSharp.PowerPack.Linq.fsproj">
+      <Project>{4C2ED03B-5ACE-427B-8285-AD333E60F35E}</Project>
+      <Name>FSharp.PowerPack.Linq</Name>
+    </ProjectReference>
+    <ProjectReference Condition="'$(TargetFramework)' == ''"  Include="..\FSharp.PowerPack.Metadata\FSharp.PowerPack.Metadata.fsproj">
+      <Project>{816CB737-0648-4889-8662-54484D42824D}</Project>
+      <Name>FSharp.PowerPack.Metadata</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\FSharp.PowerPack\FSharp.PowerPack.fsproj">
+      <Project>{649FA588-F02E-457C-9FCF-87E46407481F}</Project>
+      <Name>FSharp.PowerPack</Name>
+    </ProjectReference>
+    <ProjectReference Condition="'$(TargetFramework)' == ''"  Include="..\FsHtmlDoc\FsHtmlDoc.fsproj">
+      <Project>{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}</Project>
+      <Name>FsHtmlDoc</Name>
+    </ProjectReference>
+    <ProjectReference Condition="'$(TargetFramework)' == ''"  Include="..\FsLex\FsLex.fsproj">
+      <Project>{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}</Project>
+      <Name>FsLex</Name>
+    </ProjectReference>
+    <ProjectReference Condition="'$(TargetFramework)' == ''"  Include="..\FsYacc\FsYacc.fsproj">
+      <Project>{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}</Project>
+      <Name>FsYacc</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj.vspscc b/src/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FSharp.PowerPack.Unittests/HashtblTests.fs b/src/FSharp.PowerPack.Unittests/HashtblTests.fs
new file mode 100755
index 0000000..3262a36
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/HashtblTests.fs
@@ -0,0 +1,93 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+
+#nowarn "40"
+
+[<TestFixture>]
+type public HashtblTests() =
+
+  
+    [<Test>]
+    member this.BasicTests() = 
+
+            printf "I am running";
+            let map1 = Hashtbl.create 5 in
+            Hashtbl.add map1 5 5;
+            Hashtbl.add map1 17 17;
+            Hashtbl.add map1 94 94;
+            let map2 = Hashtbl.copy map1 in
+            Hashtbl.replace map1 5 7;
+            Hashtbl.replace map1 17 19;
+            check "21980d3" (Hashtbl.find map1 17) 19;    
+            check "21980d3" (Hashtbl.find map1 5) 7;    
+            check "21980d3" (Hashtbl.find map1 94) 94;    
+
+            check "21980d3" (Hashtbl.find_all map1 17) [19];    
+            check "21980d3" (Hashtbl.find_all map1 5) [7];    
+            check "21980d3" (Hashtbl.find_all map1 94) [94];    
+
+            check "21980d3" (Hashtbl.find map2 5) 5;    
+            check "21980d3" (Hashtbl.find map2 17) 17;    
+            check "21980d3" (Hashtbl.find map2 94) 94;    
+
+            check "21980d3" (Hashtbl.find_all map2 5) [5];    
+            check "21980d3" (Hashtbl.find_all map2 17) [17];    
+            check "21980d3" (Hashtbl.find_all map2 94) [94];    
+            printf "I am done"
+
+    [<Test>]
+    member this.NameResolutions() = 
+
+        // check name resolutions
+        let topEnvTable1 = new Microsoft.FSharp.Collections.HashSet<string>(10, HashIdentity.Structural)
+        let topEnvTable2 = new Microsoft.FSharp.Collections.HashMultiMap<string,int>(10, HashIdentity.Structural)
+        ()
+
+    [<Test>]
+    member this.MiscSamples() = 
+        let SampleHashtbl1() =
+            let tab = Microsoft.FSharp.Collections.HashMultiMap(30, HashIdentity.Structural) 
+            let data = "The quick brown fox jumps over the lazy dog" 
+            for i = 0 to data.Length - 1 do 
+                let c = data.Chars(i) 
+                match tab.TryFind(c) with 
+                | None -> tab.Add(c,1)
+                | Some v -> tab.Replace(c,v+1)
+            tab |> Seq.iter (fun (KeyValue(c,v)) -> printf "Number of '%c' characters = %d\n" c v) 
+          
+        let SampleHashtbl1b() =
+            let tab = Microsoft.FSharp.Collections.HashMultiMap<_,_>(30, HashIdentity.Structural) 
+            let data = "The quick brown fox jumps over the lazy dog" 
+            for i = 0 to data.Length - 1 do 
+                let c = data.Chars(i) 
+                match tab.TryFind(c) with 
+                | None -> tab.Add(c,1)
+                | Some v -> tab.Replace(c,v+1)
+            tab |> Seq.iter (fun (KeyValue(c,v)) -> printf "Number of '%c' characters = %d\n" c v) 
+          
+
+        let SampleHashtbl2() =
+            let tab = Hashtbl.create 30 
+            let data = "The quick brown fox jumps over the lazy dog" 
+            for i = 0 to data.Length - 1 do 
+                let c = data.Chars(i) 
+                match Hashtbl.tryfind tab c with 
+                | None -> Hashtbl.add tab c 1
+                | Some v -> Hashtbl.replace tab c (v+1)
+            Hashtbl.iter (fun c v -> printf "Number of '%c' characters = %d\n" c v) tab
+          
+          
+        let x1 = new HashMultiMap<int,int>(10, HashIdentity.Structural)
+        let x2 = HashMultiMap<int,Set<int>>(10, HashIdentity.Structural)
+        let x3 = HashMultiMap<int,Set<Set<int>>>(10, HashIdentity.Structural)
+        let x4 = HashMultiMap<int,Set<Set<Set<int>>>>(10, HashIdentity.Structural)
+        let x5 = HashMultiMap<int,Set<Set<Set<int>> >>(10, HashIdentity.Structural)
+        let x6 = HashMultiMap<int,Set<Set<Set<int> > >>(10, HashIdentity.Structural)
+        let x7 = HashMultiMap<int,Set<Set<Set<int> > > >(10, HashIdentity.Structural)
+        let x8 = HashMultiMap<int,Set<Set<Set<int>>> >(10, HashIdentity.Structural)
+        let x9 = HashMultiMap<Set<Set<int>>,int>(10, HashIdentity.Structural)
+        let x10 = HashMultiMap<Set<Set<int>>,Set<int>>(10, HashIdentity.Structural)
+        let x11 = HashMultiMap<Set<Set<int>>,Set<Set<int>>>(10, HashIdentity.Structural)
+        ()
+        
+
diff --git a/src/FSharp.PowerPack.Unittests/LazyListTests.fs b/src/FSharp.PowerPack.Unittests/LazyListTests.fs
new file mode 100755
index 0000000..e042b02
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/LazyListTests.fs
@@ -0,0 +1,137 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+
+#nowarn "40"
+
+[<TestFixture>]
+type public ZZZ_LazyListTests() =
+  
+    [<Test>]
+    member this.BasicTests1() = 
+
+        let l = LazyList.ofList [1;2;3] in
+        let res = ref 2 in 
+        for i in (LazyList.toSeq l) do res := !res + i done;
+        check "test2398984: LazyList.toSeq" 8 !res;
+        let res = ref 2 in 
+        for i in LazyList.toSeq l do 
+            res := !res + i 
+        done;
+        check "test2398984: LazyList.toSeq" 8 !res
+  
+    [<Test>]
+    member this.BasicTests2() = 
+        let l = LazyList.ofList [1;2;3] in
+        let res = ref 2 in 
+        Seq.iter (fun i -> res := !res + i) (LazyList.toSeq l) 
+        check "test2398994: foreach, LazyList.toSeq" 8 !res
+
+    [<Test>]
+    member this.BasicTests3() = 
+
+        test "se1" (LazyList.isEmpty LazyList.empty)
+        test "se2" (not (LazyList.isEmpty (LazyList.cons 1 LazyList.empty)))
+        test "se3" (not (LazyList.isEmpty (LazyList.repeat 1)))
+        test "se4" (not (LazyList.isEmpty (LazyList.unfold (fun z -> Some (z,z+1)) 0)))
+
+        test "seq1" (LazyList.head (LazyList.cons 1 LazyList.empty) = 1)
+        test "seq2" (LazyList.head (LazyList.cons 1 (LazyList.cons 2 LazyList.empty)) = 1)
+        test "seq3" (LazyList.head (LazyList.tail (LazyList.cons 1 (LazyList.cons 2 LazyList.empty))) = 2)
+
+        let nats = LazyList.unfold (fun z -> Some (z,z+1)) 0 
+        test "take1" (LazyList.toList (LazyList.take 4 nats) = [0;1;2;3])
+        test "drop1" (LazyList.head (LazyList.skip 4 nats) = 4)
+        test "drop1" (LazyList.head (LazyList.skip 0 nats) = 0)
+
+        test "repeat" (LazyList.toList (LazyList.take 4 (LazyList.repeat 1)) = [1;1;1;1])
+        test "append" (LazyList.toList (LazyList.take 4 (LazyList.append (LazyList.cons 77 (LazyList.empty)) nats)) = [77;0;1;2])
+        test "zip"  (LazyList.toList (LazyList.take 3 (LazyList.zip nats (LazyList.skip 6 nats))) = [0,6;1,7; 2,8])
+        test "firstS" (LazyList.tryFind (fun x -> x>=8) nats = Some 8)
+        test "firstN" (LazyList.tryFind (fun x -> x>=8) (LazyList.take 5 nats) = None)
+        test "find S" (LazyList.find (fun x -> x>=8) nats = 8)
+        test "find N" (let res =
+                              try
+                                LazyList.find (fun x -> x>=8) (LazyList.take 5 nats)
+                              with
+                                  Not_found -> 9999
+                       res = 9999) (* testing for exception *)
+
+        let rec diverge () = diverge ()
+        test "consfA"       (LazyList.head (LazyList.consDelayed 1 diverge) = 1)
+        test "consfB"       (let ss = LazyList.tail (LazyList.consDelayed 1 diverge) in true) (* testing for lazy divergence *)
+        test "dropDiverge1" (let ss = LazyList.skip 1 (LazyList.consDelayed 1 diverge) in true) (* testing for lazy divergence *)
+        test "dropDiverge0" (let ss = LazyList.skip 0 (LazyList.delayed (fun () -> failwith "errors")) in true) (* testing for lazy divergence *)
+        test "takedrop" (LazyList.toList (LazyList.take 3 (LazyList.skip 4 nats)) = [4;5;6])
+
+        test "filter" (LazyList.toList (LazyList.take 4 (LazyList.filter (fun x -> x mod 2 = 0) nats))     = [0;2;4;6])
+        test "map"    (LazyList.toList (LazyList.take 4 (LazyList.map    (fun x -> x+1) nats))             = [1;2;3;4])
+        test "map2"   (LazyList.toList (LazyList.take 4 (LazyList.map2   (fun x y -> x*y) nats (LazyList.tail nats))) = [0*1;1*2;2*3;3*4])
+
+        test "array"  (Array.toList (LazyList.toArray (LazyList.take 6 nats)) = LazyList.toList (LazyList.take 6 nats))
+        test "array"  (LazyList.toList (LazyList.ofArray [|1;2;3;4|]) = LazyList.toList (LazyList.ofList [1;2;3;4]))
+
+        // This checks that LazyList.map, LazyList.length etc. are tail recursive
+        check "LazyList.length" (LazyList.ofSeq (Seq.init 100 (fun c -> c)) |> LazyList.length) 100
+        check "LazyList.length" (LazyList.ofSeq (Seq.init 1000000 (fun c -> c)) |> LazyList.length) 1000000
+        check "LazyList.length" (LazyList.ofSeq (Seq.init 0 (fun c -> c)) |> LazyList.length) 0
+        check "LazyList.map" (LazyList.map (fun x -> x + 1) (LazyList.ofSeq (Seq.init 1000000 (fun c -> c))) |> Seq.length) 1000000
+        check "LazyList.filter" (LazyList.filter (fun x -> x % 2 = 0) (LazyList.ofSeq (Seq.init 1000000 (fun c -> c))) |> Seq.length) 500000
+        check "LazyList.iter" (let count = ref 0 in LazyList.iter (fun x -> incr count) (LazyList.ofSeq (Seq.init 0 (fun c -> c))); !count) 0
+        check "LazyList.iter" (let count = ref 0 in LazyList.iter (fun x -> incr count) (LazyList.ofSeq (Seq.init 1000000 (fun c -> c))); !count) 1000000
+        check "LazyList.toList" (LazyList.toList (LazyList.ofSeq (Seq.init 200000 (fun c -> c))) |> Seq.length) 200000
+        check "LazyList.toArray" (LazyList.toArray (LazyList.ofSeq (Seq.init 200000 (fun c -> c))) |> Seq.length) 200000
+
+        /// check exists on an infinite stream terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (LazyList.repeat "a" |> LazyList.toSeq)) true
+        /// check a succeeding 'exists' on a concat of an infinite number of finite streams terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (Seq.concat (LazyList.repeat [| "a"; "b"|] |> LazyList.toSeq))) true
+        /// check a succeeding 'exists' on a concat of an infinite number of infinite streams terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (Seq.concat (LazyList.repeat (LazyList.repeat "a" |> LazyList.toSeq) |> LazyList.toSeq))) true
+        /// check a failing for_all on an infinite stream terminates
+        check "IEnumerableTest.exists" (Seq.forall ((=) "a" >> not) (LazyList.repeat "a" |> LazyList.toSeq)) false
+        /// check a failing for_all on a concat of an infinite number of finite streams terminates
+        check "IEnumerableTest.exists" (Seq.forall ((=) "a" >> not) (Seq.concat (LazyList.repeat [| "a"; "b"|] |> LazyList.toSeq))) false
+        check "IEnumerableTest.append, infinite, infinite, then take" (Seq.take 2 (Seq.append (LazyList.repeat "a" |> LazyList.toSeq) (LazyList.repeat "b" |> LazyList.toSeq)) |> Seq.toList) [ "a"; "a" ]
+        /// check exists on an infinite stream terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (LazyList.repeat "a" |> LazyList.toSeq |> countEnumeratorsAndCheckedDisposedAtMostOnce)) true
+        check "<dispoal>" !numActiveEnumerators 0
+        /// check a succeeding 'exists' on a concat of an infinite number of finite streams terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (Seq.concat (LazyList.repeat [| "a"; "b"|] |> LazyList.toSeq |> countEnumeratorsAndCheckedDisposedAtMostOnce))) true
+        check "<dispoal>" !numActiveEnumerators 0
+        /// check a succeeding 'exists' on a concat of an infinite number of infinite streams terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (Seq.concat (LazyList.repeat (LazyList.repeat "a" |> LazyList.toSeq) |> LazyList.toSeq |> countEnumeratorsAndCheckedDisposedAtMostOnce))) true
+        check "<dispoal>" !numActiveEnumerators 0
+        /// check a failing for_all on an infinite stream terminates
+        check "IEnumerableTest.exists" (Seq.forall ((=) "a" >> not) (LazyList.repeat "a" |> LazyList.toSeq |> countEnumeratorsAndCheckedDisposedAtMostOnce)) false
+        check "<dispoal>" !numActiveEnumerators 0
+
+        /// check a failing for_all on a concat of an infinite number of finite streams terminates
+        check "<dispoal>" !numActiveEnumerators 0
+        check "IEnumerableTest.exists" (Seq.forall ((=) "a" >> not) (Seq.concat (LazyList.repeat [| "a"; "b"|] |> LazyList.toSeq |> countEnumeratorsAndCheckedDisposedAtMostOnce))) false
+        check "<dispoal>" !numActiveEnumerators 0
+        check "IEnumerableTest.append, infinite, infinite, then take" (Seq.take 2 (Seq.append (LazyList.repeat "a" |> LazyList.toSeq) (LazyList.repeat "b" |> LazyList.toSeq)) |> countEnumeratorsAndCheckedDisposedAtMostOnceAtEnd |> Seq.toList) [ "a"; "a" ]
+        check "<dispoal>" !numActiveEnumerators 0
+    
+
+    [<Test>]
+    member this.PatternsTests() = 
+
+        let matchTwo ll = 
+            match ll with 
+            | LazyList.Cons(h1,LazyList.Cons(h2,t)) -> printf "%O,%O\n" h1 h2
+            | LazyList.Cons(h1,t) -> printf "%O\n" h1
+            | LazyList.Nil() -> printf "empty!\n" 
+
+        let rec pairReduce xs =
+          match xs with
+            | LazyList.Cons (x, LazyList.Cons (y,ys)) -> LazyList.consDelayed (x+y) (fun () -> pairReduce ys)
+            | LazyList.Cons (x, LazyList.Nil)      -> LazyList.cons x LazyList.empty
+            | LazyList.Nil                 -> LazyList.empty 
+
+        let rec inf = LazyList.consDelayed 0 (fun () -> LazyList.map (fun x -> x + 1) inf)
+
+        let ll = LazyList.ofList [1;2;3;4]
+        check "we09wek" (sprintf "%A" (LazyList.toList (LazyList.take 10 (pairReduce inf)))) "[1; 5; 9; 13; 17; 21; 25; 29; 33; 37]"
+
+        check "we09wek" (LazyList.scan (+) 0 (LazyList.ofList [1;2])  |> LazyList.toList)  [0;1;3]
+        check "we09wek" (LazyList.scan (+) 0 (LazyList.ofList [])  |> LazyList.toList)  [0]
diff --git a/src/FSharp.PowerPack.Unittests/LibraryTestFx.fs b/src/FSharp.PowerPack.Unittests/LibraryTestFx.fs
new file mode 100755
index 0000000..f84a5ab
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/LibraryTestFx.fs
@@ -0,0 +1,47 @@
+
+module FSharp.PowerPack.LibraryTestFx
+
+open System
+open System.Collections.Generic
+
+open NUnit.Framework
+
+// Workaround for bug 3601, we are issuing an unnecessary warning
+#nowarn "0004"
+
+/// Check that the lamda throws an exception of the given type. Otherwise
+/// calls Assert.Fail()
+let private CheckThrowsExn<'a when 'a :> exn> (f : unit -> unit) =
+    let funcThrowsAsExpected =
+        try
+            let _ = f ()
+            false // Did not throw!
+        with
+        | :? 'a
+            -> true   // Thew null ref, OK
+        | _ -> false  // Did now throw a null ref exception!
+    if funcThrowsAsExpected
+    then ()
+    else Assert.Fail()
+
+// Illegitimate exceptions. Once we've scrubbed the library, we should add an
+// attribute to flag these exception's usage as a bug.
+let CheckThrowsNullRefException      f = CheckThrowsExn<NullReferenceException>   f
+let CheckThrowsIndexOutRangException f = CheckThrowsExn<IndexOutOfRangeException> f
+
+// Legit exceptions
+let CheckThrowsNotSupportedException f = CheckThrowsExn<NotSupportedException>    f
+let CheckThrowsArgumentException     f = CheckThrowsExn<ArgumentException>        f
+let CheckThrowsArgumentNullException f = CheckThrowsExn<ArgumentNullException>    f
+let CheckThrowsKeyNotFoundException  f = CheckThrowsExn<KeyNotFoundException>     f
+let CheckThrowsDivideByZeroException f = CheckThrowsExn<DivideByZeroException>    f
+let CheckThrowsInvalidOperationExn   f = CheckThrowsExn<InvalidOperationException> f
+
+// Verifies two sequences are equal (same length, equiv elements)
+let VerifySeqsEqual seq1 seq2 =
+    if Seq.length seq1 <> Seq.length seq2 then Assert.Fail()
+    
+    let zippedElements = Seq.zip seq1 seq2
+    if zippedElements |> Seq.forall (fun (a, b) -> a = b) 
+    then ()
+    else Assert.Fail()
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/MatrixVectorTests.fs b/src/FSharp.PowerPack.Unittests/MatrixVectorTests.fs
new file mode 100755
index 0000000..0e44907
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/MatrixVectorTests.fs
@@ -0,0 +1,1686 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+
+module MG = Microsoft.FSharp.Math.Matrix.Generic
+module MDouble  = Math.Matrix
+module VGeneric = Math.Vector.Generic
+module VDouble  = Math.Vector
+
+#nowarn "44" // This construct is deprecated. 
+
+module Notation = 
+
+    type matrix = Matrix<float>
+    type vector = Vector<float>
+    type rowvec = RowVector<float>
+    type complex = Complex
+  
+    let gmatrix ll = Matrix.Generic.ofSeq ll
+    let gvector l = Vector.Generic.ofSeq  l
+    let growvec l = RowVector.Generic.ofSeq l
+      
+    let S x = Matrix.Generic.ofScalar x
+    let RV x = Matrix.Generic.ofRowVector x 
+    let V x  = Matrix.Generic.ofVector x
+    let M2V x = Matrix.Generic.toVector x
+    let M2RV x = Matrix.Generic.toRowVector x
+    let M2S x = Matrix.Generic.toScalar x
+
+    let complex x y = Complex.mkRect (x,y)
+    // Notational conveniences
+    let matrix ll = Matrix.ofSeq ll
+    let vector l = Vector.ofSeq l
+    let rowvec l = RowVector.ofSeq l
+
+// This code used to be in the power pack but is now part of these tests
+module LinearAlgebra = 
+        let inline sumfR f (a,b) =
+            let mutable res = 0.0 in
+            for i = a to b do
+                res <- res + f i;
+            done;
+            res
+
+        let isSymmetric a = a |> Matrix.foralli (fun i j aij -> aij = a.[j,i]) 
+        let isLowerTriangular a = a |> Matrix.foralli (fun i j aij -> i>=j || aij=0.0)
+
+        let choleskyFactor (a: matrix) =
+          let nA,mA = a.Dimensions in
+          if nA<>mA              then invalid_arg "choleskyFactor: not square";
+          if not (isSymmetric a) then invalid_arg "choleskyFactor: not symmetric";
+          let lres = Matrix.zero nA nA  in(* nA=mA *)
+          for j=0 to nA-1 do
+            for i=j to nA-1 do (* j <= i *)
+              let psum = sumfR (fun k -> lres.[i,k] * lres.[j,k]) (0,j-1) in
+              let a_ij = a.[i,j] in
+              if i=j then
+                lres.[i,i] <- (System.Math.Sqrt (a_ij - psum))
+              else
+                lres.[i,j] <- ((a_ij - psum) / lres.[j,j])
+          lres
+
+        let lowerTriangularInverse (l: matrix) =
+          let nA,mA = l.Dimensions in
+          let res = Matrix.zero nA nA  in (* nA=mA *)
+          for j=0 to nA-1 do
+            for i=j to nA-1 do (* j <= i *)
+              let psum   = sumfR (fun k -> l.[i,k] * res.[k,j]) (0,i-1) in
+              let id_ij  = if i=j then 1.0 else 0.0 in
+              let res_ij = (id_ij - psum) / l.[i,i] in
+              res.[i, j] <- res_ij
+          res
+
+        let symmetricInverse a =
+          let l     = choleskyFactor a         in
+          let l_t   = l.Transpose                in 
+          let l_inv = lowerTriangularInverse l in
+          let a_inv = l_inv.Transpose * l_inv in
+          a_inv
+
+        let determinant (a: matrix) =
+          let rec det js ks =
+            match ks with
+              | []    -> 1.0
+              | k::ks -> 
+                let rec split sign (preJs,js) =
+                  match js with
+                  | []    -> 0.0
+                  | j::js -> sign * a.[j,k] * det (List.rev preJs @ js) ks
+                             +
+                             split (0.0 - sign) (j::preJs,js) in
+                split 1.0 ([],js) in
+          let nA,mA = a.Dimensions in
+          if nA<>mA then invalid_arg "determinant: not square";
+          det [0..nA-1] [0..nA-1]
+
+        let cholesky a =
+          let l    = choleskyFactor         a in
+          let lInv = lowerTriangularInverse l in
+          l,lInv
+
+open Notation
+open LinearAlgebra
+
+[<TestFixture>]
+type public MatrixVectorTests() =
+  
+    [<Test>]
+    member this.VectorSlicingTests() = 
+
+            let v1 = vector [| 1.0;2.0;3.0;4.0;5.0;6.0 |]
+            test "vslice1923" (v1.[*] = v1)
+            test "vslice1923" (v1.[0..] = v1)
+            test "vslice1924" (v1.[1..] = vector [| 2.0;3.0;4.0;5.0;6.0 |])
+            test "vslice1925" (v1.[2..] = vector [| 3.0;4.0;5.0;6.0 |])
+            test "vslice1926" (v1.[5..] = vector [| 6.0 |])
+            test "vslice1927" (v1.[6..] = vector [| |])
+            test "vslice1928" (try v1.[7..] |> ignore; false with _ -> true)
+            test "vslice1929" (try v1.[-1 ..] |> ignore; false with _ -> true)
+            test "vslice1917" (v1.[..0] = vector [| 1.0 |])
+            test "vslice1911" (v1.[..1] = vector [| 1.0;2.0|])
+            test "vslice1912" (v1.[..2] = vector [| 1.0;2.0;3.0 |])
+            test "vslice1913" (v1.[..3] = vector [| 1.0;2.0;3.0;4.0|])
+            test "vslice1914" (v1.[..4] = vector [| 1.0;2.0;3.0;4.0;5.0 |])
+            test "vslice1915" (v1.[..5] = vector [| 1.0;2.0;3.0;4.0;5.0;6.0 |])
+            test "vslice1918" (try v1.[..6] |> ignore; false with _ -> true)
+            test "vslice1817" (v1.[1..0] = vector [|  |])
+            test "vslice1811" (v1.[1..1] = vector [| 2.0 |])
+            test "vslice1812" (v1.[1..2] = vector [| 2.0;3.0 |])
+            test "vslice1813" (v1.[1..3] = vector [| 2.0;3.0;4.0|])
+            test "vslice1814" (v1.[1..4] = vector [| 2.0;3.0;4.0;5.0|])
+            test "vslice1815" (v1.[1 ..5] = vector [| 2.0;3.0;4.0;5.0;6.0|])
+            test "vslice1818" (try v1.[1..6] |> ignore; false with _ -> true)
+
+    [<Test>]
+    member this.MatrixSlicingTests() = 
+
+        let m1 = matrix [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |];
+                           [| 10.0;20.0;30.0;40.0;50.0;60.0 |]  |]
+        test "mslice1923" (m1.[*,*] = m1)
+        test "mslice1924" (m1.[0..,*] = matrix [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |];
+                                                  [| 10.0;20.0;30.0;40.0;50.0;60.0 |]  |])
+        test "mslice1924" (m1.[1..,*] = matrix [| //[| 1.0;2.0;3.0;4.0;5.0;6.0 |];
+                                                  [| 10.0;20.0;30.0;40.0;50.0;60.0 |]  |])
+        test "mslice1924" (m1.[..0,*] = matrix [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |];
+                                                  //[| 10.0;20.0;30.0;40.0;50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,0..] = matrix [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |];
+                                                  [| 10.0;20.0;30.0;40.0;50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,1..] = matrix [| [| 2.0;3.0;4.0;5.0;6.0 |];
+                                                  [| 20.0;30.0;40.0;50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,2..] = matrix [| [| 3.0;4.0;5.0;6.0 |];
+                                                  [| 30.0;40.0;50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,3..] = matrix [| [| 4.0;5.0;6.0 |];
+                                                  [| 40.0;50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,4..] = matrix [| [| 5.0;6.0 |];
+                                                  [| 50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,5..] = matrix [| [| 6.0 |];
+                                                  [| 60.0 |]  
+                                                |])
+
+    [<Test>]
+    member this.SomeSlicingTests() = 
+
+        let M = matrix [[ 0.0; 1.0; 2.0];[ 0.0; 1.0; 2.0];[ 0.0; 1.0; 2.0]]
+
+        check "ce0cew9js" M.[0..,0..] M
+        M.[1..2,0..1] <- matrix [[ 10.0;11.0];[ 12.0;13.0]]
+        check "ce0cew9js" M.[0..,0..] (matrix [[ 0.0; 1.0; 2.0];[ 10.0; 11.0; 2.0];[ 12.0; 13.0; 2.0]])
+
+        
+    [<Test>]
+    member this.ComplexOpsTest() = 
+
+        do test "989w42rra1" ((complex 1.0 2.0).RealPart = 1.0)
+        do test "989w42rra2" ((complex 1.0 2.0).ImaginaryPart = 2.0)
+        do test "989w42rra3" ((complex 1.0 2.0).i = 2.0)
+        do test "989w42rra4" ((complex 1.0 2.0).r = 1.0)
+        do test "989w42rra5" ((complex 3.0 4.0).Magnitude = 5.0)
+        do test "989w42rra6" ((complex 1.0 0.0).Phase = 0.0)
+        do test "989w42rra7" ((complex 1.0 0.0).Conjugate = (complex 1.0 0.0))
+        do test "989w42rra8" (Math.Complex.Create(1.0,2.0) = (complex 1.0 2.0))
+        do test "989w42rra9" (Math.Complex.Zero = complex 0.0 0.0)
+        do test "989w42rra0" (Math.Complex.Zero = Math.Complex.CreatePolar(0.0,1.0))
+        do test "989w42rra11" (Math.Complex.One = complex 1.0 0.0)
+        do test "989w42rra12" (Math.Complex.OneI = complex 0.0 1.0)
+        do test "989w42rra13" ((complex 2.0 0.0) = Math.Complex.CreatePolar(2.0,0.0) )
+        do test "989w42rra14" (complex 1.0 2.0 + complex (-1.0) (-2.0) = complex 0.0 0.0)
+        do test "989w42rra15" (complex 1.0 2.0 - (-(complex (-1.0) (-2.0))) = complex 0.0 0.0)
+        do test "989w42rra16" ((complex 1.0 0.0) * complex (-1.0) 0.0 = complex (-1.0) 0.0)
+        do test "989w42rra17" ((complex 1.0 0.0) * 2.0 = complex 2.0 0.0)
+        do test "989w42rra18" (2.0 * (complex 1.0 0.0) = complex 2.0 0.0)
+
+        do test "vrkhwe3r4y19" ((complex 1.0 1.0).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "1r+1i")
+        do test "vrkhwe3r4y20" ((complex 1.0 (-1.0)).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "1r-1i")
+        do test "vrkhwe3r4y21" ((complex (-1.0) (-1.0)).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "-1r-1i")
+        do test "vrkhwe3r4y22" ((complex (-1.0) 1.0).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "-1r+1i")
+        do test "vrkhwe3r4y23" ((complex (-1.0) 0.0).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "-1r+0i")
+        do test "vrkhwe3r4y24" ((complex 0.0 0.0).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "0r+0i")
+
+    [<Test>]
+    member this.MatrixOpsTest() = 
+
+        test "989w42rra" (Matrix.get (matrix [[1.0;2.0;1.0]]) 0 0 = 1.0)
+        test "989w42rrb" (Matrix.get (Matrix.zero 1 2) 0 0 = 0.0)
+        test "989w42rrc" (Matrix.get (Matrix.zero 1 2) 0 1 = 0.0)
+        test "989w42rrd" (Matrix.get (Matrix.create 1 2 1.1) 0 0 = 1.1)
+        test "989w42rre" (Matrix.get (Matrix.create 1 2 1.1) 0 1 = 1.1)
+        test "989w42rrf" (Matrix.get (Matrix.constDiag 2 1.1) 0 0 = 1.1)
+        test "989w42rrg" (Matrix.get (Matrix.constDiag 2 1.1) 0 1 = 0.0)
+        test "989w42rrh" (Matrix.get (Matrix.constDiag 2 1.1) 1 0 = 0.0)
+        test "989w42rri" (Matrix.get (Matrix.constDiag 2 1.1) 1 1 = 1.1)
+        test "989w42rrj" ((matrix [[1.0;2.0;1.0]]).Item(0,0) = 1.0)
+        test "989w42rrk" ((matrix [[1.0;2.0;1.0]]).Item(0,1) = 2.0)
+        test "989w42rrl" ((matrix [[1.0;2.0;1.0]]).Item(0,2) = 1.0)
+        test "989w42rr1" ((matrix [[1.0;2.0;1.0]]).[0,0] = 1.0)
+        test "989w42rr2" ((matrix [[1.0;2.0;1.0]]).[0,1] = 2.0)
+        test "989w42rr3" ((matrix [[1.0;2.0;1.0]]).[0,2] = 1.0)
+        test "989h42rr" ((matrix [[1.0;2.0;1.0]]).Dimensions = (1,3))
+        test "8f3fo3ij" ((matrix [[1.0];[2.0];[1.0]]).Dimensions = (3,1))
+        test "989hf2f2a" (Matrix.toScalar (Matrix.mul (matrix [[1.0;2.0;1.0]]) (matrix [[1.0];[2.0];[1.0]])) = 6.0)
+
+        test "989hf2f2b" ((let m = matrix [[1.0;2.0;1.0]] in 
+                           Matrix.inplace_add m (matrix [[1.0;2.0;3.0]]);
+                           m) = matrix [[2.0;4.0;4.0]])
+
+        test "989hf2f2c" (Matrix.toScalar (matrix [[1.0;2.0;1.0]] * matrix [[1.0];[2.0];[1.0]]) = 6.0)
+        test "989hf2f2d" (Matrix.toScalar (matrix [[1.0;2.0]; [3.0;4.0]] * 
+                              matrix [[1.0;2.0];[1.0;2.0]]) = 3.0)
+        test "989hf2f2e" (compare (matrix [[1.0]]) (matrix [[1.0]]) = 0)
+        test "989hf2f2f" (compare (matrix [[1.0]]) (matrix [[2.0]]) = -1)
+        test "989hf2f2g" (compare (matrix [[2.0]]) (matrix [[1.0]]) = 1)
+        test "989hf2f2h" (-(matrix [[2.0]]) = matrix [[-2.0]])
+        test "989hf2f2i" (-(matrix [[2.0; -1.0]]) = matrix [[-2.0; 1.0]])
+        test "989hf2f2j" (matrix [[1.0;2.0]; [3.0;4.0]] * matrix [[1.0;2.0]; [1.0;2.0]] = matrix [[3.0;6.0]; [7.0; 14.0]])
+
+        test "989hf2f2q" (Matrix.getCol (matrix [[1.0;2.0]; 
+                                                 [3.0;4.0]]) 0 =
+                                 vector [1.0;
+                                         3.0])
+
+        test "989hf2f3q1" (Matrix.foldByCol (fun x y -> x@[y]) (RowVector.Generic.of_list []) (matrix [[]; []])   = (RowVector.Generic.of_list []))
+        test "989hf2f3q1" (Matrix.foldByCol (fun x y -> x+y) (RowVector.Generic.of_list []) (matrix [[]; []])   = (RowVector.Generic.of_list []))
+
+        test "989hf2f3q2" (Matrix.foldByCol (fun x y -> x@[y]) (RowVector.Generic.of_list [[];[]]) (matrix [[1.0;2.0]; [3.0;4.0]])   = (RowVector.Generic.of_list [[1.0;3.0];[2.0;4.0]]))
+        test "989hf2f3q2" (Matrix.foldByCol (fun x y -> x+y) (RowVector.Generic.of_list [0.0;0.0]) (matrix [[1.0;2.0]; [3.0;4.0]])   = (RowVector.Generic.of_list [4.0;6.0]))
+
+        test "989hf2f3q3" (Matrix.foldByCol (fun x y -> x@[y]) (RowVector.Generic.of_list [[];[]]) (matrix [[1.0;2.0]; [3.0;4.0]; [5.0;6.0]])   = (RowVector.Generic.of_list [[1.0;3.0;5.0];[2.0;4.0;6.0]]))
+        test "989hf2f3q3" (Matrix.foldByCol (fun x y -> x+y) (RowVector.Generic.of_list [0.0;0.0]) (matrix [[1.0;2.0]; [3.0;4.0]; [5.0;6.0]])   = (RowVector.Generic.of_list [9.0;12.0]))
+
+        test "989hf2f3r4" (Matrix.foldByRow (fun x y -> x@[y]) (Vector.Generic.of_list [[];[]]) (matrix [[1.0;2.0]; [3.0;4.0]])   = (Vector.Generic.of_list [[1.0;2.0];[3.0;4.0]]))
+        test "989hf2f3r4" (Matrix.foldByRow (fun x y -> x+y) (Vector.Generic.of_list [0.0;0.0]) (matrix [[1.0;2.0]; [3.0;4.0]])   = (Vector.Generic.of_list [3.0;7.0]))
+
+        test "989hf2f3r5" (Matrix.foldByRow (fun x y -> x@[y]) (Vector.Generic.of_list [[];[];[]]) (matrix [[1.0;2.0]; [3.0;4.0]; [5.0;6.0]])   = (Vector.Generic.of_list [[1.0;2.0];[3.0;4.0]; [5.0;6.0];]))
+        test "989hf2f3r5" (Matrix.foldByRow (fun x y -> x+y) (Vector.Generic.of_list [0.0;0.0;0.0]) (matrix [[1.0;2.0]; [3.0;4.0]; [5.0;6.0]])   = (Vector.Generic.of_list [3.0;7.0; 11.0;]))
+
+        test "989hf2f3r4" (Matrix.foldRow (fun x y -> x@[y]) [] (matrix [[1.0;2.0]; [3.0;4.0]]) 0   = [1.0;2.0])
+        test "989hf2f3r4" (Matrix.foldCol (fun x y -> x@[y]) [] (matrix [[1.0;2.0]; [3.0;4.0]]) 0   = [1.0;3.0])
+        test "989hf2f3r4" (Matrix.foldRow (fun x y -> x@[y]) [] (matrix [[1.0;2.0]; [3.0;4.0]]) 1   = [3.0;4.0])
+        test "989hf2f3r4" (Matrix.foldCol (fun x y -> x@[y]) [] (matrix [[1.0;2.0]; [3.0;4.0]]) 1   = [2.0;4.0])
+
+
+        test "989hf2f2r1" (Matrix.getRow (matrix [[1.0;2.0]; 
+                                                 [3.0;4.0]]) 0 =
+                                 rowvec [1.0;2.0])
+
+        test "989hf2f2r2" (Matrix.getDiag (matrix [[1.0;2.0]; 
+                                                  [3.0;4.0]]) =
+                                 vector [1.0;4.0])
+
+        test "989hf2f2r3" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) 0 =
+                                 vector [1.0;4.0])
+
+        test "989hf2f2r4" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) 1 =
+                                 vector [2.0])
+
+        test "989hf2f2r5" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) 2 =
+                                 vector [])
+
+        test "989hf2f2r6" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) 3 =
+                                 vector [])
+
+        test "989hf2f2r7" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) (-1) =
+                                 vector [3.0])
+
+        test "989hf2f2r8" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) (-2) =
+                                 vector [])
+
+        test "989hf2f2s9" (Matrix.getRow (matrix [[1.0;2.0]; 
+                                                 [3.0;4.0]]) 1 =
+                                 rowvec [3.0;4.0])
+
+        test "989hf2f2tq" (Matrix.getRows (matrix [[1.0;2.0]; 
+                                                  [3.0;4.0]]) 1 1 =
+                                  (Matrix.ofRowVector (rowvec [3.0;4.0])))
+
+        test "989hf2f2u" (Matrix.getCols (matrix [[1.0;2.0]; 
+                                                  [3.0;4.0]]) 0 1 =
+                                  (Matrix.ofVector (vector [1.0;3.0])))
+        test "989hf2f2v" (Matrix.getRegion (matrix [[1.0;2.0]; 
+                                                    [3.0;4.0]]) 0 1 1 1 =
+                                  (matrix[[2.0]]))
+
+
+        test "989w42rrw" (Vector.range 0 3 = vector [0.0; 1.0; 2.0; 3.0])
+        test "989w42rrx" (Matrix.diag (vector [1.0; 2.0]) = matrix [[1.0;0.0]; 
+                                                             [0.0;2.0]])
+        test "989w42rry" (Vector.rangef 0.0 1.0 3.0 = vector [0.0; 1.0; 2.0; 3.0])
+        test "989w42rrz" (Vector.rangef 1.0 1.0 3.0 = vector [1.0; 2.0; 3.0])
+        test "989w42rra" (Vector.rangef 0.0 2.0 3.0 = vector [0.0; 2.0; 3.0])
+        test "989w42rrb" (determinant (matrix [[1.0]]) = 1.0)
+        test "989w42rrc" (determinant (matrix [[1.0;2.0];[3.0;4.0]]) = -2.0)
+
+        let a  = matrix [[1.0;2.0;1.0]; 
+                         [2.0;13.0;2.0]; 
+                         [1.0;2.0;5.0]]
+        let l  = choleskyFactor a
+        test "caeirj20" (l = matrix [[1.0; 0.0; 0.0];
+                                     [2.0; 3.0; 0.0];
+                                     [1.0; 0.0; 2.0]])
+        let lt = Matrix.transpose l
+        test "caeirj20" (l |> Matrix.transpose |> Matrix.transpose = l)
+        let a2 = l * lt
+        let zz = a2 - a
+        test "caeirj20" (zz = Matrix.zero 3 3)
+        let li = lowerTriangularInverse l
+        let uu1 = l * li  
+        let uu2 = li * l
+          
+        test "cdwioeu" (uu1 = matrix [[1.;0.;0.];[0.;1.;0.];[0.;0.;1.]])
+        test "cdwioeu" (uu2 = matrix [[1.;0.;0.];[0.;1.;0.];[0.;0.;1.]])
+
+        let m = matrix [[1.0;2.0;1.0];
+                        [3.0;8.0;5.0];
+                        [4.0;2.0;1.0]]
+        let d = determinant m
+        test "caeirj20" (d = 6.0)
+
+        
+        for i = 0 to 100000 do
+          ignore(determinant m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m .* m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m * m)
+        done
+        
+
+
+        let aa = Matrix.constDiag 2 2.0
+        let bb = Matrix.constDiag 2 1.5
+        let cc = aa + bb 
+        let dd = aa * cc
+
+        let xx = (Matrix.create 4 4 1.0) + (Matrix.constDiag 4 1.0)
+        let ll  = choleskyFactor xx
+        let llT = Matrix.transpose ll
+        let yy = ll * llT
+
+        let llInv = lowerTriangularInverse ll
+        let uu = ll * llInv
+        let aaa = Matrix.constDiag  4   1.0
+        let v   = Matrix.create 4 1 2.0
+        let w   = aaa * v
+
+        let zzz = aa + bb
+        let zz2 = aa * bb
+        let zz3 = 3.0 * bb
+        let zz4 = bb * 3.0
+        //let zz5 = bb * 3.0
+
+        zzz.Item(1,1) <- 3.0
+        test "ehoihoi" (zzz.Item(1,1) = 3.0)
+
+        zzz.[1,1] <- 4.0
+        test "ehoihoi" (zzz.[1,1] = 4.0)
+
+        
+    [<Test>]
+    member this.MiscRalfTest() = 
+
+        (*----------------------------------------------------------------------------
+        !* Ralf's test
+         *--------------------------------------------------------------------------*)
+            
+        let n = 30
+        let b = Matrix.randomize (Matrix.create n n 1.2)
+            
+        let testCholesky (b:matrix) =
+          let C = b * b.Transpose in
+          let d = choleskyFactor C in
+          let diff = d * d.Transpose - C in
+          let mm = Matrix.fold max 0.0 diff in
+          mm
+        
+
+        printf "minimum result = %O\n" (testCholesky b)
+        test "check very small" (testCholesky b < 0.000000001)
+
+    [<Test>]
+    member this.PermuteColumns() =
+        let u = matrix [ [1.;2.]; [3.;4.]; [5.;6.] ] 
+        let u' = u.PermuteColumns (fun j -> j)
+        Assert.AreEqual(u, u')
+
+        let u1 = matrix [ [1.;2.;3.]; [4.;5.;6.]; ] 
+        let u1' = u1.PermuteColumns (fun j -> 2 - j)
+        Assert.AreEqual(matrix [[3.;2.;1.]; [6.;5.;4.]], u1')
+
+        let u1transposed = u1.Transpose
+        Assert.AreEqual(matrix [[1.;4.];[2.;5.];[3.;6.]], u1transposed)
+
+       
+    [<Test>]
+    member this.PerfTest() = 
+        // sums over all elements of a vector
+
+        //-----------------------------------------------------
+        // Matrix Loop Perf: Example sumM1 (recommended, though sumM3 more explicitly better)
+        //
+        // This is simple code.  The indirect call in "Matrix.fold" may turn out to be a little
+        // costly, and either expanding by hand or using "inline" on Matrix.fold will
+        // help a lot (see sumM3)
+        let fold f z (A: matrix) = 
+          let mutable res = z in
+          for i = 0 to A.NumRows-1 do
+            for j = 0 to A.NumCols-1 do
+              res <- f res (A.Item(i, j));
+            done;
+          done;
+          res
+
+        let sumM1 (m:matrix) = fold (fun acc x -> acc + x) 0.0 m
+
+
+        //-----------------------------------------------------
+        // Matrix Loop Perf: Example sumM1a (recommended, though sumM3 more explicitly better)
+        //
+        // This is simple code.  The indirect call in "Matrix.fold" may turn out to be a little
+        // costly, and either expanding by hand or using "inline" on Matrix.fold will
+        // help a lot (see sumM3)
+        let folda f z (A: matrix) = 
+          let mutable res = z in
+          for i = 0 to A.NumRows-1 do
+            for j = 0 to A.NumCols-1 do
+              res <- f res (A.[i, j]);
+            done;
+          done;
+          res
+
+        let sumM1a (m:matrix) = folda (fun acc x -> acc + x) 0.0 m
+
+        //-----------------------------------------------------
+        // Matrix Loop Perf: Example sumM2 (not recommended)
+        //
+        // This is simple code and gives a reusable operator that 
+        // may come in handy. The tail recursive functions go1 and go2  in foldM2 will be turned 
+        // into loops and will run pretty fast, but variables 'd1' and 'd2' are
+        // captured as a free variables within the inner functions
+        // and no guarantees are made that the information necessary for
+        // array-bounds-check elimination will be propagated down.
+        let foldM2 f z (A: matrix) = 
+          let d1 = A.NumRows-1 in 
+          let d2 = A.NumCols-1 in 
+          let rec go2 acc i j = if j < d2 then f acc (A.Item(i,j)) else acc in 
+          let rec go1 acc i = if i < d1 then go1 (go2 acc i 0) (i+1) else acc in 
+          go1 z 0
+
+        let sumM2 (m:matrix) = foldM2 (fun acc x -> acc + x) 0.0 m
+
+
+        //-----------------------------------------------------
+        // Matrix Loop Perf: Example sumM3 (recommended)
+        //
+        // This is about as good as it gets.  My only performance
+        // concern here is that the array is hidden by an abstraction
+        // boundary and so the calls to A.NumRows, A.NumCols, A.Item etc.
+        // may not be optimizaed to act directly on the array.  Given
+        // the relative simplicity of the implementations of those
+        // functions that would be considered a bug in F#.
+        let sumM3 (A: matrix) = 
+          let mutable res = 0.0 in
+          for i = 0 to A.NumRows-1 do
+            for j = 0 to A.NumCols-1 do
+              res <-  res + (A.Item(i, j));
+            done;
+          done;
+          res
+
+        //-----------------------------------------------------
+        // Matrix Loop Perf: Example sumM4 (not recommended)
+        //
+        // This is sumM2 expanded by hand.
+        // Again the tail recursive functions go1 and go2 will be turned 
+        // into loops and will run pretty fast, but variables 'd1' and 'd2' are
+        // captured as a free variables within the inner functions
+        // functions, and so no guarantees are made that the information necessary for
+        // arry-bounds-check elimination will be propagated down
+        let sumM4 (A: matrix) = 
+          let d1 = A.NumRows-1 in 
+          let d2 = A.NumCols-1 in 
+          let rec go2 acc i j = if j < d2 then acc + (A.Item(i,j)) else acc in 
+          let rec go1 acc i = if i < d1 then go1 (go2 acc i 0) (i+1) else acc in 
+          go1 0.0 0
+        ()
+
+
+    [<Test>]
+    member this.GMatrixOpsAtFloatTest() = 
+
+
+        test "989w42rr" (MG.get (matrix [[1.0;2.0;1.0]]) 0 0 = 1.0)
+        test "989h42rr" ((matrix [[1.0;2.0;1.0]]).Dimensions = (1,3))
+        test "8f3fo3ij" ((matrix [[1.0];[2.0];[1.0]]).Dimensions = (3,1))
+        test "989hf2f2a" (Matrix.toScalar (MG.mul (matrix [[1.0;2.0;1.0]]) (matrix [[1.0];[2.0];[1.0]])) = 6.0)
+        test "989hf2f2q" (Matrix.toScalar (matrix [[1.0;2.0;1.0]] * matrix [[1.0];[2.0];[1.0]]) = 6.0)
+        test "989hf2f2w" (Matrix.toScalar (matrix [[1.0;2.0]; [3.0;4.0]] * 
+                              matrix [[1.0;2.0];[1.0;2.0]]) = 3.0)
+        test "989hf2f2e" (compare (matrix [[1.0]]) (matrix [[1.0]]) = 0)
+        test "989hf2f2rw" (compare (matrix [[1.0]]) (matrix [[2.0]]) = -1)
+        test "989hf2f2t" (compare (matrix [[2.0]]) (matrix [[1.0]]) = 1)
+        test "989hf2f2y" (-(matrix [[2.0; -1.0]]) = matrix [[-2.0; 1.0]])
+        test "989hf2f2u" (matrix [[1.0;2.0]; [3.0;4.0]] *  matrix [[1.0;2.0]; [1.0;2.0]] = matrix [[3.0;6.0]; [7.0; 14.0]])
+        test "989hf2f2g" (MG.getCol (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 0 =
+                                 vector [1.0;
+                                         3.0])
+
+        test "989hf2f2h" (MG.getRow (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 0 =
+                                 rowvec [1.0;2.0])
+
+        test "989hf2f2j" (MG.getRow (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 1 =
+                                 rowvec [3.0;4.0])
+
+        test "989hf2f2k" (MG.getRows (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 1 1 =
+                                  (MG.ofRowVector (rowvec [3.0;4.0])))
+
+        test "989hf2f2l" (MG.getCols (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 0 1 =
+                                  (V (vector [1.0;3.0])))
+        test "989hf2f2z" (MG.getRegion (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 0 1 1 1 =
+                                  (matrix[[2.0]]))
+
+
+        //test "989w42rr" (rangeVG 0 3 = vector [0.0; 1.0; 2.0; 3.0])
+        test "989w42rr" (MG.diag (vector [1.0; 2.0]) = matrix [[1.0;0.0]; 
+                                                               [0.0;2.0]])
+
+
+
+    [<Test>]
+    member this.GMatrixOpsAtFloat32Test() = 
+
+        test "989w42rr" (MG.get (gmatrix [[1.0f;2.0f;1.0f]]) 0 0 = 1.0f)
+        test "989h42rr" ((gmatrix [[1.0f;2.0f;1.0f]]).Dimensions = (1,3))
+        test "8f3fo3ij" ((gmatrix [[1.0f];[2.0f];[1.0f]]).Dimensions = (3,1))
+        test "98439hf2f2" (MG.toScalar (MG.mul (gmatrix [[1.0f;2.0f;1.0f]]) (gmatrix [[1.0f];[2.0f];[1.0f]])) = 6.0f)
+        test "98439hf2f2" (MG.toScalar (gmatrix [[1.0f;2.0f;1.0f]] * gmatrix [[1.0f];[2.0f];[1.0f]]) = 6.0f)
+        test "98439hf2f2" (MG.toScalar (gmatrix [[1.0f;2.0f]; [3.0f;4.0f]] * 
+                              gmatrix [[1.0f;2.0f];[1.0f;2.0f]]) = 3.0f)
+        test "98439hf2f2" (compare (gmatrix [[1.0f]]) (gmatrix [[1.0f]]) = 0)
+        test "98439hf2f2" (compare (gmatrix [[1.0f]]) (gmatrix [[2.0f]]) = -1)
+        test "98439hf2f2" (compare (gmatrix [[2.0f]]) (gmatrix [[1.0f]]) = 1)
+        test "98439hf2f2" (-(gmatrix [[2.0f; -1.0f]]) = gmatrix [[-2.0f; 1.0f]])
+        test "98439hf2f2" (gmatrix [[1.0f;2.0f]; [3.0f;4.0f]] * gmatrix [[1.0f;2.0f]; [1.0f;2.0f]] = gmatrix [[3.0f;6.0f]; [7.0f; 14.0f]])
+        test "98439hf2f2" (MG.getCol (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]]) 0 =
+                                 gvector [1.0f;3.0f])
+
+        test "98439hf2f2" (MG.getRow (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]]) 0 =
+                                 growvec [1.0f;2.0f])
+
+        test "98439hf2f2" (MG.getRow (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]]) 1 =
+                                 growvec [3.0f;4.0f])
+
+        test "98439hf2f2" (MG.getRows (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]]) 1 1 =
+                                  (MG.ofRowVector (growvec [3.0f;4.0f])))
+
+        test "98439hf2f2" (MG.getCols (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]])  0 1 =
+                                  (V (gvector [1.0f;3.0f])))
+        test "98439hf2f2" (MG.getRegion (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]]) 0 1 1 1 =
+                                  (gmatrix[[2.0f]]))
+
+
+
+    [<Test>]
+    member this.GMatrixOpsAtBigNumTest() = 
+
+        test "989w42rr" (MG.get (gmatrix [[1N;2N;1N]]) 0 0 = 1N)
+        test "989h42rr" ((gmatrix [[1N;2N;1N]]).Dimensions = (1,3))
+        test "8f3fo3ij" ((gmatrix [[1N];[2N];[1N]]).Dimensions = (3,1))
+        test "68439hf2f2a" (MG.toScalar (MG.mul (gmatrix [[1N;2N;1N]]) (gmatrix [[1N];[2N];[1N]])) = 6N)
+        test "68439hf2f2s" (MG.toScalar (gmatrix [[1N;2N;1N]] * gmatrix [[1N];[2N];[1N]]) = 6N)
+        test "68439hf2f2d" (MG.toScalar (gmatrix [[1N;2N]; [3N;4N]] * 
+                              gmatrix [[1N;2N];[1N;2N]]) = 3N)
+        test "68439hf2f2f" (compare (gmatrix [[1N]]) (gmatrix [[1N]]) = 0)
+        test "68439hf2f2g" (compare (gmatrix [[1N]]) (gmatrix [[2N]]) = -1)
+        test "68439hf2f2h" (compare (gmatrix [[2N]]) (gmatrix [[1N]]) = 1)
+        test "68439hf2f2j" (-(gmatrix [[2N; -1N]]) = gmatrix [[-2N; 1N]])
+        test "68439hf2f2k" (gmatrix [[1N;2N]; [3N;4N]] * gmatrix [[1N;2N]; [1N;2N]] = gmatrix [[3N;6N]; [7N; 14N]])
+        test "68439hf2f2ppp" (1N = 1N)
+        test "68439hf2f2ppp" ([| 1N; 3N |] = [| 1N ; 3N |])
+
+        test "68439hf2f2m" (MG.getCol (gmatrix [[1N;2N]; 
+                                          [3N;4N]]) 0 =
+                                 gvector [1N;
+                                         3N])
+
+        test "68439hf2f2q" (MG.getRow (gmatrix [[1N;2N]; 
+                                          [3N;4N]]) 0 =
+                                 growvec [1N;2N])
+
+        test "68439hf2f2w" (MG.getRow (gmatrix [[1N;2N]; 
+                                          [3N;4N]]) 1 =
+                                 growvec [3N;4N])
+
+        test "68439hf2f2e" (MG.getRows (gmatrix [[1N;2N]; 
+                                          [3N;4N]]) 1 1 =
+                                  (MG.ofRowVector (growvec [3N;4N])))
+
+        test "68439hf2f2r" (MG.getCols (gmatrix [[1N;2N]; 
+                                                 [3N;4N]]) 0 1 =
+                                  (V (gvector [1N;3N])))
+        test "68439hf2f2t" (MG.getRegion (gmatrix [[1N;2N]; 
+                                                   [3N;4N]]) 0 1 1 1 =
+                                  (gmatrix[[2N]]))
+
+
+    [<Test>]
+    member this.FloatMatrixPerfTest() = 
+
+        let m = matrix [[1.0;2.0;1.0];
+                        [3.0;8.0;5.0];
+                        [4.0;2.0;1.0]]
+
+        let d = determinant m
+        test "caeirj20" (d = 6.0)
+
+        for i = 0 to 100000 do
+          ignore(determinant m)
+        done
+        for i = 0 to 100000 do
+          ignore(m .* m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m * m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m + m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m * m * m)
+        done
+
+    [<Test>]
+    member this.Float32MatrixPerf() = 
+
+        let m = gmatrix [[1.0f;2.0f;1.0f];
+                        [3.0f;8.0f;5.0f];
+                        [4.0f;2.0f;1.0f]]
+
+
+        for i = 0 to 100000 do
+          ignore(m .* m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m * m)
+        done
+    
+    [<Test>]
+    member this.GMatrixOpsAtComplexTest() = 
+
+        let R r = complex r 0.0
+        let I i = complex 0.0 i
+        test "989w42rr" (MG.get (gmatrix [[R 1.0;R 2.0;R 1.0]]) 0 0 = R 1.0)
+        test "989h42rr" ((gmatrix [[R 1.0;R 2.0;R 1.0]]).Dimensions = (1,3))
+        test "8f3fo3ij" ((gmatrix [[R 1.0];[R 2.0];[R 1.0]]).Dimensions = (3,1))
+        test "28439hf2f2" (MG.toScalar (MG.mul (gmatrix [[R 1.0;R 2.0;R 1.0]]) (gmatrix [[R 1.0];[R 2.0];[R 1.0]])) = R 6.0)
+        test "28439hf2f2" (MG.toScalar (gmatrix [[R 1.0;R 2.0;R 1.0]] * gmatrix [[R 1.0];[R 2.0];[R 1.0]]) = R 6.0)
+        test "28439hf2f2" (MG.toScalar (gmatrix [[R 1.0;R 2.0]; [R 3.0;R 4.0]] * 
+                              gmatrix [[R 1.0;R 2.0];[R 1.0;R 2.0]]) = R 3.0)
+        test "28439hf2f2" (compare (gmatrix [[R 1.0]]) (gmatrix [[R 1.0]]) = 0)
+        test "28439hf2f2" (compare (gmatrix [[R 1.0]]) (gmatrix [[R 2.0]]) = -1)
+        test "28439hf2f2" (compare (gmatrix [[R 2.0]]) (gmatrix [[R 1.0]]) = 1)
+        test "28439hf2f2" (-(gmatrix [[R 2.0; -R 1.0]]) = gmatrix [[-R 2.0; R 1.0]])
+        test "28439hf2f2" (gmatrix [[R 1.0;R 2.0]; [R 3.0;R 4.0]] * gmatrix [[R 1.0;R 2.0]; [R 1.0;R 2.0]] = gmatrix [[R 3.0;R 6.0]; [R 7.0; R 14.0]])
+        test "28439hf2f2" (MG.getCol (gmatrix [[R 1.0;R 2.0]; 
+                                          [R 3.0;R 4.0]]) 0 =
+                                 gvector [R 1.0;
+                                         R 3.0])
+
+        test "28439hf2f2" (MG.getRow (gmatrix [[R 1.0;R 2.0]; 
+                                          [R 3.0;R 4.0]]) 0 =
+                                 growvec [R 1.0;R 2.0])
+
+        test "28439hf2f2" (MG.getRow (gmatrix [[R 1.0;R 2.0]; 
+                                          [R 3.0;R 4.0]]) 1 =
+                                 growvec [R 3.0;R 4.0])
+
+        test "28439hf2f2" (MG.getRows (gmatrix [[R 1.0;R 2.0]; 
+                                          [R 3.0;R 4.0]]) 1 1 =
+                                  (MG.ofRowVector (growvec [R 3.0;R 4.0])))
+
+        test "28439hf2f2" (MG.getCols (gmatrix [[R 1.0;R 2.0]; 
+                                          [R 3.0;R 4.0]]) 0 1 =
+                                  (V (gvector [R 1.0;R 3.0])))
+        test "28439hf2f2" ((gmatrix [[R 1.0;R 2.0]; 
+                                     [R 3.0;R 4.0]]).Region(0,1,1,1) =
+                                  (gmatrix[[R 2.0]]))
+
+        (* Test norm functions on gmatrix, note, there are 2 norm functions on gmatrix.
+         * One fast-path that assumes float elt type, one assuming generic element type.
+         * Similarly, two Vector norms to test.
+         * No RowVector norm.
+         *)
+
+        test "norm-gmatrix-generic-int32"   (MG.norm (MG.init 2 2 (fun _ _ -> 11))    = 22.0)
+        test "norm-gmatrix-generic-int64"   (MG.norm (MG.init 2 2 (fun _ _ -> 11L))   = 22.0)
+        test "norm-gmatrix-generic-float"   (MG.norm (MG.init 2 2 (fun _ _ -> 11.0))  = 22.0)
+        test "norm-gmatrix-generic-float32" (MG.norm (MG.init 2 2 (fun _ _ -> 11.0f)) = 22.0)
+        test "norm-gmatrix-generic-bigint"  (MG.norm (MG.init 2 2 (fun _ _ -> 11I))   = 22.0)
+        test "norm-gmatrix-generic-bignum"  (MG.norm (MG.init 2 2 (fun _ _ -> 11N))   = 22.0)
+        test "norm-gmatrix-float"           (MDouble .norm (MDouble .init 2 2 (fun _ _ -> 11.0))  = 22.0)
+
+        test "norm-vector-generic-int32"   (VGeneric.norm (VGeneric.init 4 (fun _ -> 11))    = 22.0)
+        test "norm-vector-generic-int64"   (VGeneric.norm (VGeneric.init 4 (fun _ -> 11L))   = 22.0)
+        test "norm-vector-generic-float"   (VGeneric.norm (VGeneric.init 4 (fun _ -> 11.0))  = 22.0)
+        test "norm-vector-generic-float32" (VGeneric.norm (VGeneric.init 4 (fun _ -> 11.0f)) = 22.0)
+        test "norm-vector-generic-bigint"  (VGeneric.norm (VGeneric.init 4 (fun _ -> 11I))   = 22.0)
+        test "norm-vector-generic-bignum"  (VGeneric.norm (VGeneric.init 4 (fun _ -> 11N))   = 22.0)
+        test "norm-vector-float"           (VDouble .norm (VDouble .init 4 (fun _ -> 11.0))  = 22.0)
+
+        (* norm is not provided on RowVector...
+        module RGeneric = Math.RowVector.Generic
+        module RDouble  = Math.RowVector
+        test "norm-rowvector-generic-float" (RGeneric.norm (RGeneric.init 4 (fun _ -> 1.1)) = 2.2)
+        test "norm-rowvector-float"         (RDouble .norm (RDouble .init 4 (fun _ -> 1.1)) = 2.2)
+        *)   
+
+    [<Test>]
+    member this.SizeOfFormattedMatrix() = 
+
+        //check the number of characters in this display is < 100000. In reality it displays 100 x 100, around 74000 characters
+        test "vrkomvrwe0" ((sprintf "%A" (matrix [ for i in 0 .. 1000 -> [ for j in 0 .. 1000 -> float (i+j) ] ])).Length < 100000)
+        //check the number of characters in this display is < 10000. In reality it displays 50 x 50, around 7000 characters
+        test "vrkomvrwe0" (((matrix [ for i in 0 .. 1000 -> [ for j in 0 .. 1000 -> float (i+j) ] ]).ToString()).Length < 10000)
+
+(* Regression 3716: ensure the members/properties mentioned in matrix Obsolete redirect messages exist *)
+module M3716 = begin
+  open Microsoft.FSharp.Math
+  let check_Dimensions     (m:matrix) = m.Dimensions     : int * int
+  let check_NumRows        (m:matrix) = m.NumRows        : int
+  let check_NumCols        (m:matrix) = m.NumCols        : int
+  let check_NonZeroEntries (m:matrix) = m.NonZeroEntries : seq<int * int * float> 
+  let check_Column         (m:matrix) = m.Column         : int -> Vector<float>
+  let check_Row            (m:matrix) = m.Row            : int -> RowVector<float>
+  let check_Columns        (m:matrix) = m.Columns        : int  * int -> Matrix<float>
+  let check_Rows           (m:matrix) = m.Rows           : int  * int -> Matrix<float>
+  let check_Region         (m:matrix) = m.Region         : int  * int * int * int -> Matrix<float>
+  let check_Diagonal       (m:matrix) = m.Diagonal       : Vector<float>
+  let check_ElementOps     (m:matrix) = m.ElementOps     : INumeric<float>
+end
+
+module Numeric = 
+
+    open System
+
+    open Microsoft.FSharp.Math
+    module LinearAlgebra = begin
+
+        open Microsoft.FSharp.Core
+        open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
+        open Microsoft.FSharp.Core.Operators
+        open Microsoft.FSharp.Collections
+        open Microsoft.FSharp.Math
+
+        let inline sumfR f (a,b) =
+            let mutable res = 0.0 in
+            for i = a to b do
+                res <- res + f i;
+            done;
+            res
+
+        (*----------------------------------------------------------------------------
+        !* predicates
+         *--------------------------------------------------------------------------*)
+
+        let isSymmetric a = a |> Matrix.foralli (fun i j aij -> aij = a.[j,i]) 
+        let isLowerTriangular a = a |> Matrix.foralli (fun i j aij -> i>=j || aij=0.0)
+
+        (*----------------------------------------------------------------------------
+        !* choleskyFactor
+         *--------------------------------------------------------------------------*)
+
+        let choleskyFactor (a: matrix) =
+          let nA,mA = a.Dimensions in
+          if nA<>mA              then invalid_arg "choleskyFactor: not square";
+          if not (isSymmetric a) then invalid_arg "choleskyFactor: not symmetric";
+          let lres = Matrix.zero nA nA  in(* nA=mA *)
+          for j=0 to nA-1 do
+            for i=j to nA-1 do (* j <= i *)
+              (* Consider a_ij = sum(k=0...n-1)  (lres_ik . lresT_kj)
+               *               = sum(k=0...n-1)  (lres_ik . lres_jk)
+               *               = sum(k=0...j-1)  (lres_ik . lres_jk) + lres_ij . lres_jj + (0 when k>j)
+               *               = psum                                + lres_ij . lres_jj
+               * This determines lres_ij terms of preceding terms.
+               * lres_ij depends on lres_ik and lres_jk (and maybe lres_ii) for k<i
+               *)
+              let psum = sumfR (fun k -> lres.[i,k] * lres.[j,k]) (0,j-1) in
+              let a_ij = a.[i,j] in
+              if i=j then
+                lres.[i,i] <- (System.Math.Sqrt (a_ij - psum))
+              else
+                lres.[i,j] <- ((a_ij - psum) / lres.[j,j])
+            done
+          done;
+          // if not (isLowerTriangular lres) then failwith "choleskyFactor: not lower triangular result";
+          lres
+
+        (*----------------------------------------------------------------------------
+        !* lowerTriangularInverse
+         *--------------------------------------------------------------------------*)
+            
+        let lowerTriangularInverse (l: matrix) =
+          (* Given l s.t. LT: l is lower_triangular (l_ij = 0 when i<j).
+           * Finds res s.t. l.res = id *)
+          let nA,mA = l.Dimensions in
+          let res = Matrix.zero nA nA  in (* nA=mA *)
+          for j=0 to nA-1 do
+            for i=j to nA-1 do (* j <= i *)
+              (* Consider id_ij = sum(k=0...n-1)  (l_ik . res_kj)
+               *                = sum(k=0...i-1)  (l_ik . res_kj) + l_ii . res_ij + (0 when k>i by LT)
+               *                = psum                            + l_ii . res_ij
+               * Have res_ij terms of res_kj for k<i and l_??.
+               *)
+              let psum   = sumfR (fun k -> l.[i,k] * res.[k,j]) (0,i-1) in
+              let id_ij  = if i=j then 1.0 else 0.0 in
+              let res_ij = (id_ij - psum) / l.[i,i] in
+              res.[i, j] <- res_ij
+            done
+          done;
+          res
+
+
+        (*----------------------------------------------------------------------------
+        !* symmetricInverse
+         *--------------------------------------------------------------------------*)
+
+        let symmetricInverse a =
+          (* Given a symmetric matix.
+           * Have l s.t. a = l . transpose(l)  where l is lowerTriangular.
+           * Have l_inv s.t. l.l_inv = id
+           * Have a_inv = transpose(l_inv).l_inv
+           *)
+          let l     = choleskyFactor a         in
+          let l_t   = l.Transpose                in 
+          let l_inv = lowerTriangularInverse l in
+          let a_inv = l_inv.Transpose * l_inv in
+          a_inv
+
+
+        (*----------------------------------------------------------------------------
+        !* determinant 
+         *--------------------------------------------------------------------------*)
+
+
+        let determinant (a: matrix) =
+          (* Allocates lists to manage walk over permutations.
+           * Iterating through permutations a mutable array may help GC.
+           *)
+          let rec det js ks =
+            match ks with
+              | []    -> 1.0
+              | k::ks -> 
+                let rec split sign (preJs,js) =
+                  match js with
+                  | []    -> 0.0
+                  | j::js -> sign * a.[j,k] * det (List.rev preJs @ js) ks
+                             +
+                             split (0.0 - sign) (j::preJs,js) in
+                split 1.0 ([],js) in
+          let nA,mA = a.Dimensions in
+          if nA<>mA then invalid_arg "determinant: not square";
+          det [0..nA-1] [0..nA-1]
+
+        let cholesky a =
+          let l    = choleskyFactor         a in
+          let lInv = lowerTriangularInverse l in
+          l,lInv
+
+    end
+    module Notation = begin
+
+        type matrix = Matrix<float>
+        type vector = Vector<float>
+        type rowvec = RowVector<float>
+        type complex = Complex
+      
+        module Generic = begin
+            type 'a matrix = Matrix<'a>
+            type 'a vector = Vector<'a>
+            type 'a rowvec = RowVector<'a>
+            type complex = Complex
+          
+            let complex x y = Complex.mkRect (x,y)
+            let matrix ll = Matrix.Generic.ofSeq ll
+            let vector l = Vector.Generic.ofSeq  l
+            let rowvec l = RowVector.Generic.ofSeq l
+            let S x = Matrix.Generic.ofScalar x
+            let RV x = Matrix.Generic.ofRowVector x 
+            let V x  = Matrix.Generic.ofVector x
+            let M2V x = Matrix.Generic.toVector x
+            let M2RV x = Matrix.Generic.toRowVector x
+            let M2S x = Matrix.Generic.toScalar x
+        end    
+
+        let complex x y = Complex.mkRect (x,y)
+        // Notational conveniences
+        let matrix ll = Matrix.ofSeq ll
+        let vector l = Vector.ofSeq l
+        let rowvec l = RowVector.ofSeq l
+        let S x = Matrix.ofScalar x
+        let RV x = Matrix.ofRowVector x 
+        let V x  = Matrix.ofVector x
+        let M2V x = Matrix.toVector x
+        let M2RV x = Matrix.toRowVector x
+        let M2S x = Matrix.toScalar x
+    end
+
+
+    open LinearAlgebra
+    open Notation 
+
+    let abs x = if x<0. then -. x   else x
+    let neg x = -. x
+
+    let poly x cs =
+      (* eval a poly expansion - could take a precision and terminate early... *)
+      let rec eval (* i *) acc cs xi = 
+        match cs with
+        | []    -> acc
+        | c::cs -> eval (* i+1 *) (acc + c * xi) cs (x * xi)
+      in
+      eval (* i=0 *) 0.0 cs 1.
+
+    let powerseries x cs =
+      (* eval a poly expansion - and divide by factorials along the way *)
+      let rec eval i acc cs xi ifact = 
+        match cs with
+        | []    -> acc
+        | c::cs -> eval (i+1) (acc + (c * xi) / ifact) cs (x * xi) (ifact * (float (i+1)))
+      in
+      eval 0 0.0 cs 1. 1. 
+
+    (*check*)
+    let e   = powerseries 1. [1.; 1.;1.; 1.;1.; 1.;1.; 1.;1.; 1.;1.; 1.;1.; 1.;]
+    let pi  = 2. * asin 1.0      
+
+
+    (*----------------------------------------------------------------------------
+    !* erfc - complementary error function and inverse
+     *--------------------------------------------------------------------------*)
+
+    (* NOTE: got sign wrong in poly factorisation *)  
+    let erfc x =
+      if x = neg_infinity then 2.0 else
+      if x = infinity then 0.0 else
+      let z = abs x in
+      let t = 1.0 / (1.0 + 0.5 * z) in
+      let y = t * exp (-. z*z 
+                       +. poly t [ -1.26551223;  1.00002368; 0.37409196;  0.09678418; -0.18628806;
+                                    0.27886807; -1.13520398; 1.48851587; -0.82215223;  0.17087277])
+      in
+      if x >= 0.0 then y else 2.0 - y
+
+    let erfcinv y =
+      if (y < 0. || y > 2.) then failwith "Inverse complementary function not defined outside [0,2]." else
+      if (y = 0.) then infinity else
+      if (y = 2.) then neg_infinity else
+      let central y =
+        let q = y - 1.0 in
+        let r = q * q in
+          poly r   [ - 0.8862269264526915; 2.710410832036097; -3.057303267970988;
+                     1.524304069216834; -0.3051415712357203; 0.01370600482778535 ]
+          * q
+          / poly r [ 1.0                ; -3.320170388221430;  4.175081992982483;
+                     - 2.432796560310728; 0.6311946752267222; -0.05319931523264068 ]
+      in
+      let lower y =
+        (* Rational approximation lower region *)
+          let q = sqrt (-2.0 * log (y / 2.0)) in
+          poly q [-2.077595676404383; -3.093354679843504;  1.802933168781950;
+                   1.697592457770869;  0.2279687217114118; 0.005504751339936943;] /
+          poly q [ 1.0;                3.754408661907416;  2.445134137142996;
+                   0.3224671290700398; 0.007784695709041462]
+      in
+      let upper y =
+        let  q = sqrt (-2.0 * log (1. - y / 2.0)) in
+        -.
+          poly q [ -2.077595676404383; -3.093354679843504;  1.802933168781950;
+                   1.697592457770869;  0.2279687217114118; 0.005504751339936943] /
+          poly q [ 1.0;                 3.754408661907416;  2.445134137142996;
+                    0.3224671290700398;  0.007784695709041462;
+                 ]
+      in
+      let halleys x = (* One iteration of Halley's rational method (third order) gives full machine precision. *)
+        let u = (erfc (x) - y) / (-2.0 / sqrt pi * exp (-. x * x)) in
+        x - u / (1.0 + x * u)
+      in
+     (* compute x according to region *)
+      let x =
+        if (y  >= 0.0485 && y <= 1.9515) then central y else
+        if (y < 0.0485) then lower y else
+        (* y > 1.9515 *) upper y
+      in
+      (* iterate halleys once *)
+      halleys x
+
+
+    (*----------------------------------------------------------------------------
+    !* phi and phi_inv - complementary error function 
+     *--------------------------------------------------------------------------*)
+      
+    let root2 = sqrt 2.0
+    let phi     t = erfc(-. t / root2) / 2.
+    let phi_inv p = -. root2 * erfcinv (2. * p)
+
+    let Phi t = phi t
+    let Phi_Inv p = phi_inv p
+
+
+    (*----------------------------------------------------------------------------
+    !* normalpdf, v3, w3
+     *--------------------------------------------------------------------------*)
+      
+    /// <summary>
+    /// Computes the normal density at a specified point of interest.
+    /// </summary>
+    /// <param name="t">The point of interest.</param>
+    /// <returns>The normal density at the point of interest.</returns>
+    let dSqrt2Pi = 2.5066282746310002 (* not checked *)
+    let normalpdf t = 1.0 / dSqrt2Pi * exp (-. t*t / 2.0)
+
+    /// <summary>
+    /// Computes the additive correction of a single-sided truncated Gaussian with unit variance.
+    /// </summary>
+    /// <param name="t">The mean of the non-truncated Gaussian.</param>
+    /// <param name="epsilon">The truncation point.</param>
+    /// <returns>The additive correction.</returns>
+    let doubleEpsilon = System.Double.Epsilon
+    let v t epsilon =
+      let dNumerator = normalpdf (t - epsilon) in
+      let dDenominator = phi (t - epsilon) in
+      if dDenominator < sqrt doubleEpsilon then
+        0.0-t + epsilon
+      else
+       dNumerator / dDenominator
+
+    /// <summary>
+    /// Computes the additive correction of a general double-sided truncated Gaussian with unit variance.
+    /// </summary>
+    /// <param name="t">The mean of the non-truncated Gaussian.</param>
+    /// <param name="l">The lower truncation point.</param>
+    /// <param name="u">The upper truncation point.</param>
+    /// <returns>The additive correction.</returns>
+    /// <remarks>This routine has not been tested in all regimes of t for a given l and u.</remarks>
+    /// <exception cref="ArithmeticException">Thrown if the computation is not numerically stable.</exception>
+    let v3 t l u =
+      let dNumerator = normalpdf (t - l) - normalpdf (t - u) in
+      let dDenominator = phi (u - t) - phi (l - t) in
+      if (dDenominator < sqrt (doubleEpsilon)) then
+        failwith "Unsafe v3 call" (* raise (new System.ArithmeticException("Unsafe computation of v"))*)
+        (* failwith "Unsafe computation of v" // was arithmetic exception *)
+      else
+        if t<0.0 then (* MatLab version only, not C# *)
+          (0.0 - dNumerator) / dDenominator
+        else
+          dNumerator / dDenominator
+
+    /// <summary>
+    /// Computes the multiplicative correction of a general double-sided truncated Gaussian with unit variance.
+    /// </summary>
+    /// <param name="t">The mean of the non-truncated Gaussian.</param>
+    /// <param name="l">The lower truncation point.</param>
+    /// <param name="u">The upper truncation point.</param>
+    /// <returns>The multiplicative correction.</returns>
+    /// <remarks>This routine has not been tested in all regimes of t for a given l and u.</remarks>
+    /// <exception cref="ArithmeticException">Thrown if the computation is not numerically stable.</exception>
+    let w3 t l u =
+      let dNumerator = (u - t) * normalpdf (u - t) - (l - t) * normalpdf (l - t) in
+      let dDenominator = phi (u - t) - phi (l - t) in
+      if (dDenominator < sqrt (doubleEpsilon)) then
+        failwith "unsafe w3 call" (* raise (new ArithmeticException ("Unsafe computation of v")) *)
+      else
+        let z = v3 t l u in
+        z * z + dNumerator / dDenominator
+
+
+    (*----------------------------------------------------------------------------
+    !* streams
+     *--------------------------------------------------------------------------*)
+
+    type 'a stream = SCONS of (unit -> ('a * 'a stream))  (* fully suspended *)
+    let rec constS x = SCONS (fun () -> (x,constS x))
+    let rec unfoldS   f z = SCONS (fun () -> let z,x = f z in x,unfoldS f z)
+    let rec generateS f   = SCONS(fun () -> f (),generateS f)
+    let pullS (SCONS xtailf) = xtailf()
+    let listS xs =
+      let pull = function (x::xs) -> xs,x | [] -> failwith "listS: exhausted points" in
+      unfoldS pull xs
+    let rec takeS n s = if n=0 then [] else let x,s = pullS s in x::takeS (n-1) s
+
+
+    (*----------------------------------------------------------------------------
+    !* streams - random, neiderreiter
+     *--------------------------------------------------------------------------*)
+    let randomM m n = Matrix.randomize (Matrix.zero m n)       
+    let randomPts dim = generateS (fun () -> randomM dim 1)
+
+    (* Neiderreiter series:
+     * Definition extracted from C# code.
+     * To generate npts random points of dimension d.
+     * 
+     * For k = 0 to npts-1   // over pts 
+     *  For i = 0 to ndims-1 // over dimension
+     *  
+     *   p(k).[i] = let t = (k+1).Neiderreiter(i)
+     *              in  abs(2*fract(t) - 1)
+     *
+     * where fract(t) = t - floor(t)
+     * where Neiderreiter(i) = 2 ^ ( (i+1)/(ndims+1) )
+     *
+     * So, Neiderreiter(i) falls inside [1,2].
+     *)
+    let neiderreiterS dim npts =
+      let fract x = x - floor x in
+      let neiderreiter  = Matrix.init dim 1 (fun i _ -> 2. ** (float (i + 1) / float (dim + 1))) in
+      let mkPoint k = Matrix.init dim 1 (fun i _ -> let t = float(k + 1) * Matrix.get neiderreiter i 0 in
+                                                    let x = abs (2.0 * fract t - 1.0) in
+                                                    assert (0.0 <= x && x <= 1.0);
+                                                    x)
+      in
+      let step k = if k<npts then k+1,mkPoint k
+                             else failwith "neiderreiterS: exhausted points"
+      in
+      unfoldS step 0
+
+    let dim,npts = 3,100
+    let pts = takeS npts (neiderreiterS dim npts)
+
+
+    (*----------------------------------------------------------------------------
+    !* unitIntegrals
+     *--------------------------------------------------------------------------*)
+
+    let unitIntegralOverPts pts nPts f =
+      (* unit integral of f by averaging nPts samples of f at pt where pt drawn from pts *)
+      let rec sum i total f pts =
+        if i=nPts then total
+                  else let pt,pts = pullS pts in
+                       let total = total + f pt in
+                       sum (i + 1) total f pts
+      in
+      sum 0 0. f pts / float nPts
+
+    let unitIntegralOverRandomPoints dim nPts f =
+      (* unit integral of f by averaging nPts samples of f at a random pt *)  
+      let eval () = let w = randomM dim 1 in
+                    f w
+      in
+      let sum = seq { for i in 0 .. nPts-1 -> eval() } |> Seq.fold (+) 0.0 in 
+      let res = sum / float nPts in
+      res
+
+    let f v = let x = Matrix.get v 0 0 in x*x  (* [1/3 x^3] 0,1 = 1/3 *)
+    let x1 = unitIntegralOverRandomPoints 1             1000 f   (* random pts *)
+    let x2 = unitIntegralOverPts (randomPts 1)          1000 f   (* random pt sequence *)
+    let x3 = unitIntegralOverPts (neiderreiterS 1 1000) 1000 f   (* pseudo random pt sequence *)
+
+
+    (*----------------------------------------------------------------------------
+    !* weightedGaussian - alg 9
+     *--------------------------------------------------------------------------*)
+
+    (* weightedGaussian: implements algorithm 8 *)
+    let weightedGaussian unitIntegrate g (mu:Matrix<_>,sigma:Matrix<_>) (alpha:Matrix<_>,beta:Matrix<_>) =
+      printf "dim(sigma) = %d,%d\n" sigma.NumRows sigma.NumCols;
+      printf "dim(mu) = %d,%d\n" mu.NumRows mu.NumCols;
+      printf "dim(alpha) = %d,%d\n" alpha.NumRows alpha.NumCols;
+      printf "dim(beta) = %d,%d\n" beta.NumRows beta.NumCols;
+      let l     = choleskyFactor sigma in
+      printf "dim(l) = %d,%d\n" l.NumRows l.NumCols;
+      let l_inv = lowerTriangularInverse l in
+      printf "dim(l_inv) = %d,%d\n" l_inv.NumRows l_inv.NumCols;
+      (* apply mu subst and L_inv subst *)
+      let alpha'  = l_inv * (alpha - mu) in
+      let beta'   = l_inv * (beta  - mu) in
+      printf "dim(alpha') = %d,%d\n" alpha'.NumRows alpha'.NumCols;
+      printf "dim(beta') = %d,%d\n" beta'.NumRows beta'.NumCols;
+
+      (* apply phi_inv subst *)
+      let alpha''     = Matrix.map phi alpha' in
+      let beta''      = Matrix.map phi beta'  in
+      printf "dim(alpha'') = %d,%d\n" alpha''.NumRows alpha''.NumCols;
+      printf "dim(beta'') = %d,%d\n" beta''.NumRows beta''.NumCols;
+      let alphabeta'' = beta'' - alpha'' in
+      (* reduced to unit integral *)
+      let eval w =
+        let v = alpha'' + (w .* alphabeta'') in
+        let z = Matrix.map phi_inv v in
+        let x = (l * z) + mu in
+        g x
+      in
+      unitIntegrate eval
+
+    let g v = let x = Matrix.get v 0 0 in
+              let y = Matrix.get v 1 0 in
+              x*y*y
+
+    (*	    
+    let integrate3 = weightedGaussian
+    let res1 = integrate3 (unitIntegralOverRandomPoints 3 100)                g (mu,sigma) (alpha,beta)  
+    let res2 = integrate3 (unitIntegralOverRandomPoints 3 1000)               g (mu,sigma) (alpha,beta)  
+    let res3 = integrate3 (unitIntegralOverRandomPoints 3 10000)              g (mu,sigma) (alpha,beta)
+    let res4 = integrate3 (unitIntegralOverPts (neiderreiterS 3 100) 100)     g (mu,sigma) (alpha,beta)
+    let res5 = integrate3 (unitIntegralOverPts (neiderreiterS 3 1000) 1000)   g (mu,sigma) (alpha,beta)
+    let res6 = integrate3 (unitIntegralOverPts (neiderreiterS 3 10000) 10000) g (mu,sigma) (alpha,beta)
+    *)
+
+    let res1 = 
+      let mu    = Matrix.create 3 1 0.2 in
+      let sigma = Matrix.add (Matrix.create 3 3 0.2) (Matrix.init 3 3 (fun _ _ -> 2.0)) in
+      let alpha = Matrix.create 3 1 0.1 in
+      let beta  = Matrix.create 3 1 0.3 in
+      weightedGaussian (unitIntegralOverRandomPoints 3 100) g (mu,sigma) (alpha,beta)
+
+
+    (*----------------------------------------------------------------------------
+    !* expectationPropagation - alg 8
+     *--------------------------------------------------------------------------*)
+      
+    let sqr x  : float  = x*x
+    let inv x = 1.0/x
+
+    let expectationPropagation (mu,sigma:matrix) m (a:matrix[],z:_[],alpha: _[],beta: _[]) nIters =
+
+      let mu0 = mu in
+
+      let mutable muHat    = mu0   in     
+      let mutable sigmaHat = sigma in     
+      let mu = Vector.create m 0.0 in  // nb: rebinds mu 
+      let pi = Vector.create m 0.0 in
+      let s  = Vector.create m 1.0 in
+
+      (* pre-compute *)
+      let aT = a |> Array.map (fun ai ->    printf "dim(ai) = %d,%d\n" ai.NumRows ai.NumCols; ai.Transpose)  in
+      Printf.printf "sigmaHat=\n%O\n\n" sigmaHat;
+
+      for i = 1 to nIters do
+       for j = 0 to m-1 do
+        Printf.printf "i=%d,j=%d,sigmaHat=\n%O\n\n" i j sigmaHat;
+
+        (* Pre-computations for jth factor *)    
+        let u_j      = sigmaHat * a.[j] in
+        Printf.printf "i=%d,j=%d,u_j=\n%O\n\n" i j u_j;
+
+        let c_j      = aT.[j] * u_j   |> Matrix.toScalar in
+        Printf.printf "i=%d,j=%d,c_j=\n%O\n\n" i j c_j;
+        let m_j      = aT.[j] * muHat |> Matrix.toScalar in
+        Printf.printf "i=%d,j=%d,m_j=\n%O\n\n" i j m_j;
+        let d_j      = pi.[j] * c_j in
+        Printf.printf "i=%d,j=%d,d_j=\n%O\n\n" i j d_j;
+        let phi_j    = m_j + d_j / (1.0 - d_j) * (m_j - mu.[j]) in
+        Printf.printf "i=%d,j=%d,phi_j=\n%O\n\n" i j phi_j;
+        let psi_j    = c_j / (1.0 - d_j) in
+        Printf.printf "i=%d,j=%d,psi_j=\n%O\n\n" i j psi_j;
+        let alpha_j  = alpha.[j] phi_j psi_j in
+        Printf.printf "i=%d,j=%d,alpha_j=\n%O\n\n" i j alpha_j;
+        let beta_j   = beta.[j]  phi_j psi_j in
+        Printf.printf "i=%d,j=%d,beta_j=\n%O\n\n" i j beta_j;
+       (* ADF update *)
+        muHat    <- (let factor = (pi.[j] * (m_j - mu.[j]) + alpha_j)  /  (1.0 - d_j) in muHat + (factor * u_j))
+        Printf.printf "i=%d,j=%d,muHat=\n%O\n\n" i j muHat;
+        sigmaHat <- (let factor = (pi.[j] * (1.0 - d_j) - beta_j)  /  (1.0 - d_j) ** 2.0 in sigmaHat + (factor * (u_j * u_j.Transpose)));
+        Printf.printf "i=%d,j=%d,ie1=\n%O\n\n" i j ((1.0 - d_j) ** 2.0);
+        Printf.printf "i=%d,j=%d,ie2=\n%O\n\n" i j u_j.Transpose;
+        Printf.printf "i=%d,j=%d,ie3=\n%O\n\n" i j ((pi.[j] * (1.0 - d_j) - beta_j));
+        Printf.printf "i=%d,j=%d,ie4=\n%O\n\n" i j ((pi.[j] * (1.0 - d_j) - beta_j)  /  (1.0 - d_j) ** 2.0);
+        Printf.printf "i=%d,j=%d,ie5=\n%O\n\n" i j (let factor = (pi.[j] * (1.0 - d_j) - beta_j)  /  (1.0 - d_j) ** 2.0 in factor * (u_j * u_j.Transpose));
+        Printf.printf "i=%d,j=%d,sigmaHat=\n%O\n\n" i j sigmaHat;
+        (* Factor update *)
+        pi.[j] <- 1.0 / (inv beta_j - psi_j);
+        mu.[j] <- alpha_j / beta_j + phi_j;
+        s.[j]  <- z.[j] phi_j psi_j * exp ( sqr(alpha_j) / (2.0 * beta_j)) / sqrt (1.0 - psi_j * beta_j);
+       done;
+      done;
+
+
+      (* result *)
+      let sigmaInv    = symmetricInverse sigma     in
+      let sigmaHatInv = symmetricInverse sigmaHat in (* invertible? *)
+
+      let zHat =
+        Vector.prod s *
+        sqrt (determinant (sigmaHat * sigmaInv)) *
+        exp (-0.5 * ( Vector.dot pi (mu .* mu)
+                + Matrix.toScalar (mu0.Transpose  *  sigmaInv * mu0)
+                - Matrix.toScalar (muHat.Transpose * sigmaHatInv * muHat)))
+      in
+      muHat, sigmaHat, zHat
+
+
+
+    type floatf = float -> float -> float
+
+    let expectationPropagationB 
+         (mu,sigma:matrix) 
+         m 
+         (a : matrix[]) 
+         (z : floatf[])
+         (alphas: floatf [])
+         (betas : floatf [])
+         nIters =
+
+      let mu0 = mu in
+
+      let mutable muHat    = mu0   in     
+      let mutable sigmaHat = sigma in     
+      let mu = Vector.create m 0.0 in  // nb: rebinds mu 
+      let pi = Vector.create m 0.0 in
+      let s  = Vector.create m 1.0 in
+
+      // pre-compute 
+      let aT = a |> Array.map (fun ai ->  ai.Transpose)  in
+
+      for i = 1 to nIters do
+       for j = 0 to m-1 do
+
+        // Pre-computations for jth factor 
+        let u      = sigmaHat * a.[j] in
+
+        let c      = aT.[j] * u   |> M2S in
+        let m      = aT.[j] * muHat |> M2S in
+        let d      = pi.[j] * c in
+        let phi    = m + d / (1.0 - d) * (m - mu.[j]) in
+        let psi    = c / (1.0 - d) in
+        let alpha  = alphas.[j] phi psi in
+        let beta   = betas.[j]  phi psi in
+       // ADF update 
+        muHat    <- (let factor = (pi.[j] * (m - mu.[j]) + alpha)  /  (1.0 - d) in
+                     muHat + (factor * u))
+        sigmaHat <- (let factor = (pi.[j] * (1.0 - d) - beta)  /  (1.0 - d) ** 2.0 in
+                     sigmaHat + (factor * (u * u.Transpose)))
+        // Factor update 
+        pi.[j] <- 1.0 / (inv beta - psi);
+        mu.[j] <- alpha / beta + phi;
+        s.[j]  <- z.[j] phi psi * exp ( sqr(alpha) / (2.0 * beta)) / sqrt (1.0 - psi * beta);
+       done;
+      done;
+
+
+      (* result *)
+      let sigmaInv    = symmetricInverse sigma     in
+      let sigmaHatInv = symmetricInverse sigmaHat in (* invertible? *)
+
+      let zHat =
+        Vector.prod s *
+        sqrt (determinant (sigmaHat * sigmaInv)) *
+        exp (-0.5 * ( Vector.dot pi (mu .* mu)
+                 + M2S (mu0.Transpose  *  sigmaInv * mu0)
+                 - M2S (muHat.Transpose * sigmaHatInv * muHat)))
+      in
+      muHat, sigmaHat, zHat
+
+    (*----------------------------------------------------------------------------
+    !* The MatLab version with hardwired functions
+     *--------------------------------------------------------------------------*)
+
+    let getV m i   = Matrix.get m i 0
+    let setV m i x = Matrix.set m i 0 x
+
+    (* TODO: syntax for matrix indexing and assignment *)
+    (* Recoded MatLab version *)
+    let zeros d = Matrix.create d 1 0.0
+    let expectationPropagationMatLab (mu,sigma) m (l,u) noIterations =
+      let siteMu            = zeros m in
+      let sitePi            = zeros m in
+      let siteS             = zeros m in
+      let newMu          = ref mu      in
+      let newSigma        = ref sigma   in
+
+      for i = 0 to noIterations-1 do
+        for j = 0 to m-1 do 
+          // prepare computation    
+          let t      = Matrix.init m 1 (fun i _ -> Matrix.get !newSigma i j) in
+          let d  = getV sitePi j * Matrix.get !newSigma j j in
+          let e  = 1.0 - d in
+          let phi  = getV !newMu j + d * (getV !newMu j - getV siteMu j) / e in
+          let psi  = Matrix.get !newSigma j j / e in
+          let sPsi  = sqrt psi in
+          let alpha  = v3 (phi / sPsi) (getV l j / sPsi) (getV u j / sPsi) / sPsi in
+          let beta  = w3 (phi / sPsi) (getV l j / sPsi) (getV u j / sPsi) / psi in
+          
+          // GDF update
+          newMu    := !newMu + (((getV sitePi j * (getV !newMu j - getV siteMu j) + alpha) / e) * t) ;
+          newSigma := !newSigma + (((getV sitePi j * e - beta) / (e * e)) * (t * Matrix.transpose t)) ;
+             
+          // Factor update
+          setV sitePi j (1.0 / (1.0/beta - psi));
+          setV siteMu j (alpha / beta + phi);
+          setV siteS  j ( (Phi ((getV u j - phi) / sPsi) - Phi ((getV l j - phi) / sPsi)) 
+                      * exp (alpha * alpha / (2.0 * beta)) / sqrt (1.0 - psi * beta))
+        done
+      done;
+      // compute the normalisation constant
+      let SigmaInv    = symmetricInverse sigma    in
+      let newSigmaInv = symmetricInverse !newSigma in
+      let Z = 
+         Matrix.prod siteS
+         * sqrt (determinant !newSigma / determinant sigma)
+         * exp (-0.5 * ( Matrix.dot sitePi (siteMu .* siteMu)
+                        + Matrix.toScalar (Matrix.transpose mu * SigmaInv * mu)
+                        - Matrix.toScalar (Matrix.transpose !newMu * newSigmaInv * !newMu)))
+      in
+      !newMu, !newSigma, Z
+
+
+    (*----------------------------------------------------------------------------
+    !* expectationPropagation - test code
+     *--------------------------------------------------------------------------*)
+
+    let mA = 1
+    let aA     = [| Matrix.create 3 1 0.2   |]
+    let zA     = [| fun (a:float) (b:float) -> a+b |]
+    let alphaA = [| fun (a:float) (b:float) -> 0.1 |]
+    let betaA  = [| fun (a:float) (b:float) -> 0.9 |]
+
+    let muA    = Matrix.create 3 1 0.2
+    let sigma' = matrix [[10.0; 2.0;-3.0];
+                         [ 2.0; 4.0; 5.0];
+                         [-3.0; 5.0;40.0]]
+    let sigmaA = Matrix.map (fun k -> k * 0.1) sigma'
+    let sInv  = symmetricInverse sigmaA (* check |R inverse exists *)
+
+
+    let nItersA = 8
+    let muHatA,sigmaHatA,zHatA = expectationPropagation (muA,sigmaA) mA (aA,zA,alphaA,betaA) nItersA
+
+    let dumpM str m = Printf.printf "%s:\n%O\n\n" str m
+    let dumpR str x = Printf.printf "%s = %f\n\n" str x
+    let _ = dumpM "muHat"    muHatA
+    let _ = dumpM "sigmaHat" sigmaHatA
+    let _ = dumpR "zHat"     zHatA
+
+
+    (*----------------------------------------------------------------------------
+    !* expectationPropagation - test code MatLab values
+     *--------------------------------------------------------------------------*)
+
+    (* Matlab:
+    >> [newMu, newSigma, evidence] = EP ([1;2],[[1 0];[0 2]], [0;0], [2; 3], 20)
+    newMu =
+        1.0000
+        1.6599
+    newSigma =
+        0.2911         0
+             0    0.6306
+    evidence =
+        0.4653
+    >>
+    >> help EP
+
+      EP		The EP algorithm for computing Gaussian approximation to a
+ 		    truncated Gaussian.
+     
+ 	    [newMu, newSigma, Z] = EP (mu, sigma, l, u, noIterations)
+     
+ 		    mu		mean of the untruncated Gaussian
+ 		    sigma		covariance of the untruncated Gaussian
+ 		    l		lower integration boundaries
+ 		    u		upper integration boundaries
+ 		    noIterations	number of iterations (default: 20)
+ 		    newMu		mean of the Gaussian approximation
+ 		    newSigma	covariance of the Gaussian approximation
+ 		    Z		normalisation constant of the untruncated Gaussian
+     
+      2005 written by Ralf Herbrich
+      Microsoft Research Ltd.
+    *)
+
+    let m = 2
+    let mu    = matrix [[1.0];[2.0]]
+    let sigma = matrix [[1.0; 0.0]; [0.0; 2.0]]
+    let l     = matrix [[0.0];[0.0]]
+    let u     = matrix [[2.0];[3.0]]
+    let nIters = 20
+
+    let x,y = l.Dimensions
+    let _ = assert(x=m)
+    let _ = assert(y=1)
+
+    let a     = [| matrix [[ 1.0]; [0.0 ]];
+                   matrix [[ 0.0]; [1.0 ]] |]
+                
+    (* factor l',u' *)
+    let zf j phi_j psi_j =
+      let k = inv(sqrt(psi_j)) in
+      let l_j' = Matrix.get l j 0 * k in
+      let u_j' = Matrix.get u j 0 * k in
+      phi (u_j' - phi_j * k) - phi (l_j' - phi_j * k)
+
+    let z = [| zf 0;zf 1 |]
+               
+    (* there is common code, compute both *)
+    let alpha i phi_i psi_i =
+      let root_psi_i = sqrt(psi_i) in
+      v3 (phi_i/root_psi_i) (Matrix.get l i 0 / root_psi_i) (Matrix.get u i 0 / root_psi_i) / root_psi_i
+
+    let beta i phi_i psi_i =
+      let root_psi_i = sqrt(psi_i) in
+      w3 (phi_i/root_psi_i) (Matrix.get l i 0 / root_psi_i) (Matrix.get u i 0 / root_psi_i) / psi_i
+
+        
+    let alphas = Array.init 2 (fun i -> alpha i)
+    let betas  = Array.init 2 (fun i -> beta  i)
+
+    let muHat ,sigmaHat ,zHat  = expectationPropagation (mu,sigma) m (a,z,alphas,betas) nIters
+
+    let _ = dumpM "muHat"    muHat 
+    let _ = dumpM "sigmaHat" sigmaHat   
+    let _ = dumpR "zHat"     zHat  
+
+
+
+    let muHatC,sigmaHatC,zHatC = expectationPropagationMatLab (mu,sigma) m (l,u) nIters
+
+    let _ = dumpM "muHatC"    muHatC 
+    let _ = dumpM "sigmaHatC" sigmaHatC   
+    let _ = dumpR "zHatC"     zHatC  
+
+    (*----------------------------------------------------------------------------
+    !* misc tests
+     *--------------------------------------------------------------------------*)
+
+
+    let _ = (box 1N).GetHashCode()
+    let _ = (box 1I).GetHashCode()
+    let _ = hash 10000000000000000000N
+    let _ = hash 1N
+    let _ = hash (-1N)
+    let _ = hash 1I
+    let _ = hash 1000000000000000000I
+    let _ = hash (-1I)
+    let _ = hash (-10000000000000000000000000000000000000000I)
+
+
+    (*----------------------------------------------------------------------------
+    !* comparison code
+     *--------------------------------------------------------------------------*)
+
+    
+    (*
+
+    // specific alpha and gamma functions
+    let alpha i phi psi (lower:matrix) (upper:matrix) = 
+	    let spsi = sqrt (psi) in 
+	    let u = upper.Item (i, 0)/spsi in
+	    if (System.Double.IsPositiveInfinity (u)) then
+		    1.0 / spsi * GaussianApproximations.v (phi/spsi, lower.Item (i, 0)/spsi)
+	    else
+		    1.0 / spsi * GaussianApproximations.v (phi/spsi, lower.Item (i, 0)/spsi, u)
+    	
+    let gamma i phi psi (lower:matrix) (upper:matrix) = 
+	    let spsi = sqrt (psi) in 
+	    let u = upper.Item (i, 0)/spsi in
+	    if (System.Double.IsPositiveInfinity (u)) then
+		    1.0 / psi * GaussianApproximations.w (phi/spsi, lower.Item (i, 0)/spsi)
+	    else
+		    1.0 / psi * GaussianApproximations.w (phi/spsi, lower.Item (i, 0)/spsi, u)
+    	
+    *)
+
+
+    (* FRAGS: test code
+
+    let n = 150
+    let mu = new Matrix (n, 1)
+    let sigma = new Matrix (n, n)
+    let A = new Matrix (n, n)
+    let lower = new Matrix (n, 1)
+    let upper = new Matrix (n, 1)
+
+    do
+      for i = 0 to n-1 do
+        mu.Item (i, 0) <- 1.0;
+        sigma.Item (i, i) <- 1.0 + (float) i;
+        A.Item (i, i) <- 1.0;
+        lower.Item (i, 0) <- 0.0;
+        upper.Item (i, 0) <- System.Double.PositiveInfinity;
+      done  
+
+    expectationPropagationMatLab (vnoc mu,vnoc sigma) n (vnoc lower,vnoc upper) 10
+
+    *)
+
+// These are really type checking tests
+module BasicOverloadTests = 
+
+    let f1 (a:matrix) (b:matrix) = a * b
+    let f2 (a:matrix) (b:vector) = a * b
+
+    let f12 (x1: Matrix<'a>) (x2: Matrix<'a>) = x1 * x2
+    let f13 (x1: Matrix<'a>) (x2: Vector<'a>) = x1 * x2
+    let f14 (x1: RowVector<'a>) (x2: Matrix<'a>) = x1 * x2
+
+    // Traditionally we've had a hard time supporting both 
+    //    'a * Matrix<'a>  -> Matrix<'a>
+    //    Matrix<'a> * 'a  -> Matrix<'a>
+    // overloads for multiplication. However these now work correctly
+    let f15 (x1: Matrix<float>) (x2: float) = x1 * x2
+    let f16 (x1: float) (x2: Matrix<float>) = x1 * x2
+    // This is an interesting case. Strictly speaking it seems there is not enough information to resolve the
+    // overload.
+    // let f23 (x1: Matrix<_>) (x2: Matrix<_>) = x1 * x2
+
+    let f24 (x1: Matrix<int>) (x2: Matrix<_>) = x1 * x2
+
+// These are really type checking tests
+module BasicGeneralizationTests = 
+    let MFMV = Microsoft.FSharp.Math.Vector.init 3 (fun i -> float(i))
+    let _ = MFMV.[1]
+    let _ = MFMV.[1] <- 3.13
+
+    // check we have generalized 
+    let MFMV_generic_function (k: 'a) = 
+      let MFMV = Microsoft.FSharp.Math.Vector.Generic.init 3 (fun i -> k) in
+      let _ = MFMV.[1] in
+      let _ =MFMV.[1] <- k in
+      ()
+
+    // check we have generalized 
+    do MFMV_generic_function 1
+    do MFMV_generic_function "3"
+
+    let MFMM = Microsoft.FSharp.Math.Matrix.init 3 3 (fun i j -> float(i+j))
+    let _ = MFMM.[1,1]
+    let _ = MFMM.[1,1] <- 3.13
+
+    // check we have generalized 
+    let MFMM_generic_function (k: 'a) = 
+      let MFMM = Microsoft.FSharp.Math.Matrix.Generic.init 3 3 (fun i j -> k) in
+      let _ = MFMM.[1,1] in
+      let _ =MFMM.[1,1] <- k in
+      ()
+
+    // check we have generalized 
+    do MFMM_generic_function 1
+    do MFMM_generic_function "3"
+
diff --git a/src/FSharp.PowerPack.Unittests/MetadataTests.fs b/src/FSharp.PowerPack.Unittests/MetadataTests.fs
new file mode 100755
index 0000000..fc46812
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/MetadataTests.fs
@@ -0,0 +1,425 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Metadata
+
+[<TestFixture>]
+type public MetadataTests() =
+  
+
+    let fsharpLibrary = Microsoft.FSharp.Metadata.FSharpAssembly.FSharpLibrary
+
+    let okAttribs (attrs:seq<FSharpAttribute>) = 
+        attrs |> Seq.forall (fun attr -> let ty = attr.ReflectionType in ty <> typeof<System.ObsoleteAttribute> && ty <> typeof<CompilerMessageAttribute>)
+
+    let okEntity (x:FSharpEntity) = x.Attributes |> okAttribs
+
+    let okVal (x:FSharpEntity,v:FSharpMemberOrVal) = v.Attributes |> okAttribs
+
+    let explore (library:FSharpAssembly) = 
+      for x in library.Entities do 
+        let rec loop (x:FSharpEntity) = 
+            if okEntity x then
+              logMessage (sprintf "entity %s : XMLDOC SIG = %s" x.DisplayName x.XmlDocSig)
+              for x in x.NestedEntities do 
+                 loop x
+              for v in x.MembersOrValues do 
+                   if okVal (x,v) then 
+                     logMessage (sprintf "value/member %s : XMLDOC SIG = %A" v.DisplayName v.XmlDocSig)
+        loop x
+    let seqItem item s = (s |> Seq.toArray).[item]
+
+    let assertEquality (o1:obj) (o2:obj) =
+        Assert.IsTrue((o1 = o2))
+        Assert.AreEqual(o1.GetHashCode(), o2.GetHashCode())
+
+    let assertInequality (o1:obj) (o2:obj) =
+        Assert.IsFalse((o1 = o2))
+        if o1.GetHashCode() = o2.GetHashCode() then
+            printfn "Same hashcode for unequal objects %A %A" o1 o2
+
+    let strictZip c1 c2 =
+        Assert.AreEqual(Seq.length c1, Seq.length c2)
+        Seq.zip c1 c2
+
+
+    [<Test>]
+    member this.Test1() = 
+
+        let fsharpEntity1 = fsharpLibrary.Entities |> Seq.find (fun y -> y.LogicalName = "ResizeArray`1")
+
+        check "cnwoein" fsharpEntity1.IsAbbreviation true 
+
+        // This gets the abbreviation 'ResizeArray<'T> = System.Collections.Generic.List<'T>'
+        let fsharpType1 = fsharpEntity1.AbbreviatedType
+
+        check "ckwjen0o" fsharpType1.IsNamed true
+
+        let fsharpEntity2 = fsharpType1.NamedEntity
+
+        check "ckwjen0o" fsharpEntity2.IsExternal true
+
+        let systemType = fsharpEntity2.ReflectionType
+        
+        check "ckwjen01" systemType.Name "List`1"
+        
+
+    [<Test>]
+    member this.Test2() = 
+
+        check "ckwfew0o4" fsharpLibrary.QualifiedName fsharpLibrary.ReflectionAssembly.FullName
+        check "ckwfew0o4" (fsharpLibrary.QualifiedName.Contains("FSharp.Core")) true
+
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.sbyte")
+
+        check "ckwfew0o441" fsharpEntity1.IsAbbreviation true    
+
+        // This gets the abbreviation 'sbyte = System.SByte'
+        let fsharpType1 = fsharpEntity1.AbbreviatedType
+
+        check "ckwjen0o4" fsharpType1.IsNamed true
+
+        let fsharpEntity2 = fsharpType1.NamedEntity
+
+        check "ckwjen0o4" fsharpEntity2.IsExternal true
+
+        let systemType = fsharpEntity2.ReflectionType
+        
+        check "ckwjen014" systemType typeof<sbyte>
+
+
+    [<Test>]
+    member this.Test3() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.sbyte")
+
+        check "ckwfew0o41" fsharpEntity1.IsExternal false
+        check "ckwfew0o42" fsharpEntity1.IsModule false
+        check "ckwfew0o43" fsharpEntity1.IsValueType false
+        check "ckwfew0o442" fsharpEntity1.LogicalName "sbyte"
+        check "ckwfew0o443" fsharpEntity1.IsAbbreviation true
+        check "ckwfew0o444" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types-prelude.fs")) true
+        check "ckwfew0o445" fsharpEntity1.HasAssemblyCodeRepresentation false
+        check "ckwfew0o446" fsharpEntity1.UnionCases.Count 0
+        check "ckwfew0o447" fsharpEntity1.RecordFields.Count 0
+        check "ckwfew0o448" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Core.sbyte"
+
+    // Test the entity used for an F# library module
+    [<Test>]
+    member this.Test4() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.LanguagePrimitives")
+
+        check "ckwfew0o41q" fsharpEntity1.IsExternal false
+        check "ckwfew0o42w" fsharpEntity1.IsModule true
+        check "ckwfew0o43e" fsharpEntity1.IsValueType false
+        check "ckwfew0o44r" fsharpEntity1.LogicalName "LanguagePrimitives"
+        check "ckwfew0o44t" fsharpEntity1.IsAbbreviation false
+        check "ckwfew0o44y" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types.fs")) true
+        check "ckwfew0o44u" fsharpEntity1.HasAssemblyCodeRepresentation false
+        check "ckwfew0o44i" fsharpEntity1.UnionCases.Count 0
+        check "ckwfew0o44o" fsharpEntity1.RecordFields.Count 0
+        check "ckwfew0o44p" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Core.LanguagePrimitives"
+
+    // Test the entity used for F# floating point types annotated with units of measure
+    [<Test>]
+    member this.Test5() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.float`1")
+
+        check "ckwfew0o41" fsharpEntity1.IsExternal false
+        check "ckwfew0o42" fsharpEntity1.IsModule false
+        check "ckwfew0o43" fsharpEntity1.IsValueType false
+        check "ckwfew0o44a" fsharpEntity1.LogicalName "float`1"
+        check "ckwfew0o44s" fsharpEntity1.IsAbbreviation false
+        check "ckwfew0o44d" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types.fs")) true
+        check "ckwfew0o44f" fsharpEntity1.HasAssemblyCodeRepresentation true
+        check "ckwfew0o44g" fsharpEntity1.UnionCases.Count 0
+        check "ckwfew0o44h" fsharpEntity1.RecordFields.Count 0
+        check "ckwfew0o44j" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Core.float`1"
+
+    // Test the entity used for F# array types
+    [<Test>]
+    member this.Test6() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.[]`1")
+
+        check "ckwfew0o41" fsharpEntity1.IsExternal false
+        check "ckwfew0o42" fsharpEntity1.IsModule false
+        check "ckwfew0o43" fsharpEntity1.IsValueType false
+        check "ckwfew0o44k" fsharpEntity1.LogicalName "[]`1"
+        check "ckwfew0o44l" fsharpEntity1.IsAbbreviation false
+        check "ckwfew0o44z" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types-prelude.fs")) true
+        check "ckwfew0o44x" fsharpEntity1.HasAssemblyCodeRepresentation true
+        check "ckwfew0o44c" fsharpEntity1.UnionCases.Count 0
+        check "ckwfew0o44v" fsharpEntity1.RecordFields.Count 0
+        check "ckwfew0o44b" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Core.[]`1"
+
+    // Test the value used for List.map
+    [<Test>]
+    member this.Test7() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Collections.ListModule")
+        let v = fsharpEntity1.MembersOrValues |> Seq.find (fun x -> x.CompiledName = "Map") 
+        
+        
+        check "ckwfew0o47qa" v.CompiledName "Map"
+        check "ckwfew0o47qb" v.IsCompilerGenerated false
+        check "ckwfew0o47qc" v.IsExtensionMember false
+        check "ckwfew0o47qd" v.IsImplicitConstructor false
+        check "ckwfew0o47qe" v.IsModuleValueOrMember true
+        check "ckwfew0o47qf" v.InlineAnnotation Microsoft.FSharp.Metadata.FSharpInlineAnnotation.OptionalInline
+        check "ckwfew0o47qg" v.IsMutable false
+        check "ckwfew0o47qh" v.IsTypeFunction false
+        check "ckwfew0o47qh" v.XmlDocSig "M:Microsoft.FSharp.Collections.ListModule.Map``2(Microsoft.FSharp.Core.FSharpFunc`2{``0,``1},Microsoft.FSharp.Collections.FSharpList{``0})"
+        
+        check "ckwfew0o47w" v.CurriedParameterGroups.Count 2
+        check "ckwfew0o47e" v.CurriedParameterGroups.[0].Count 1
+        check "ckwfew0o47r" v.CurriedParameterGroups.[1].Count 1
+        check "ckwfew0o47t" v.CurriedParameterGroups.[0].[0].Name "mapping"
+        check "ckwfew0o47y" v.CurriedParameterGroups.[1].[0].Name "list"
+        check "ckwfew0o47u" v.CurriedParameterGroups.[0].[0].Type.IsFunction true
+        check "ckwfew0o47i" v.CurriedParameterGroups.[0].[0].Type.IsNamed false
+        check "ckwfew0o47o" v.CurriedParameterGroups.[0].[0].Type.IsTuple false
+        check "ckwfew0o47p" v.CurriedParameterGroups.[0].[0].Type.IsGenericParameter false
+
+        check "ckwfew0o47a" (v.CurriedParameterGroups.[0].[0].Type.GenericArguments.[0].IsGenericParameter) true
+        check "ckwfew0o47s" (v.CurriedParameterGroups.[0].[0].Type.GenericArguments.[0].GenericParameterIndex) 0
+        check "ckwfew0o47d" (v.CurriedParameterGroups.[0].[0].Type.GenericArguments.[1].IsGenericParameter) true
+        check "ckwfew0o47f" (v.CurriedParameterGroups.[0].[0].Type.GenericArguments.[1].GenericParameterIndex) 1
+
+        check "ckwfew0o47g" v.CurriedParameterGroups.[1].[0].Type.IsFunction false
+        check "ckwfew0o47h" v.CurriedParameterGroups.[1].[0].Type.IsNamed true
+        check "ckwfew0o47j" v.CurriedParameterGroups.[1].[0].Type.IsTuple false
+        check "ckwfew0o47k" v.CurriedParameterGroups.[1].[0].Type.IsGenericParameter false
+
+        check "ckwfew0o47l" (v.CurriedParameterGroups.[1].[0].Type.NamedEntity.LogicalName) "list`1"
+        check "ckwfew0o47z" (v.CurriedParameterGroups.[1].[0].Type.NamedEntity.IsAbbreviation) true
+        check "ckwfew0o47x" (v.CurriedParameterGroups.[1].[0].Type.GenericArguments.Count) 1
+        check "ckwfew0o47c" (v.CurriedParameterGroups.[1].[0].Type.GenericArguments.[0].IsGenericParameter) true
+        check "ckwfew0o47v" (v.CurriedParameterGroups.[1].[0].Type.GenericArguments.[0].GenericParameterIndex) 0
+        check "ckwfew0o47b" (v.CurriedParameterGroups.[1].[0].Type.NamedEntity.IsAbbreviation) true
+
+        check "ckwfew0o47n" (v.ReturnParameter.Type.NamedEntity.LogicalName) "list`1"
+        check "ckwfew0o47m" (v.ReturnParameter.Type.GenericArguments.Count) 1
+        check "ckwfew0o474" (v.ReturnParameter.Type.GenericArguments.[0].IsGenericParameter) true
+        check "ckwfew0o475" (v.ReturnParameter.Type.GenericArguments.[0].GenericParameterIndex) 1
+
+    // Test the value for (|||)
+    [<Test>]
+    member this.Test7b() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.Operators")
+        let v = fsharpEntity1.MembersOrValues |> Seq.find (fun x -> x.CompiledName = "op_BitwiseOr") 
+        
+        
+        check "ckwfew0o47qa" v.CompiledName "op_BitwiseOr"
+        check "ckwfew0o47qb" v.IsCompilerGenerated false
+        check "ckwfew0o47qb" v.IsActivePattern false
+        check "ckwfew0o47qc" v.IsExtensionMember false
+        check "ckwfew0o47qd" v.IsImplicitConstructor false
+        check "ckwfew0o47qe" v.IsModuleValueOrMember true
+        check "ckwfew0o47qf" v.InlineAnnotation Microsoft.FSharp.Metadata.FSharpInlineAnnotation.PsuedoValue
+        check "ckwfew0o47qg" v.IsMutable false
+        check "ckwfew0o47qh" v.IsTypeFunction false
+        
+
+    // Test the value used for .Length on the list type
+    [<Test>]
+    member this.Test8() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Collections.List`1")
+        fsharpEntity1.MembersOrValues |> Seq.iter (fun x -> printfn "Found member '%s' in List`1 metadata" x.CompiledName)
+        let v = fsharpEntity1.MembersOrValues |> Seq.find (fun x -> x.CompiledName = "get_Length") 
+        
+        
+        check "ckwfew0o48q" v.CompiledName "get_Length"
+        // one argument group, no entries in it
+        check "ckwfew0o48w" v.CurriedParameterGroups.Count 1
+        check "ckwfew0o48w" v.CurriedParameterGroups.[0].Count 0
+
+        check "ckwfew0o48n" (v.ReturnParameter.Type.NamedEntity.LogicalName) "int"
+        check "ckwfew0o48m" (v.ReturnParameter.Type.GenericArguments.Count) 0
+
+
+    [<Test>]
+    member this.Test9() = 
+
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Collections.List`1")
+
+        check "ckwfew0o41" fsharpEntity1.IsExternal false
+        check "ckwfew0o42" fsharpEntity1.IsModule false
+        check "ckwfew0o43" fsharpEntity1.IsValueType false
+        check "ckwfew0o44" fsharpEntity1.LogicalName "List`1"
+        check "ckwfew0o44" fsharpEntity1.CompiledName "FSharpList`1"
+        check "ckwfew0o44" fsharpEntity1.IsAbbreviation false
+        check "ckwfew0o44" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types.fs")) true
+        check "ckwfew0o44" fsharpEntity1.HasAssemblyCodeRepresentation false
+        check "ckwfew0o44" fsharpEntity1.UnionCases.Count 2
+        check "ckwfew0o44" fsharpEntity1.RecordFields.Count 0
+        check "ckwfew0o44" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Collections.FSharpList`1"
+
+
+    [<Test>]
+    member this.Test10() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.Ref`1")
+
+        check "ckwfew0o41" fsharpEntity1.IsExternal false
+        check "ckwfew0o42" fsharpEntity1.IsModule false
+        check "ckwfew0o43" fsharpEntity1.IsValueType false
+        check "ckwfew0o44" fsharpEntity1.LogicalName "Ref`1"
+        check "ckwfew0o44" fsharpEntity1.CompiledName "FSharpRef`1"
+        check "ckwfew0o44" fsharpEntity1.IsAbbreviation false
+        check "ckwfew0o44" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types.fs")) true
+        check "ckwfew0o44" fsharpEntity1.HasAssemblyCodeRepresentation false
+        check "ckwfew0o44" fsharpEntity1.UnionCases.Count 0
+        check "ckwfew0o44" fsharpEntity1.RecordFields.Count 1
+        check "ckwfew0o44" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Core.FSharpRef`1"
+
+
+
+    [<Test>]
+    member this.TraversalTestLookingForBadDocumentation() = 
+
+         for x in fsharpLibrary.Entities do 
+             if x.IsModule then 
+                 printfn "module: Name = %s, QualifiedName = %s" x.LogicalName x.QualifiedName
+                 
+         for x in fsharpLibrary.Entities do 
+             if not x.IsModule && not x.IsAbbreviation && not x.HasAssemblyCodeRepresentation then 
+                 printfn "type: Name = %s, QualifiedName = %s" x.LogicalName x.QualifiedName
+
+         for x in fsharpLibrary.Entities do 
+             if x.HasAssemblyCodeRepresentation then 
+                 printfn "mapped to assembly code: Name = %s" x.LogicalName 
+
+         for x in fsharpLibrary.Entities do 
+             if x.IsAbbreviation then 
+                 printfn "type abbreviation: Name = %s" x.LogicalName 
+
+         for x in fsharpLibrary.Entities do 
+            for v in x.NestedEntities do 
+               printfn "nested entity : Name = %s.%s" x.LogicalName v.LogicalName 
+
+         for x in fsharpLibrary.Entities do 
+            printfn "entity: Name = %s" x.LogicalName 
+            for v in x.MembersOrValues do 
+               printfn "member : Name = %s.%s" x.LogicalName v.CompiledName
+               for ps in v.CurriedParameterGroups do 
+                   for p in ps do 
+                       printfn "       : Parameter %s" p.Name 
+
+         printfn "--------------------- ERRORS----------------------------------"
+
+             //x.IsAbbreviation  || 
+             //x.HasAssemblyCodeRepresentation || 
+             //(x.ReflectionType.GetCustomAttributes(typeof<System.ObsoleteAttribute>,true).Length = 0 && x.ReflectionType.GetCustomAttributes(typeof<OCamlCompatibilityAttribute>,true).Length = 0) 
+
+            //not (v.CompiledName.Contains "_") && 
+            // (v.CompiledName = ".ctor" 
+            // || x.IsAbbreviation  
+            // || x.HasAssemblyCodeRepresentation 
+            // || (let minfos = x.ReflectionType.GetMethods() |> Array.filter (fun m -> m.Name = v.CompiledName) 
+            //     minfos |> Array.exists (fun minfo -> minfo.GetCustomAttributes(typeof<System.ObsoleteAttribute>,true).Length = 0 && minfo.GetCustomAttributes(typeof<OCamlCompatibilityAttribute>,true).Length = 0)))
+         
+         for x in fsharpLibrary.Entities do 
+            let rec loop (x:FSharpEntity) = 
+                if okEntity x then
+                  for x in x.NestedEntities do 
+                     loop x
+                  for v in x.MembersOrValues do 
+                   if okVal (x,v) then 
+                     for ps in v.CurriedParameterGroups do 
+                       for p in ps do 
+                           match p.Name with 
+                           | null -> printfn "member %s.%s : NULL PARAMETER NAME" x.LogicalName v.CompiledName
+                           | _ -> ()
+            loop x
+                          
+
+    [<Test>]
+    member this.ExploreFSharpCore() = explore fsharpLibrary
+
+    [<Test>]
+    member this.ExploreFSharpPowerPack() = explore (FSharpAssembly.FromFile(@"FSharp.PowerPack.dll"))
+    
+    [<Test>]
+    member this.ExploreFSharpPowerPackLinq() = explore (FSharpAssembly.FromFile(@"FSharp.PowerPack.Linq.dll"))
+                    
+    [<Test>]
+    member this.LoadPowerPack() = FSharpAssembly.FromFile(@"FSharp.PowerPack.dll") |> ignore
+
+    [<Test>]
+    member this.LoadPowerPackLinq() =  FSharpAssembly.FromFile(@"FSharp.PowerPack.Linq.dll") |> ignore
+
+    [<Test>]
+    member this.TestMultipleAssemblies() =        
+        let fscore = FSharpAssembly.FSharpLibrary
+        let list = fscore.GetEntity("Microsoft.FSharp.Collections.List`1")
+        let fscore1 = FSharpAssembly.FromAssembly(typedefof<list<_>>.Assembly)
+        let list1 = fscore1.GetEntity("Microsoft.FSharp.Collections.List`1")
+        Assert.IsTrue((list = list1))
+        Assert.IsTrue((fscore = fscore1))
+
+    [<Test>]
+    member this.TestEqualityOnEntities() =        
+        let fscore = FSharpAssembly.FSharpLibrary
+        let list1 = fscore.GetEntity("Microsoft.FSharp.Collections.List`1")
+        let unitE = fscore.GetEntity("Microsoft.FSharp.Core.unit")
+        let list2 = fscore.GetEntity("Microsoft.FSharp.Collections.List`1")
+        assertEquality list1 list2
+        assertInequality list1 unitE
+
+
+        // Union cases
+        for (uc1,uc2) in Seq.zip list1.UnionCases list2.UnionCases do
+            Assert.IsTrue((uc1 = uc2), sprintf "%A <> %A" uc1 uc2)
+            for (f1,f2) in strictZip uc1.Fields uc2.Fields do
+                assertEquality f1 f2
+        assertInequality (list1.UnionCases |> Seq.toArray).[0] (list1.UnionCases |> Seq.toArray).[1]
+        let consE = (list1.UnionCases |> Seq.toArray).[1]
+        assertInequality (consE.Fields |> Seq.toArray).[0]  (consE.Fields |> Seq.toArray).[1]
+
+        // Generic type parameters
+        let event1 = fscore.GetEntity "Microsoft.FSharp.Control.Event`2"
+        let event2 = fscore.GetEntity "Microsoft.FSharp.Control.Event`2"
+        assertEquality event1 event2
+        for (p1,p2) in strictZip event1.GenericParameters event2.GenericParameters do
+            assertEquality p1 p2
+
+        assertInequality (event1.GenericParameters |> Seq.toArray).[0]  (event1.GenericParameters |> Seq.toArray).[1]
+        assertInequality (event1.GenericParameters |> Seq.toArray).[0]  (event2.GenericParameters |> Seq.toArray).[1]
+
+        // parameters
+        let listMap () = 
+            fscore.GetEntity("Microsoft.FSharp.Collections.ListModule").MembersOrValues |> Seq.find (fun m -> m.DisplayName = "map")
+        let map1 = listMap()
+        let map2 = listMap()
+        assertEquality map1 map2
+        for cp1,cp2 in strictZip map1.CurriedParameterGroups map2.CurriedParameterGroups do
+            for p1,p2 in strictZip cp1 cp2 do
+                assertEquality p1 p2
+        let p1 = map1.CurriedParameterGroups |> seqItem 0 |> seqItem 0
+        let p2 = map1.CurriedParameterGroups |> seqItem 1 |> seqItem 0
+        assertInequality p1 p2
+
+        // attributes
+        let map1Attrs = map1.Attributes
+        let map2Attrs = map2.Attributes
+        for a1, a2 in strictZip map1Attrs map2Attrs do
+            assertEquality a1 a2
+
+        let zip =
+            fscore.GetEntity("Microsoft.FSharp.Collections.ListModule").MembersOrValues |> Seq.find (fun m -> m.DisplayName = "zip")
+        assertInequality (zip.Attributes |> seqItem 0) (map1Attrs |> seqItem 0)
+
+
+    [<Test>]
+    member this.TestTypeEquality() =
+        let fscoreEnt = FSharpAssembly.FSharpLibrary.GetEntity
+        let listModule = fscoreEnt "Microsoft.FSharp.Collections.ListModule"
+        Assert.IsNotNull listModule
+        let mapFun = listModule.MembersOrValues |> Seq.find (fun m -> m.DisplayName = "map")
+        let t = mapFun.Type
+        assertEquality t t
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/NORTHWND.MDF b/src/FSharp.PowerPack.Unittests/NORTHWND.MDF
new file mode 100755
index 0000000..aa2c06a
Binary files /dev/null and b/src/FSharp.PowerPack.Unittests/NORTHWND.MDF differ
diff --git a/src/FSharp.PowerPack.Unittests/NUnitFrameworkShims.fs b/src/FSharp.PowerPack.Unittests/NUnitFrameworkShims.fs
new file mode 100755
index 0000000..7dc4e58
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/NUnitFrameworkShims.fs
@@ -0,0 +1,79 @@
+namespace NUnit.Framework
+open System
+
+type TestFixtureAttribute() =
+    inherit System.Attribute()
+
+type TestAttribute() =
+    inherit System.Attribute()
+
+type SetUpAttribute() =
+    inherit System.Attribute()
+
+type TestFixtureSetUpAttribute() =
+    inherit System.Attribute()
+
+
+type TearDownAttribute() =
+    inherit System.Attribute()
+
+type TestFixtureTearDownAttribute() =
+    inherit System.Attribute()
+
+type IgnoreAttribute(reason:string) =
+    inherit System.Attribute()
+
+exception AssertionException of string
+
+module private Impl =
+    let rec equals (expected:obj) (actual:obj) = 
+        match expected, actual with 
+        |   (:? Array as a1), (:? Array as a2) ->
+                if a1.Rank > 1 then failwith "Rank > 1 not supported"                
+                if a2.Rank > 1 then false
+                else
+                    let lb = a1.GetLowerBound(0)
+                    let ub = a1.GetUpperBound(0)
+                    if lb <> a2.GetLowerBound(0) || ub <> a2.GetUpperBound(0) then false
+                    else
+                        {lb..ub} |> Seq.forall(fun i -> equals (a1.GetValue(i)) (a2.GetValue(i)))    
+        |   _ ->
+                Object.Equals(expected, actual)
+
+type Assert = 
+    
+
+    static member AreEqual(expected : obj, actual : obj, message : string) =
+        if not (Impl.equals expected actual) then
+            let message = sprintf "%s: Expected %A but got %A" message expected actual
+            AssertionException message |> raise
+
+    static member AreNotEqual(expected : obj, actual : obj, message : string) =
+        if Impl.equals expected actual then
+            let message = sprintf "%s: Expected not %A but got %A" message expected actual
+            AssertionException message |> raise
+
+
+    static member AreEqual(expected : obj, actual : obj) = Assert.AreEqual(expected, actual, "Assertion")
+
+    static member AreNotEqual(expected : obj, actual : obj) = Assert.AreNotEqual(expected, actual, "Assertion")
+
+    static member IsNull(o : obj) = Assert.AreEqual(null, o)
+
+    static member IsTrue(x : bool, message : string) =
+        if not x then
+            AssertionException(message) |> raise
+
+    static member IsTrue(x : bool) = Assert.IsTrue(x, "")
+
+    static member IsFalse(x : bool, message : string) =
+        if x then
+            AssertionException(message) |> raise
+
+    static member IsFalse(x : bool) = Assert.IsFalse(x, "")
+
+    static member Fail(message : string) = AssertionException(message) |> raise
+    
+    static member Fail() = Assert.Fail("") 
+
+    static member Fail(message : string, args : obj[]) = Assert.Fail(String.Format(message,args))
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/NativeArrayTests.fs b/src/FSharp.PowerPack.Unittests/NativeArrayTests.fs
new file mode 100755
index 0000000..9f02c79
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/NativeArrayTests.fs
@@ -0,0 +1,554 @@
+namespace FSharp.PowerPack.Unittests
+
+open NUnit.Framework
+open System.Collections.Generic
+open System.Runtime.InteropServices
+open System.Diagnostics
+open System
+open System.Windows.Forms
+open System.Drawing
+open Microsoft.FSharp.NativeInterop
+open Microsoft.FSharp.Math
+
+#nowarn "9"
+#nowarn "51"
+
+module PrimitiveBindings = 
+
+    /// LAPACK/BLAS primitive matrix/matrix multiply routine
+    [<DllImport(@"blas.dll",EntryPoint="dgemm_")>]
+    extern void DoubleMatrixMultiply_(char* transa, char* transb, int* m, int* n, int *k,
+                                      double* alpha, double* A, int* lda,double* B, int* ldb,
+                                      double* beta,
+                                      double* C, int* ldc);
+
+    ///  C := alpha*op( A )*op( B ) + beta*C
+    let DoubleMatrixMultiply trans alpha (A: FortranMatrix<double>) (B: FortranMatrix<double>) beta (C: FortranMatrix<double>) = 
+        // Mutable is needed because F# only lets you take pointers to mutable values
+        let mutable trans = trans  // nb. unchanged on exit 
+        let mutable beta = beta 
+        let mutable alpha = alpha 
+        let mutable m = A.NumCols 
+        let mutable n = B.NumRows 
+        let mutable k = A.NumRows 
+        let mutable lda = A.NumCols 
+        // Call the BLAS/LAPACK routine
+        DoubleMatrixMultiply_(&&trans, &&trans, &&m, &&n, &&k, &&alpha, A.Ptr, &&lda, B.Ptr, &&k, &&beta, C.Ptr, &&m)
+
+    /// LAPACK/BLAS primitive matrix/vector multiply routine
+    [<DllImport(@"blas.dll",EntryPoint="dgemv_")>]
+    extern void DoubleMatrixVectorMultiply_(char* trans, int* m, int* n,
+                                            double* alpha, double* A, int* lda,
+                                            double* x, int* incx, double* beta,
+                                            double* y, int* incy);
+
+    let DoubleMatrixVectorMultiply trans alpha (A: FortranMatrix<double>) (B: NativeArray<double>) beta (C: NativeArray<double>) = 
+        let mutable trans = trans
+        let mutable beta = beta 
+        let mutable alpha = alpha 
+        let mutable m = A.NumCols 
+        let mutable n = A.NumRows 
+        let mutable i_one = 1
+        // Call the BLAS/LAPACK routine
+        DoubleMatrixVectorMultiply_(&&trans, &&m, &&n, &&alpha, A.Ptr, &&m, B.Ptr, &&i_one, &&beta, C.Ptr, &&i_one)
+
+
+    [<DllImport(@"lapack.dll", EntryPoint="dgetrf_")>]
+    extern void DoublePLUDecomposition_(int *m, int *n, double *a, int* lda, int *ipiv, int *info);
+
+    let DoublePLUDecomposition (A : FortranMatrix<double>) (ipiv : NativeArray<int>) = 
+        let mutable m = A.NumCols
+        let mutable n = A.NumRows
+        let mutable info = 0
+        let mutable lda = A.NumCols
+        DoublePLUDecomposition_(&&m, &&n, A.Ptr, &&lda, ipiv.Ptr, &&info);
+        match info with 
+        | -1 -> invalid_arg "m"
+        | -2 -> invalid_arg "n"
+        | -3 -> invalid_arg "A"
+        | -4 -> invalid_arg "lda"
+        | -5 -> invalid_arg "ipiv"
+        | -6 -> invalid_arg "info"
+        | 0 -> ()
+        | n -> invalid_arg (sprintf "singular: U(%d,%d) is zero" n n)
+
+
+    [<DllImport(@"lapack.dll", EntryPoint="dgetrs_")>]
+    extern void DoubleSolveAfterPLUDecomposition_(char *trans, int *n, int *nrhs, double *a, int *lda, int *ipiv, double*b, int * ldb, int*info)
+
+    let DoubleSolveAfterPLUDecomposition trans (A : FortranMatrix<double>) (B : FortranMatrix<double>) (ipiv : NativeArray<int>) = 
+        let mutable trans = trans
+        let mutable n = A.NumRows
+        let mutable nrhs = B.NumCols
+        let mutable lda = n
+        let mutable ldb = n
+        let mutable info = 0
+        DoubleSolveAfterPLUDecomposition_(&&trans, &&n, &&nrhs, A.Ptr, &&lda, ipiv.Ptr, B.Ptr, &&ldb, &&info);
+        match info with 
+        | -1 -> invalid_arg "trans"
+        | -2 -> invalid_arg "n"
+        | -3 -> invalid_arg "nrhs"
+        | -4 -> invalid_arg "A"
+        | -5 -> invalid_arg "lda"
+        | -6 -> invalid_arg "ipiv"
+        | -7 -> invalid_arg "B"
+        | -8 -> invalid_arg "ldb"
+        | -9 -> invalid_arg "info"
+        | _ -> ()
+
+    [<DllImport(@"lapack.dll", EntryPoint="dgeev_")>]
+    extern void DoubleComputeEigenValuesAndVectors_(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *wr, double *wi, double *vl, 
+                                                    int *ldvl, double *vr, int *ldvr, double*work, int *lwork, int*info);
+
+    let DoubleComputeEigenValuesAndVectors jobvl jobvr (A : FortranMatrix<double>) (WR : NativeArray<double>) (WI : NativeArray<double>) (VL : FortranMatrix<double>) (VR : FortranMatrix<double>) (workspace : NativeArray<double>) = 
+        let mutable jobvl = jobvl
+        let mutable jobvr = jobvr
+        let mutable lda = A.NumCols
+        let mutable n = A.NumRows
+        let mutable n = A.NumRows
+        let mutable ldvl = VL.NumCols
+        let mutable ldvr = VR.NumCols
+        let mutable lwork = workspace.Length
+        let mutable info = 0
+        DoubleComputeEigenValuesAndVectors_(&&jobvl, &&jobvr, &&n, A.Ptr, &&lda, WR.Ptr, WI.Ptr, VL.Ptr, &&ldvl, VR.Ptr, &&ldvr,workspace.Ptr, &&lwork, &&info);
+        match info with 
+        | -1 -> invalid_arg "jobvl"
+        | -2 -> invalid_arg "jobvr"
+        | -3 -> invalid_arg "n"
+        | -4 -> invalid_arg "A"
+        | -5 -> invalid_arg "lda"
+        | -6 -> invalid_arg "wr"
+        | -7 -> invalid_arg "wi"
+        | -8 -> invalid_arg "vl"
+        | -9 -> invalid_arg "ldvl"
+        | -10 -> invalid_arg "vr"
+        | -11 -> invalid_arg "ldvr"
+        | -12 -> invalid_arg "work"
+        | -13 -> invalid_arg "lwork"
+        | -14 -> invalid_arg "info"
+        | _ -> ()
+
+    let DoubleComputeEigenValuesAndVectorsWorkspaceSize jobvl jobvr (A : FortranMatrix<double>)  = 
+        let mutable jobvl = jobvl
+        let mutable jobvr = jobvr
+        let mutable lda = A.NumCols
+        let mutable n = A.NumRows
+        let mutable ldvl = n
+        let mutable ldvr = n
+        let mutable lwork = -1
+        let mutable workspaceSize = 0
+        let mutable info = 0
+        printf "DoubleComputeEigenValuesAndVectorsWorkspaceSize\n" ;
+        DoubleComputeEigenValuesAndVectors_(&&jobvl, &&jobvr, &&n, A.Ptr, &&lda, A.Ptr, A.Ptr, A.Ptr, &&ldvl, A.Ptr, &&ldvr,NativePtr.ofNativeInt (NativePtr.toNativeInt (&&workspaceSize)), &&lwork, &&info);
+        printf "workspaceSize = %d\n" workspaceSize;
+        match info with 
+        | -1 -> invalid_arg "jobvl"
+        | -2 -> invalid_arg "jobvr"
+        | -3 -> invalid_arg "n"
+        | -4 -> invalid_arg "A"
+        | -5 -> invalid_arg "lda"
+        | -6 -> invalid_arg "wr"
+        | -7 -> invalid_arg "wi"
+        | -8 -> invalid_arg "vl"
+        | -9 -> invalid_arg "ldvl"
+        | -10 -> invalid_arg "vr"
+        | -11 -> invalid_arg "ldvr"
+        | -12 -> invalid_arg "work"
+        | -13 -> invalid_arg "lwork"
+        | -14 -> invalid_arg "info"
+        | _ -> workspaceSize
+
+
+//----------------------------------------------------------------------------
+/// Tutorial Part 3. LAPACK accepts Fortran matrices, though often permits flags 
+/// to view the input matrices a transposed way.  This is a pain. Here we
+/// use some implicit transpose trickery and transpose settings to give 
+/// a view of these operations oeprating over CMatrix values.  Note that no actual
+/// copying of matrix data occurs.
+
+module PrimitiveCMatrixBindings = 
+
+     /// Here we builda  version that operates on row-major data
+    let DoubleMatrixMultiply alpha (A: CMatrix<double>) (B: CMatrix<double>) beta (C: CMatrix<double>) = 
+        Debug.Assert(A.NumCols = B.NumRows);
+        // Lapack is column-major, so we give it the implicitly transposed matrices and reverse their order:
+        // C <- A*B   ~~> C' <- (B'*A')
+        PrimitiveBindings.DoubleMatrixMultiply 'n' alpha B.NativeTranspose A.NativeTranspose beta C.NativeTranspose
+
+    let DoubleMatrixVectorMultiply alpha (A: CMatrix<double>) (B: NativeArray<double>) beta (C: NativeArray<double>) = 
+        Debug.Assert(A.NumCols = B.Length);
+        // Lapack is column-major, so we tell it that A is transposed. The 't' and the A.NativeTranspose effectively cancel.
+        // C <- A*B   ~~> C <- (A''*B)
+        PrimitiveBindings.DoubleMatrixVectorMultiply 't' alpha A.NativeTranspose B beta C
+
+    let DoubleSolveAfterPLUDecomposition (A : CMatrix<double>) (B : FortranMatrix<double>) (ipiv : NativeArray<int>) = 
+        Debug.Assert(A.NumRows = A.NumCols);
+        Debug.Assert(A.NumCols = B.NumRows);
+        Debug.Assert(ipiv.Length = A.NumRows);
+        // Lapack is column-major, so we solve A' X = B.  
+        PrimitiveBindings.DoubleSolveAfterPLUDecomposition 'T' A.NativeTranspose B ipiv
+        
+    let DoubleComputeEigenValues (A: CMatrix<double>) (WR: NativeArray<double>) (WI: NativeArray<double>) (workspace: NativeArray<double>) = 
+        Debug.Assert(A.NumCols = A.NumRows);
+        Debug.Assert(A.NumCols = WR.Length);
+        Debug.Assert(A.NumCols = WI.Length);
+        Debug.Assert(workspace.Length >= max 1 (3*A.NumCols));
+        let dummy = A.NativeTranspose 
+        // Lapack is column-major, but the eigen values of the transpose are the same as the eigen values of A
+        // C <- A*B   ~~> C <- (A''*B)
+        PrimitiveBindings.DoubleComputeEigenValuesAndVectors 'v' 'v' A.NativeTranspose WR WI dummy dummy workspace
+      
+    let DoubleComputeEigenValuesAndVectors (A: CMatrix<double>) (WR: NativeArray<double>) (WI: NativeArray<double>) (VR: FortranMatrix<double>) (workspace: NativeArray<double>) = 
+        Debug.Assert(A.NumCols = A.NumRows);
+        Debug.Assert(A.NumCols = WR.Length);
+        Debug.Assert(A.NumCols = WI.Length);
+        Debug.Assert(workspace.Length >= max 1 (3*A.NumCols));
+        let dummy = A.NativeTranspose 
+        // Lapack is column-major, but the eigen values of the transpose are the same as the eigen values of A
+        // C <- A*B   ~~> C <- (A''*B)
+        PrimitiveBindings.DoubleComputeEigenValuesAndVectors 'n' 'v' A.NativeTranspose WR WI dummy VR workspace
+      
+    let DoubleComputeEigenValuesWorkspace (A: CMatrix<double>) = 
+        Debug.Assert(A.NumCols = A.NumRows);
+        let dummy = A.NativeTranspose 
+        // Lapack is column-major, but the eigen values of the transpose are the same as the eigen values of A
+        // C <- A*B   ~~> C <- (A''*B)
+        PrimitiveBindings.DoubleComputeEigenValuesAndVectorsWorkspaceSize 'n' 'n' A.NativeTranspose 
+        
+
+//----------------------------------------------------------------------------
+/// Tutorial Part 4. To pass F# data structures to C and Fortran you need to
+/// pin the underlying array objects.  This can be done entirely F# code.
+///
+
+module NativeUtilities = 
+    let nativeArray_as_CMatrix_colvec (arr: 'a NativeArray) =
+       new CMatrix<_>(arr.Ptr,arr.Length,1)
+       
+    let nativeArray_as_FortranMatrix_colvec (arr: 'a NativeArray) =
+       new FortranMatrix<_>(arr.Ptr,arr.Length,1)
+       
+    (* Functions to pin and free arrays *)
+    let pinM m = PinnedArray2.of_matrix(m)
+    let pinV v = PinnedArray.of_vector(v)
+    let pinA arr = PinnedArray.of_array(arr)
+    let pinMV m1 v2 = pinM m1,pinV v2
+    let pinVV v1 v2 = pinV v1,pinV v2
+    let pinAA v1 v2 = pinA v1,pinA v2
+    let pinMVV m1 v2 m3 = pinM m1,pinV v2,pinV m3
+    let pinMM m1 m2  = pinM m1,pinM m2
+    let pinMMM m1 m2 m3 = pinM m1,pinM m2,pinM m3
+    let freeM (pA: PinnedArray2<'a>) = pA.Free()
+    let freeV (pA: 'a PinnedArray) = pA.Free()
+    let freeA (pA: 'a PinnedArray) = pA.Free()
+    let freeMV ((pA: PinnedArray2<'a>),(pB : 'a PinnedArray)) = pA.Free(); pB.Free()
+    let freeVV ((pA: 'a PinnedArray),(pB : 'a PinnedArray)) = pA.Free(); pB.Free()
+    let freeAA ((pA: 'a PinnedArray),(pB : 'a PinnedArray)) = pA.Free(); pB.Free()
+    let freeMM ((pA: PinnedArray2<'a>),(pB: PinnedArray2<'a>)) = pA.Free();pB.Free()
+    let freeMMM ((pA: PinnedArray2<'a>),(pB: PinnedArray2<'a>),(pC: PinnedArray2<'a>)) = pA.Free();pB.Free();pC.Free()
+    let freeMVV ((pA: PinnedArray2<'a>),(pB: 'a PinnedArray),(pC: 'a PinnedArray)) = pA.Free();pB.Free();pC.Free()
+
+
+//----------------------------------------------------------------------------
+/// Tutorial Part 5. Higher level-place bindings that operate mutatively over the F#
+/// Matrix type by first pinning the data structures.  Be careful with these operations,
+/// as they will write some results into your input matrices.
+///
+
+module MutableMatrixRoutines = 
+
+    open NativeUtilities
+
+    /// C <- A * B
+    let mulMM (A:matrix) (B:matrix) (C:matrix) = 
+        let (pA,pB,pC) as ptrs = pinMMM A B C
+        try PrimitiveCMatrixBindings.DoubleMatrixMultiply 1.0 pA.NativeArray pB.NativeArray 0.0 pC.NativeArray
+        finally
+            freeMMM ptrs
+
+    /// C <- A * V
+    let mulMV (A:matrix) (B:vector) (C:vector) = 
+        let pA,pB,pC as pin = pinMVV A B C
+        try PrimitiveCMatrixBindings.DoubleMatrixVectorMultiply 1.0 pA.NativeArray pB.NativeArray 0.0 pC.NativeArray
+        finally
+            freeMVV pin
+
+    /// B <- A \ B
+    let solve (A : matrix) (B: vector) (ipiv: int[]) = 
+        let pA = pinM A
+        let pB = pinV B
+        let pPivots = pinA ipiv
+        try 
+          PrimitiveBindings.DoublePLUDecomposition pA.NativeArray.NativeTranspose pPivots.NativeArray;
+          PrimitiveCMatrixBindings.DoubleSolveAfterPLUDecomposition pA.NativeArray (nativeArray_as_FortranMatrix_colvec pB.NativeArray) pPivots.NativeArray
+        finally
+            freeM pA; freeV pB; freeA pPivots
+
+    let computeEigenValues (A : matrix) (WR: double[]) (WI:double[]) (workspace:double[])  = 
+        let pA = pinM A
+        let pWR,pWI as pWRI = pinAA WR WI
+        let pWorkspace = pinA workspace
+        try 
+          PrimitiveCMatrixBindings.DoubleComputeEigenValues pA.NativeArray pWR.NativeArray pWI.NativeArray pWorkspace.NativeArray 
+        finally
+            freeM pA; freeVV pWRI; freeA pWorkspace
+            
+    let computeEigenValuesAndVectors (A : matrix) (WR: double[]) (WI:double[]) (VR: matrix) (workspace:double[])  = 
+        let pA,pVR as pMM = pinMM A VR
+        let pWR,pWI as pWRI = pinAA WR WI
+        let pWorkspace = pinA workspace
+        try 
+          PrimitiveCMatrixBindings.DoubleComputeEigenValuesAndVectors pA.NativeArray pWR.NativeArray pWI.NativeArray pVR.NativeArray.NativeTranspose pWorkspace.NativeArray 
+        finally
+            freeMM pMM; freeVV pWRI; freeA pWorkspace
+            
+
+//----------------------------------------------------------------------------
+// Tutorial Part 6. Higher level bindings that defensively copy their input
+//
+
+module ImmutableMatrixRoutines = 
+
+    open NativeUtilities
+
+    /// Compute A * B
+    let mulMM (A:matrix) (B:matrix) = 
+        let C = Matrix.zero A.NumRows B.NumCols
+        // C <- A * B
+        MutableMatrixRoutines.mulMM A B C;
+        C
+
+    /// Compute A * v
+    let mulMV (A:matrix) (v:vector) = 
+        let C = Vector.zero A.NumRows
+        // C <- A * v
+        MutableMatrixRoutines.mulMV A v C;
+        C
+
+    /// Compute A \ v
+    let solve (A : matrix) (v: vector) = 
+        Debug.Assert(A.NumRows = A.NumCols);
+        let A = Matrix.copy A // workspace (yuck) 
+        let vX = Vector.copy v 
+        let ipiv = Array.zeroCreate A.NumCols 
+        // vX <- A \ v
+        MutableMatrixRoutines.solve A vX ipiv;
+        vX
+
+    (* The underlying LAPACK routine raises an error when trying to estimate the workspace. *)
+    (* Hence I've removed this from the sample just for now. *)
+    
+(*
+    let computeEigenValuesWorkspace (A : matrix)   = 
+        let pA = pinM A
+        try 
+          PrimitiveCMatrixBindings.DoubleComputeEigenValuesWorkspace pA.NativeArray 
+        finally
+            freeM pA
+*)
+            
+    let computeEigenValues (A : matrix)  = 
+        let At = A.Transpose
+        let n = At.NumRows
+        let WR = Array.zeroCreate n
+        let WI = Array.zeroCreate n
+        let workspace = Array.zeroCreate (5 * n (* computeEigenValuesWorkspace At *) ) 
+        MutableMatrixRoutines.computeEigenValues At WR WI workspace;
+        let W = Vector.Generic.init n (fun i -> Complex.mkPolar (WR.[i],WI.[i])) 
+        W
+             
+    let computeEigenValuesAndVectors (A : matrix)  = 
+        let At = A.Transpose
+        let n = At.NumRows
+        let WR = Array.zeroCreate n
+        let WI = Array.zeroCreate n
+        let VR = Matrix.zero n n
+        let workspace = Array.zeroCreate (5 * n (* computeEigenValuesAndVectorsWorkspace A *) ) 
+        MutableMatrixRoutines.computeEigenValuesAndVectors At WR WI VR workspace;
+        let W = Vector.Generic.init n (fun i -> Complex.mkPolar (WR.[i],WI.[i])) 
+        W,VR.Transpose
+
+//----------------------------------------------------------------------------
+// Tutorial Part 7. Reusing primitive bindings on other similarly shapped data structures
+//
+// Here we show that the same NativeArray/CMatrix/FortranMatrix primitive bindings can be used
+// with other data structures where the underlying bits are ultimately stored as shape double[] and double[,],
+// e.g. they can be used directly on arrays, or even on memory allocated C.
+
+module MutableArrayRoutines = 
+    open NativeUtilities
+    let pinA2 arr2 = PinnedArray2.of_array2D(arr2)
+    let pinA2AA m1 v2 m3 = pinA2 m1,pinA v2,pinA m3
+    let freeA2A2A2 ((pA: PinnedArray2<'a>),(pB: PinnedArray2<'a>),(pC: PinnedArray2<'a>)) = pA.Free();pB.Free();pC.Free()
+    let freeA2AA ((pA: PinnedArray2<'a>),(pB: 'a PinnedArray),(pC: 'a PinnedArray)) = pA.Free();pB.Free();pC.Free()
+    let pinA2A2A2 m1 m2 m3 = pinA2 m1,pinA2 m2,pinA2 m3
+    let freeA2 (pA: PinnedArray2<'a>) = pA.Free()
+
+    let mulMM (A: double[,]) (B: double[,]) (C: double[,]) = 
+        let (pA,pB,pC) as ptrs = pinA2A2A2 A B C
+        try PrimitiveCMatrixBindings.DoubleMatrixMultiply 1.0 pA.NativeArray pB.NativeArray 0.0 pC.NativeArray
+        finally
+            freeMMM ptrs
+
+    let mulMV (A: double[,]) (B: double[]) (C: double[]) = 
+        let pA,pB,pC as pin = pinA2AA A B C
+        try PrimitiveCMatrixBindings.DoubleMatrixVectorMultiply 1.0 pA.NativeArray pB.NativeArray 0.0 pC.NativeArray
+        finally
+            freeA2AA pin
+    
+    let solve (A : double[,]) (B: double[]) (ipiv: int[]) = 
+        let pA = pinA2 A
+        let pB = pinA B
+        let pPivots = pinA ipiv
+        try 
+          PrimitiveBindings.DoublePLUDecomposition pA.NativeArray.NativeTranspose pPivots.NativeArray;
+          PrimitiveCMatrixBindings.DoubleSolveAfterPLUDecomposition pA.NativeArray (nativeArray_as_FortranMatrix_colvec pB.NativeArray) pPivots.NativeArray
+        finally
+            freeA2 pA; freeA pB; freeA pPivots
+    
+module ImmutableArrayRoutines = 
+    let mulMM (A:double[,]) (B:double[,]) = 
+        let C = Array2D.zeroCreate (Array2D.length1 A) (Array2D.length2 B)
+        MutableArrayRoutines.mulMM A B C;
+        C
+
+    let mulMV (A:double[,]) (B:double[]) = 
+        let C = Array.zeroCreate (Array2D.length1 A)
+        MutableArrayRoutines.mulMV A B C;
+        C
+    let solve (A : double[,]) (B: double[]) = 
+        Debug.Assert(Array2D.length1 A = Array2D.length2 A);
+        let A = Array2D.init (Array2D.length1 A) (Array2D.length2 A) (fun i j ->  A.[i,j]) 
+        let BX = Array.copy B 
+        let ipiv = Array.zeroCreate (Array2D.length1 A)
+        MutableArrayRoutines.solve A BX ipiv;
+        BX
+
+[<TestFixture>]
+type public NativeArrayTests() =
+  
+    [<Test>]
+    member this.BasicTests1() = 
+
+
+          // Ensure you have LAPACK.dll and BLAS.dll the sample directory or elsewhere
+          // on your path. Here we set the current directory so we can find any local copies
+          // of LAPACK.dll and BLAS.dll.
+          System.Environment.CurrentDirectory <- __SOURCE_DIRECTORY__ 
+
+          // Here are some simple matrix values.
+          let onesM = matrix [ [ 1.0; 1.0];  
+                                [1.0; 1.0] ]
+          let onesA = [| 1.0; 1.0 |]
+          let onesV = vector [ 1.0; 1.0]
+          let onesv = matrix [ [ 1.0] ; 
+                               [ 1.0] ]
+          let twosM = matrix [ [ 2.0; 2.0]; 
+                               [ 2.0; 2.0] ]
+          let twosV = vector [ 2.0; 2.0 ]
+          let twosv = matrix [ [ 2.0] ; 
+                               [ 2.0] ]
+          let iM = matrix [ [ 1.0; 0.0]; 
+                            [ 0.0; 1.0] ]
+
+          let miM = matrix [ [ -1.0; 0.0]; 
+                             [  0.0; -1.0] ]
+
+          matrix [ [ 0.0; 0.0]; 
+                   [ 0.0; 0.0] ]  |> ignore
+
+          Matrix.identity 2  |> ignore
+
+          Matrix.identity 10  |> ignore
+
+          let A = 1
+
+          let show x = printf "%s\n" (sprintf "%A" x)
+          printf " ------------------------\n" 
+
+          let J  = matrix [ [ 2.0; 3.0]; 
+                            [ 4.0; 5.0] ]
+          let J2 = matrix [ [ 2.0; 3.0;4.0]; 
+                            [ 2.0; 3.0;5.0]; 
+                            [ 4.0; 5.0;6.0] ]
+
+          // MATALB notation is M \ v, i.e. solve Mx=v for vector x.  Solving Mx=v
+          // The notation we use here is M $ v
+          let ( $ ) (M : matrix) v = ImmutableMatrixRoutines.solve M v
+          let ( *. ) A B = ImmutableMatrixRoutines.mulMM A B
+          let ( *%. ) A v = ImmutableMatrixRoutines.mulMV A v
+
+          let Random = Matrix.create 200 200 1.0 |> Matrix.randomize
+          let RandomV = Matrix.create 200 1 1.0 |> Matrix.toVector
+
+          let time s f =
+            let sw = new System.Diagnostics.Stopwatch() 
+            sw.Start();
+            let res = f()
+            printf "%s, time: %d\n" s sw.ElapsedMilliseconds;
+            ()
+            
+            
+          time "Random * Random" (fun () -> Random * Random )
+          time "Random *. Random" (fun () -> Random *. Random )
+          time "Random $ Random" (fun () -> Random $ RandomV )
+          time "Random $ Random, check with *" (fun () -> Vector.sum (Random * (Random $ RandomV) - RandomV) |> show )
+          time "Random $ Random, check with *%." (fun () -> Vector.sum (Random *%. (Random $ RandomV) - RandomV) |> show )
+
+          time "computeEigenValues Random" (fun () -> ImmutableMatrixRoutines.computeEigenValues Random)
+
+          ImmutableMatrixRoutines.computeEigenValues (Matrix.identity 2) |> ignore
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (Matrix.identity 2) |> ignore
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (matrix [ [ 3.0 ] ]) |> ignore
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (matrix [ [ 3.0; 0.0 ]; [ 0.0; 3.0] ]) |> ignore
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (matrix [ [ 1.0; 0.0 ]; [ 0.0; -1.0] ]) |> ignore
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (matrix [ [ -1.0; 0.0 ]; [ 0.0; -1.0] ]) |> ignore
+
+          let trans = ref (fun (t:float) -> Matrix.identity 2)
+          let points = ref [ (0.0, 0.0); (1.0,0.0); (1.0,1.0); (0.0,1.0); (0.0,0.0) ]
+
+          let f = new System.Windows.Forms.Form()
+          let paint (e:System.Windows.Forms.PaintEventArgs) = 
+              let t = (System.DateTime.Now.Ticks |> Int64.to_float) / 10000000.0
+              let trans = (!trans) t
+              let of_vec (v:vector) = new Point(f.Width/2 + int (v.[0]*100.0), f.Height/2  - int (v.[1]*100.0)) 
+              let origin = vector [0.0; 0.0]
+              let to_vec (x,y) = vector [x;y]
+              let draw_vec pen v1 v2 = e.Graphics.DrawLine(pen,of_vec v1,of_vec v2);
+              let draw (p1,p2) = draw_vec Pens.Aqua (trans * to_vec p1) (trans * to_vec p2);
+              let es,E = ImmutableMatrixRoutines.computeEigenValuesAndVectors trans.Transpose
+              draw_vec Pens.Red origin (E.Column 0 * es.[0].r)
+              draw_vec Pens.Red origin (E.Column 1 * es.[1].r)
+              !points |> List.fold (fun acc p1 -> match acc with None -> Some p1 | Some p0 -> draw (p0,p1); Some p1) None |> ignore;
+              f.Invalidate()
+          let scaleM n k = Matrix.initDiagonal (Vector.create n k)
+          trans := (fun t -> scaleM 2 (sin t)); f.Invalidate()
+          let rotateM th = matrix [ [ cos th; -sin th ]; [ sin th; cos th ] ]
+          let pi = System.Math.PI
+          trans := (fun t -> rotateM (pi * t)); f.Invalidate()
+          trans := (fun t -> matrix [ [ sin t; 1.0]; [cos (t/1.3); 1.0] ])
+
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (rotateM 0.23)  |> ignore
+          let M = matrix [ [ 0.5; 1.0]; [0.0; 1.0] ]
+          trans := (fun _ -> M)
+          let es,EM = ImmutableMatrixRoutines.computeEigenValuesAndVectors M.Transpose
+
+          let e0 = es.[1]
+          assert(e0.i = 0.0) 
+          M.Transpose * EM.Column 0  |> ignore
+          M.Transpose * EM.Column 1 * (1.0/es.[1].r)  |> ignore
+          let disp x = sprintf "%A" x
+
+
+          printf " ------------------------\n" 
+          printf " %s $ %s = %s\n" (disp J) (disp onesV) (disp (J $ onesV))
+          printf " ------------------------\n" 
+          onesV  |> show
+          printf " ------------------------\n" 
+          J * (J $ vector [1.0;1.0])  |> show
+          printf " ------------------------\n" 
+          J2 * (J2 $ vector [1.0;2.0;3.0])  |> show
+          printf " ------------------------\n" 
+          printf " DONE\n" 
+
+
diff --git a/src/FSharp.PowerPack.Unittests/PermutationTests.fs b/src/FSharp.PowerPack.Unittests/PermutationTests.fs
new file mode 100755
index 0000000..177f168
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/PermutationTests.fs
@@ -0,0 +1,44 @@
+namespace FSharp.PowerPack.Unittests
+
+open Microsoft.FSharp.Math
+open NUnit.Framework
+
+#nowarn "40"
+
+[<TestFixture>]
+type public PermutationTests() =
+    [<Test>]
+    member this.BasicTests() = 
+        let p2 = Permutation.ofArray [| 0;2;1;3 |]
+        do test "cwnewr91" (p2 0 = 0)
+        do test "cwnewr92" (p2 1 = 2)
+        do test "cwnewr93" (p2 2 = 1)
+        do test "cwnewr94" (p2 3 = 3)
+        let p3 = p2 >> p2
+        do test "cwnewr95" (p3 0 = 0)
+        do test "cwnewr96" (p3 1 = 1)
+        do test "cwnewr97" (p3 2 = 2)
+        do test "cwnewr98" (p3 3 = 3)
+        let p4 = Permutation.rotation 4 1
+        do test "cwnewr99" (p4 0 = 1)
+        do test "cwnewr9a" (p4 1 = 2)
+        do test "cwnewr9s" (p4 2 = 3)
+        do test "cwnewr9d" (p4 3 = 0)
+        let p5 = Permutation.rotation 4 -1
+        do test "cwnewr9f" (p5 0 = 3)
+        do test "cwnewr9g" (p5 1 = 0)
+        do test "cwnewr9h" (p5 2 = 1)
+        do test "cwnewr9j" (p5 3 = 2)
+        let p6 = Permutation.swap 2 3
+        do test "cwnewr9k" (p6 0 = 0)
+        do test "cwnewr9l" (p6 1 = 1)
+        do test "cwnewr9z" (p6 2 = 3)
+        do test "cwnewr9x" (p6 3 = 2)
+
+        do test "cwcoinwcq" (Array.permute (Permutation.rotation 4 1) [| 0;1;2;3 |] = [| 3;0;1;2 |])
+        do test "cwcoinwcw" (Array.permute (Permutation.swap 1 2) [| 0;1;2;3 |] = [| 0;2;1;3 |])
+        do test "cwcoinwce" (try let _ = Permutation.ofArray [| 0;0 |] in false with :? System.ArgumentException -> true)
+        do test "cwcoinwcr" (try let _ = Permutation.ofArray [| 1;1 |] in false with :? System.ArgumentException -> true)
+        do test "cwcoinwct" (try let _ = Permutation.ofArray [| 1;3 |] in false with :? System.ArgumentException -> true)
+        ()
+
diff --git a/src/FSharp.PowerPack.Unittests/QueryTests.fs b/src/FSharp.PowerPack.Unittests/QueryTests.fs
new file mode 100755
index 0000000..af29d37
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/QueryTests.fs
@@ -0,0 +1,418 @@
+// Copyright (c) Microsoft Corporation 2005-2007.
+// This sample code is provided "as is" without warranty of any kind. 
+// We disclaim all warranties, either express or implied, including the 
+// warranties of merchantability and fitness for a particular purpose. 
+//
+
+namespace FSharp.PowerPack.Unittests
+
+open NUnit.Framework
+open System.IO
+open System.Windows.Forms
+open Microsoft.FSharp.Linq
+open Microsoft.FSharp.Linq.Query
+
+[<AutoOpen>]
+module Database = 
+(*
+    let dbPath() = 
+        let dbPath1 = Path.GetFullPath(Path.Combine(Application.StartupPath, @"NORTHWND.MDF"))
+        let dbPath2 = Path.GetFullPath(Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), @"NORTHWND.MDF"))
+        if   System.IO.File.Exists dbPath1 then dbPath1
+        elif System.IO.File.Exists dbPath2 then dbPath2
+        else 
+           System.Windows.Forms.MessageBox.Show("You must install a version of Microsoft SQLServer or SQLServer Express and download the Northwind example database (NORTHWND.MDF) before running the database portions of this sample. You can download NORTHWND.MDF from http://www.codeproject.com/cs/database/InstallingNorthwindAndPub.asp. Place it in either "+dbPath1+" or the FLinq sample directory or your My Documents directory. Then restart this sample.") |> ignore; 
+           dbPath1
+*)
+    let dbPath = __SOURCE_DIRECTORY__ + @"\NORTHWND.MDF"
+    
+    System.IO.File.SetAttributes(dbPath, System.IO.File.GetAttributes dbPath &&& ~~~System.IO.FileAttributes.ReadOnly )
+    //#r "SqlMetal.exe NORTHWND.MDF"
+    //C:\fsharp2\staging>"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SqlMetal.exe" /code:test.cs NORTHWND.MDF
+    //C:\fsharp2\staging>\Windows\Microsoft.NET\Framework\v3.5\csc.exe /target:library test.cs
+            
+    let sqlServerInstance = @".\SQLEXPRESS"
+    //let connString = "AttachDBFileName='" + dbPath() + "';Server='" + sqlServerInstance + "';user instance=true;Integrated Security=SSPI;Connection Timeout=30"
+    let connString = @"AttachDBFileName='" + dbPath + "';Server='" + sqlServerInstance + "';user instance=true;Integrated Security=SSPI;Connection Timeout=30" 
+    //let connString = @"AttachDBFileName='c:\fsharp2\staging\NORTHWND.MDF';Server='" + sqlServerInstance + "';user instance=true;Integrated Security=SSPI;Connection Timeout=30" 
+
+    let db = new NORTHWND(connString)
+
+    do db.Log <- System.Console.Out
+    
+
+[<AutoOpen>]
+module Macros = 
+
+    [<ReflectedDefinition>]
+    let queryCondition (c:Customers) = c.City = "London" 
+            
+    // Check we can use a macro as a subsequence
+    [<ReflectedDefinition>]
+    let subSequence (c:Customers) = seq { for e in db.Employees do if queryCondition  c then yield c }
+
+    // Nullable manipulations
+    [<ReflectedDefinition>]
+    let (=?!) (x : System.Nullable<'a>) (y: 'a) = 
+        x.HasValue && x.Value = y
+
+[<TestFixture>]
+type public LinqToSqlQueryTests() =
+  
+
+    [<Test>]
+    member this.BasicTests1() = 
+
+        check "vesnvew01" (query <@ seq {  for c in db.Customers do if true then yield c.ContactName }  |> Seq.length @>) 91
+        check "vesnvew02" (query <@ seq { for c in db.Customers do if true then yield (c.ContactName,c.Address) } |> Seq.length @>) 91
+        check "vesnvew03" (query <@ seq { for c in db.Customers do yield [c.ContactName] } |> Seq.length @>) 91
+        check "vesnvew04" (query <@ seq { for c in db.Customers do if true then yield [c.ContactName;c.Address] } |> Seq.length @>) 91
+        check "vesnvew05" (query <@ seq { for c in db.Customers do if false then yield c.ContactName } |> Seq.length @>) 0
+        check "vesnvew06" (query <@ seq { for c in db.Customers do if 1 > 2 then yield c.ContactName } |> Seq.length @>) 0
+        check "vesnvew07" (query <@ seq { for c in db.Customers do if 2 > 1 then yield c.ContactName } |> Seq.length @>) 91
+
+        check "vesnvew08" ((query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.take 4 @>  ) |> Seq.length) 4
+        check "vesnvew09" (query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.take 4 |> Seq.length @>  ) 4
+
+        check "vesnvew0q" ((query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.truncate 4 @>  ) |> Seq.length) 4
+        check "vesnvew0w" (query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.truncate 4 |> Seq.length @>  ) 4
+
+        check "vesnvew0e" ((query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.take 4 @>  ) |> Seq.length) 4
+        check "vesnvew0r" (query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.take 4 |> Seq.length @>  ) 4
+
+        check "vesnvew0t" (query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.head @>) "Maria Anders"
+        check "vesnvew0y" (query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.distinct |> Seq.length @>) 91
+        check "vesnvew0u" (query <@ seq { for c in db.Customers do yield c.City } |> Seq.distinct |> Seq.length @>) 69
+        check "vesnvew0i" (query <@ seq { for c in db.Customers do yield c.CustomerID } |> Seq.distinct |> Seq.length @>) 91
+
+        check "vesnvew0o" ((query <@ seq { for c in db.Customers do yield c.Orders.Count }  @>) |> Seq.averageBy float |> int) 9
+        
+        check "vesnvew0p" ((query <@ seq { for c in db.Customers do yield c.Orders.Count }  @>) |> Seq.filter (fun x -> true) |> Seq.length) 91
+        check "vesnvew0a" ((query <@ seq { for c in db.Customers do yield c.Orders.Count }  @>) |> Seq.filter (fun x -> false) |> Seq.length) 0
+        check "vesnvew0s" ((query <@ seq { for c in db.Customers do yield c }  @>) |> Seq.filter (fun x -> x.City = "London") |> Seq.length) 6
+
+    [<Test>]
+    member this.BasicTests2() = 
+        check "vesnvew0d" ((query <@ db.Customers  @>) |> Seq.length) 91
+        check "vesnvew0f" ((query <@ db.Customers |> Seq.filter (fun x -> true) @>) |> Seq.length) 91
+        check "vesnvew0g" ((query <@ seq { for c in db.Customers do yield c.Orders.Count }  @>) |> Seq.filter (fun x -> false) |> Seq.length) 0
+        check "vesnvew0h" ((query <@ seq { for c in db.Customers do yield c }  @>) |> Seq.filter (fun x -> x.City = "London") |> Seq.length) 6
+
+
+        check "vesnvew0j" ((query <@ let f (c:Customers) = c.City = "London" in seq { for c in db.Customers do if f c then yield c }  @>) |> Seq.length) 6
+
+        check "vesnvew0k" ((query <@ seq { for c in db.Customers do if queryCondition  c then yield c }  @>) |> Seq.length) 6
+
+
+        check "vesnvew0l" ((query <@ seq { for c in db.Customers do yield! subSequence c }  @>) |> Seq.length) 54
+
+
+
+        check "vesnvew0z" (query <@ seq { for c in db.Customers do if c.Address.Contains("Jardim das rosas") then yield c.ContactName } |> Seq.length @>) 1
+
+        check "vesnvew0x" (query <@ seq { for c in db.Customers do if c.Address.Length = 17 then yield c.ContactName } |> Seq.length @>) 6
+
+        check "vesnvew0c" (query <@ seq { for c in db.Customers do for e in db.Employees do yield e.LastName } |> Seq.length @>) 819
+
+        check "vesnvew0v" (query <@ seq { for c in db.Customers do for e in db.Employees do if true then yield (e.LastName,c.ContactName) } @> |> Seq.length)  819
+        check "vesnvew0b" (query <@ seq { for c in db.Customers do if true then for e in db.Employees do yield (e.LastName,c.ContactName) } @> |> Seq.length)  819
+        check "vesnvew0n" (query <@ seq { for c in db.Customers do if c.Country.Length = 6 then for e in db.Employees do yield (e.LastName,c.ContactName) } @> |> Seq.length)  288
+
+    [<Test>]
+    member this.EqualityAndComparison() =        
+        let allEmployees = db.Employees |> Seq.toArray        
+        check "terty01"  (query <@ seq { for c in db.Employees do if c.EmployeeID < 0 then yield c  } @> |> Seq.length) 0
+        check "terty01a" (query <@ seq { for c in db.Employees do if c.EmployeeID > 0 then yield c  } @> |> Seq.length) (allEmployees.Length)
+        check "terty01b" (query <@ seq { for c in db.Employees do if c.EmployeeID = 0 then yield c  } @> |> Seq.length) 0
+        check "terty02" (query <@ seq { for c in db.Customers do if c.CompanyName = "Z"  then yield c  } @> |> Seq.length) 0
+        check "terty03" (query <@ seq { for c in db.Employees do if c.EmployeeID <> allEmployees.[0].EmployeeID  then yield c  } @> |> Seq.length) (allEmployees.Length - 1)
+        let jan1of2010 = System.DateTime(2010,1,1)
+        check "terty04" 
+            (query <@ seq { for c in db.Orders do if c.OrderDate.HasValue && c.OrderDate.Value <= jan1of2010  then yield c  } @> |> Seq.length) 
+            (db.Orders |> Seq.filter(fun o -> o.OrderDate.HasValue) |> Seq.length)
+        let jan1of1900 = System.DateTime(1900,1,1)
+        check "terty05" 
+            (query <@ seq { for c in db.Orders do if c.OrderDate.HasValue && c.OrderDate.Value >= jan1of1900  then yield c  } @> |> Seq.length) 
+            (db.Orders |> Seq.filter(fun o -> o.OrderDate.HasValue) |> Seq.length)
+
+
+    [<Test>]
+    member this.BasicTests3() = 
+        check "vesnvew0m" (query <@ seq { for c in db.Customers do 
+                                             for e in db.Employees do 
+                                                 if c.Address.Contains("Jardim") && 
+                                                    c.Address.Contains("rosas") then 
+                                                       yield (e.LastName,c.ContactName) } @> 
+                                   |> Seq.length) 9
+        
+        check "vesnvew0QQ" (query <@ seq { for c in db.Customers do 
+                                           for e in db.Employees do 
+                                            if c.ContactName = e.LastName then 
+                                             yield c.ContactName } @> 
+                                   |> Seq.length) 0
+
+
+        check "vesnvew0WW" (query <@ seq { for p in db.Products do
+                                            for c in db.Categories do
+                                             for s in db.Suppliers  do
+                                              yield c.CategoryName, p.ProductName, s.CompanyName } 
+                                   |> Seq.length @>) 17864
+
+
+    [<Test>]
+    member this.NullableTests1() = 
+
+        check "vesnvew0EE" (query <@ seq { for p in db.Products do
+                                           for c in db.Categories do
+                                            for s in db.Suppliers  do
+                                              if p.CategoryID =?! c.CategoryID &&
+                                                 p.SupplierID =?! s.SupplierID then 
+                                                yield c.CategoryName, p.ProductName, s.CompanyName } 
+                                   |> Seq.length @>) 77
+
+        check "vesnvew0RR" (query <@ seq { for p in db.Products do
+                                             if p.CategoryID =?! 1 then 
+                                                 yield p.ProductName }  |> Seq.length @>) 12
+        
+    [<Test>]
+    member this.BasicTests4() = 
+
+        // By design: Can't use Seq.groupBy
+        check "vrejkner0TT" (try let _ = query <@ Seq.groupBy (fun (p:Products) -> p.CategoryID) db.Products @> in false with _ -> true) true
+
+        check "vrejkner0YY" (try let _ = query <@ db.Products |> Seq.groupBy (fun p -> p.CategoryID) @> in false with _ -> true) true
+
+
+        check "cnewnc081"  (query <@ Query.groupBy
+                                       (fun (c:Customers) -> c.Address.Length) 
+                                       (seq { for c in db.Customers do yield c }) 
+                                    |> Seq.length @> ) 
+                          22
+
+    [<Test>]
+    member this.BasicTests5() = 
+
+        check "cnewnc082"  (query <@ Seq.sortBy
+                                       (fun (c:Customers) -> c.Address.Length) 
+                                       (seq { for c in db.Customers do yield c }) 
+                                    |> Seq.length @> ) 
+                          91
+
+        check "cnewnc083"  (query <@ Seq.sort (seq { for c in db.Customers do yield c.Address.Length }) 
+                                     |> Seq.length @> ) 
+                          91
+
+
+        check "cnewnc083"  (query <@ seq { for c in db.Customers do yield c.Address.Length }
+                                     |> Seq.sort
+                                     |> Seq.length @> ) 
+                          91
+
+        check "cnewnc094"  (query <@ seq { for c in db.Customers do yield c }
+                                    |> Seq.sortBy (fun c -> c.Address.Length)                                    
+                                    |> Seq.length @> ) 
+                          91
+        check "cnewnc094"  (query <@ Seq.length
+                                       (Seq.sortBy (fun (c:Customers) -> c .Address.Length) 
+                                         (seq { for c in db.Customers do yield c })) @> ) 
+                          91
+
+    [<Test>]
+    member this.BasicTests6() = 
+
+        check "cnewnc085"  (query <@ Seq.exists
+                                       (fun (c:Customers) -> c.Address.Length > 10) 
+                                       (seq { for c in db.Customers do yield c }) @> ) 
+                          true
+
+
+        check "cnewnc086"  (query <@ Seq.forall
+                                       (fun (c:Customers) -> c.Address.Length <= 10) 
+                                       (seq { for c in db.Customers do yield c }) @> ) 
+                          false
+
+        check "cnewnc087"  (query <@ Query.join 
+                                       (seq { for e in db.Employees do yield e }) 
+                                       (seq { for c in db.Customers do yield c }) 
+                                       (fun e -> e.Country) 
+                                       (fun c -> c.Country) 
+                                       (fun e c -> (e,c)) 
+                                    |> Seq.length  @> ) 
+                          93
+
+        check "cnewnc088"  (query <@ seq { for e in db.Employees do  
+                                             for c in db.Customers do 
+                                                 if e.Country = c.Country then 
+                                                     yield (e,c) } 
+                                    |> Seq.length  @> ) 
+                      93
+
+
+    [<Test>]
+    member this.BasicTests7() = 
+        check "cnewnc089"  (query <@ Linq.Query.groupJoin 
+                                       (seq { for c in db.Employees do yield c }) 
+                                       (seq { for c in db.Customers do yield c }) 
+                                       (fun e -> e.Country) 
+                                       (fun c -> c.Country) 
+                                       (fun e cs -> (e,Seq.length cs)) 
+                                    |> Seq.length  @> ) 
+                          9
+
+
+
+        check "we09j" 
+              (query <@ seq { let grouping = db.Products |> Linq.Query.groupBy (fun p -> p.CategoryID)
+                              yield! grouping } |> Seq.length   @>) 8
+
+        check "we09j" 
+              (query <@ seq { let grouping = db.Products |> Linq.Query.groupBy (fun p -> p.CategoryID)
+                              for group in grouping  do
+                                  yield group.Key }  |> Seq.length  @>) 8
+
+        check "we09j" 
+              (query <@ seq { let grouping = db.Products |> Linq.Query.groupBy (fun p -> p.CategoryID)
+                              for group in grouping  do
+                                          let lowest = group |> Linq.Query.minBy (fun x -> x.UnitPrice.Value)
+                                          yield lowest } @> |> Seq.sum) 
+              56.6500M
+          
+    [<Test>]
+    member this.BasicTests8() = 
+        check "we09j" 
+              (query <@ seq { let grouping = db.Products |> Linq.Query.groupBy (fun p -> p.CategoryID)
+                              for group in grouping  do
+                                          let lowest = group |> Seq.minBy (fun x -> x.UnitPrice.GetValueOrDefault())
+                                          let res = seq { for p in group do if p.UnitPrice = lowest.UnitPrice then yield p }
+                                          yield group } |> Seq.length @>) 
+              8
+
+        check "we09j" 
+              (query <@ db.Customers |> Seq.length @>)  91
+        check "we09j" 
+              (query <@ db.Orders |> Seq.length @>) 830
+
+        check "we09j" 
+              (((query <@ seq { for c in db.OrderDetails -> c.Discount } |> Seq.sum @> - 121.04f) |> abs) < 0.001f) true
+        check "we09j" 
+              (query <@ seq { for c in db.OrderDetails -> c.Discount } |> Seq.sumBy (fun d -> d + 1.0f) @> >= 2276.0f) true
+
+
+(*
+    check "vesnvew0" (query <@ [ for c in db.Customers do yield c.ContactName ] @>)
+          ["Maria Anders"; "Ana Trujillo"; "Antonio Moreno"; "Thomas Hardy";
+           "Christina Berglund"; "Hanna Moos"; "Frédérique Citeaux"; "Martín Sommer";
+           "Laurence Lebihan"; "Elizabeth Lincoln"; "Victoria Ashworth";
+           "Patricio Simpson"; "Francisco Chang"; "Yang Wang"; "Pedro Afonso";
+           "Elizabeth Brown"; "Sven Ottlieb"; "Janine Labrune"; "Ann Devon";
+           "Roland Mendel"; "Aria Cruz"; "Diego Roel"; "Martine Rancé"; "Maria Larsson";
+           "Peter Franken"; "Carine Schmitt"; "Paolo Accorti"; "Lino Rodriguez";
+           "Eduardo Saavedra"; "José Pedro Freyre"; "André Fonseca"; "Howard Snyder";
+           "Manuel Pereira"; "Mario Pontes"; "Carlos Hernández"; "Yoshi Latimer";
+           "Patricia McKenna"; "Helen Bennett"; "Philip Cramer"; "Daniel Tonini";
+           "Annette Roulet"; "Yoshi Tannamuri"; "John Steel"; "Renate Messner";
+           "Jaime Yorres"; "Carlos González"; "Felipe Izquierdo"; "Fran Wilson";
+           "Giovanni Rovelli"; "Catherine Dewey"; "Jean Fresnière"; "Alexander Feuer";
+           "Simon Crowther"; "Yvonne Moncada"; "Rene Phillips"; "Henriette Pfalzheim";
+           "Marie Bertrand"; "Guillermo Fernández"; "Georg Pipps"; "Isabel de Castro";
+           "Bernardo Batista"; "Lúcia Carvalho"; "Horst Kloss"; "Sergio Gutiérrez";
+           "Paula Wilson"; "Maurizio Moroni"; "Janete Limeira"; "Michael Holz";
+           "Alejandra Camino"; "Jonas Bergulfsen"; "Jose Pavarotti"; "Hari Kumar";
+           "Jytte Petersen"; "Dominique Perrier"; "Art Braunschweiger"; "Pascale Cartrain";
+           "Liz Nixon"; "Liu Wong"; "Karin Josephs"; "Miguel Angel Paolino";
+           "Anabela Domingues"; "Helvetius Nagy"; "Palle Ibsen"; "Mary Saveley";
+           "Paul Henriot"; "Rita Müller"; "Pirkko Koskitalo"; "Paula Parente";
+           "Karl Jablonski"; "Matti Karttunen"; "Zbyszek Piestrzeniewicz"]
+           
+    check "vesnvew0" (query <@ [ for c in db.Customers do yield c.Address ] @>)
+         ["Obere Str. 57"; "Avda. de la Constitución 2222"; "Mataderos  2312";
+         "120 Hanover Sq."; "Berguvsvägen  8"; "Forsterstr. 57"; "24, place Kléber";
+         "C/ Araquil, 67"; "12, rue des Bouchers"; "23 Tsawassen Blvd.";
+         "Fauntleroy Circus"; "Cerrito 333"; "Sierras de Granada 9993"; "Hauptstr. 29";
+         "Av. dos Lusíadas, 23"; "Berkeley Gardens 12  Brewery"; "Walserweg 21";
+         "67, rue des Cinquante Otages"; "35 King George"; "Kirchgasse 6";
+         "Rua Orós, 92"; "C/ Moralzarzal, 86"; "184, chaussée de Tournai";
+         "Åkergatan 24"; "Berliner Platz 43"; "54, rue Royale"; "Via Monte Bianco 34";
+         "Jardim das rosas n. 32"; "Rambla de Cataluña, 23"; "C/ Romero, 33";
+         "Av. Brasil, 442"; "2732 Baker Blvd."; "5ª Ave. Los Palos Grandes";
+         "Rua do Paço, 67"; "Carrera 22 con Ave. Carlos Soublette #8-35";
+         "City Center Plaza 516 Main St."; "8 Johnstown Road";
+         "Garden House Crowther Way"; "Maubelstr. 90"; "67, avenue de l'Europe";
+         "1 rue Alsace-Lorraine"; "1900 Oak St."; "12 Orchestra Terrace"; "Magazinweg 7";
+         "87 Polk St. Suite 5"; "Carrera 52 con Ave. Bolívar #65-98 Llano Largo";
+         "Ave. 5 de Mayo Porlamar"; "89 Chiaroscuro Rd."; "Via Ludovico il Moro 22";
+         "Rue Joseph-Bens 532"; "43 rue St. Laurent"; "Heerstr. 22";
+         "South House 300 Queensbridge"; "Ing. Gustavo Moncada 8585 Piso 20-A";
+         "2743 Bering St."; "Mehrheimerstr. 369"; "265, boulevard Charonne";
+         "Calle Dr. Jorge Cash 321"; "Geislweg 14"; "Estrada da saúde n. 58";
+         "Rua da Panificadora, 12"; "Alameda dos Canàrios, 891"; "Taucherstraße 10";
+         "Av. del Libertador 900"; "2817 Milton Dr."; "Strada Provinciale 124";
+         "Av. Copacabana, 267"; "Grenzacherweg 237"; "Gran Vía, 1";
+         "Erling Skakkes gate 78"; "187 Suffolk Ln."; "90 Wadhurst Rd."; "Vinbæltet 34";
+         "25, rue Lauriston"; "P.O. Box 555"; "Boulevard Tirou, 255";
+         "89 Jefferson Way Suite 2"; "55 Grizzly Peak Rd."; "Luisenstr. 48";
+         "Avda. Azteca 123"; "Av. Inês de Castro, 414"; "722 DaVinci Blvd.";
+         "Smagsloget 45"; "2, rue du Commerce"; "59 rue de l'Abbaye";
+         "Adenauerallee 900"; "Torikatu 38"; "Rua do Mercado, 12";
+         "305 - 14th Ave. S. Suite 3B"; "Keskuskatu 45"; "ul. Filtrowa 68"]    
+    
+    check "vesnvew0" (query <@ [ for c in db.Employees do yield c.LastName ] @>)
+       ["Buchanan"; "Callahan"; "Davolio"; "Dodsworth"; "Fuller"; "King"; "Leverling";"Peacock"; "Suyama"]
+
+    check "vesnvew0" (query <@ [ for c in db.Customers do if true then yield c.ContactName ] @>)
+        ["Maria Anders"; "Ana Trujillo"; "Antonio Moreno"; "Thomas Hardy";
+         "Christina Berglund"; "Hanna Moos"; "Frédérique Citeaux"; "Martín Sommer";
+         "Laurence Lebihan"; "Elizabeth Lincoln"; "Victoria Ashworth";
+         "Patricio Simpson"; "Francisco Chang"; "Yang Wang"; "Pedro Afonso";
+         "Elizabeth Brown"; "Sven Ottlieb"; "Janine Labrune"; "Ann Devon";
+         "Roland Mendel"; "Aria Cruz"; "Diego Roel"; "Martine Rancé"; "Maria Larsson";
+         "Peter Franken"; "Carine Schmitt"; "Paolo Accorti"; "Lino Rodriguez";
+         "Eduardo Saavedra"; "José Pedro Freyre"; "André Fonseca"; "Howard Snyder";
+         "Manuel Pereira"; "Mario Pontes"; "Carlos Hernández"; "Yoshi Latimer";
+         "Patricia McKenna"; "Helen Bennett"; "Philip Cramer"; "Daniel Tonini";
+         "Annette Roulet"; "Yoshi Tannamuri"; "John Steel"; "Renate Messner";
+         "Jaime Yorres"; "Carlos González"; "Felipe Izquierdo"; "Fran Wilson";
+         "Giovanni Rovelli"; "Catherine Dewey"; "Jean Fresnière"; "Alexander Feuer";
+         "Simon Crowther"; "Yvonne Moncada"; "Rene Phillips"; "Henriette Pfalzheim";
+         "Marie Bertrand"; "Guillermo Fernández"; "Georg Pipps"; "Isabel de Castro";
+         "Bernardo Batista"; "Lúcia Carvalho"; "Horst Kloss"; "Sergio Gutiérrez";
+         "Paula Wilson"; "Maurizio Moroni"; "Janete Limeira"; "Michael Holz";
+         "Alejandra Camino"; "Jonas Bergulfsen"; "Jose Pavarotti"; "Hari Kumar";
+         "Jytte Petersen"; "Dominique Perrier"; "Art Braunschweiger"; "Pascale Cartrain";
+         "Liz Nixon"; "Liu Wong"; "Karin Josephs"; "Miguel Angel Paolino";
+         "Anabela Domingues"; "Helvetius Nagy"; "Palle Ibsen"; "Mary Saveley";
+         "Paul Henriot"; "Rita Müller"; "Pirkko Koskitalo"; "Paula Parente";
+         "Karl Jablonski"; "Matti Karttunen"; "Zbyszek Piestrzeniewicz"]    
+*)
+
+module LocalType =
+    open System.Linq
+    type Foo() =                
+        let source = [1;2;3;4;5] |> Queryable.AsQueryable
+     
+        let bar() =     
+            <@ seq { for x in source -> x + 1 } @>
+     
+        let bar2() = <@ source @>
+        member this.Bar() = bar()
+
+        member this.Bar2() = bar2()
+
+    [<TestFixture>]
+    type Test4060() =
+        [<Test>]
+        member this.TestLocalField0() =
+            try 
+                (new Foo()).Bar2() |> query |> ignore
+            with
+            | :? System.NotSupportedException -> ()
+            |   _ -> Assert.Fail("Should detect and report this case")
+
+
+        [<Test>]
+        member this.TestLocalField() =
+            try 
+                (new Foo()).Bar() |> query |> ignore
+            with
+            | :? System.NotSupportedException -> ()
+            |   _ -> Assert.Fail("Should detect and report this case")
diff --git a/src/FSharp.PowerPack.Unittests/QuotationEvalTests.fs b/src/FSharp.PowerPack.Unittests/QuotationEvalTests.fs
new file mode 100755
index 0000000..74df260
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/QuotationEvalTests.fs
@@ -0,0 +1,1473 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Linq.QuotationEvaluation
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Quotations.Patterns
+open Microsoft.FSharp.Quotations.DerivedPatterns
+open Microsoft.FSharp.Quotations.ExprShape
+
+open Microsoft.FSharp.Linq.QuotationEvaluation
+open Microsoft.FSharp.Linq.Query
+
+#nowarn "40"
+#nowarn "57"
+#nowarn "67" // This type test or downcast will always hold
+#nowarn "1204"
+
+    
+[<Measure>] type kg
+[<Measure>] type m
+[<Measure>] type s
+[<Measure>] type sqrm = m ^ 2
+type area = float<m ^ 2>
+
+
+[<AutoOpen>]
+module Extensions = 
+    type System.Object with 
+        member x.ExtensionMethod0()  = 3
+        member x.ExtensionMethod1()  = ()
+        member x.ExtensionMethod2(y:int)  = y
+        member x.ExtensionMethod3(y:int)  = ()
+        member x.ExtensionMethod4(y:int,z:int)  = y + z
+        member x.ExtensionMethod5(y:(int*int))  = y 
+        member x.ExtensionProperty1 = 3
+        member x.ExtensionProperty2 with get() = 3
+        member x.ExtensionProperty3 with set(v:int) = ()
+        member x.ExtensionIndexer1 with get(idx:int) = idx
+        member x.ExtensionIndexer2 with set(idx:int) (v:int) = ()
+
+    type System.Int32 with 
+        member x.Int32ExtensionMethod0()  = 3
+        member x.Int32ExtensionMethod1()  = ()
+        member x.Int32ExtensionMethod2(y:int)  = y
+        member x.Int32ExtensionMethod3(y:int)  = ()
+        member x.Int32ExtensionMethod4(y:int,z:int)  = y + z
+        member x.Int32ExtensionMethod5(y:(int*int))  = y 
+        member x.Int32ExtensionProperty1 = 3
+        member x.Int32ExtensionProperty2 with get() = 3
+        member x.Int32ExtensionProperty3 with set(v:int) = ()
+        member x.Int32ExtensionIndexer1 with get(idx:int) = idx
+        member x.Int32ExtensionIndexer2 with set(idx:int) (v:int) = ()
+
+[<AutoOpen>]
+module ModuleDefinitions = 
+    let eval (q: Expr<_>) = 
+        q.ToLinqExpression() |> ignore 
+        q.Compile() |> ignore  
+        q.Eval()
+
+    let x22<[<Measure>] 'a>() = <@ typeof<float<'a>> @> |> eval
+
+    // The following hopefully is an identity function on quotations:
+    let transformIdentity (x: Expr<'T>) : Expr<'T> = 
+        let rec conv x = 
+            match x with
+            | ShapeVar _ -> 
+                x
+            | ShapeLambda (head, body) -> 
+                Expr.Lambda (head, conv body)    
+            | ShapeCombination (head, tail) -> 
+                RebuildShapeCombination (head, List.map conv tail)
+        conv x |> Expr.Cast
+
+    let checkEval nm (q : Expr<'T>) expected = 
+        check nm (eval q) expected
+        check (nm + "(after applying transformIdentity)") (eval (transformIdentity q)) expected
+        check (nm + "(after applying transformIdentity^2)")  (eval (transformIdentity (transformIdentity q))) expected
+
+    let raise x = Operators.raise x
+
+type Customer = { mutable Name:string; Data: int }
+type CustomerG<'a> = { mutable Name:string; Data: 'a }
+exception E0
+exception E1 of string
+type C0() = 
+    member x.P = 1
+type C1(s:string) = 
+    member x.P = s
+
+type Union10 = 
+   | Case1 of string 
+   | Case2
+
+type Union1 = 
+   | Case1 of string 
+
+type Union11 = 
+   | Case1 of string 
+   | Case2 of string
+
+type Union1111 = 
+   | Case1 of string 
+   | Case2 of string
+   | Case3 of string
+   | Dog2 of string
+   | Dog3 of string
+   | Dog4 of string
+   | Dog5 of string
+   | Dog6 of string
+   | Dog7 of string
+   | Dog8 of string
+   | Dog9 of string
+   | DogQ of string
+   | DogW of string
+   | DogE of string
+   | DogR of string
+   | DogT of string
+   | DogY of string
+   | DogU of string
+   | DogI of string
+
+type GUnion10<'a> = Case1 of 'a | Case2
+
+type PointRecord = { field1 : int; field2 : int }
+
+[<TestFixture>]
+type public QuotationEvalTests() =
+  
+    [<Test>]
+    member this.FloatTests() = 
+
+     // set up bindings
+     let x1 = <@ 2.0<kg> + 4.0<kg> @> |> eval
+     let x2 = <@ 2.0<s> - 4.0<s> @> |> eval
+     let x3 = <@ 2.0<m> / 4.0<s> @> |> eval
+     let x3a = <@ 2.0<m> / 4.0<m> @> |> eval
+     let x3b = <@ 1.0 / 4.0<s> @> |> eval
+     let x3c = <@ 1.0<m> / 4.0 @> |> eval
+     let x4 = <@ 2.0<m> * 4.0<s> @> |> eval
+     let x4a = <@ 2.0<m> * 4.0<m> @> |> eval
+     let x4b = <@ 2.0 * 4.0<m> @> |> eval
+     let x4c = <@ 2.0<m> * 4.0 @> |> eval
+     let x5 = <@ 5.0<m> % 3.0<m> @> |> eval
+     let x6 = <@ - (2.0<m>) @> |> eval
+     let x7 = <@ abs (-2.0<m>) @> |> eval
+     let x8 = <@ sqrt (4.0<sqrm>) @> |> eval
+     let x9 = <@ [ 1.0<m> .. 1.0<m> .. 4.0<m> ] @> |> eval
+     let x10 = <@ sign (3.0<m/s>) @> |> eval
+     let x11 = <@ atan2 4.4<s^3> 5.4<s^3> @> |> eval
+     let x11a : float<1> = <@ acos 4.4<1>  @> |> eval
+     let x11b : float<1> = <@ asin 4.4<1>  @> |> eval
+     let x11c : float<1> = <@ atan 4.4<1>  @> |> eval
+     let x11d : float<1> = <@ ceil 4.4<1>  @> |> eval
+     let x11e : float<1> = <@ cos 4.4<1>  @> |> eval
+     let x11f : float<1> = <@ cosh 4.4<1>  @> |> eval
+     let x11g : float<1> = <@ exp 4.4<1>  @> |> eval
+     let x11h : float<1> = <@ floor 4.4<1>  @> |> eval
+     let x11i : float<1> = <@ log 4.4<1>  @> |> eval
+     let x11j : float<1> = <@ log10 4.4<1>  @> |> eval
+     let x11k : float<1> = <@ 4.4<1> ** 3.0<1> @> |> eval
+     //let x11l : float<1> = <@ pown 4.4<1> 3 @> |> eval
+     let x11m : float<1> = <@ round 4.4<1>  @> |> eval
+     let x11n : int = <@ sign 4.4<1>  @> |> eval
+     let x11o : float<1> = <@ sin 4.4<1>  @> |> eval
+     let x11p : float<1> = <@ sinh 4.4<1>  @> |> eval
+     let x11q : float<1> = <@ sqrt 4.4<1>  @> |> eval
+     let x11r : float<1> = <@ tan 4.4<1>  @> |> eval
+     let x11s : float<1> = <@ tanh 4.4<1>  @> |> eval
+     let x12 = <@ Seq.sum [2.0<sqrm>; 3.0<m^2>] @> |> eval
+     let x12a = <@ Seq.sumBy (fun x -> x*x) [(2.0<sqrm> : area); 3.0<m^2>] @> |> eval
+     let x13 = <@ (Seq.average [2.0<sqrm>; 3.0<m^2>]) : area @> |> eval
+     let x13a = <@ Seq.averageBy (fun x -> x*x) [2.0<m^2/m>; 3.0<m>] @> |> eval
+     let x14 = <@ x13 + x13a @> |> eval
+     let x15 = <@ 5.0<m> < 3.0<m> @> |> eval
+     let x16 = <@ 5.0<m> <= 3.0<m> @> |> eval
+     let x17 = <@ 5.0<m> > 3.0<m> @> |> eval
+     let x18 = <@ 5.0<m> >= 3.0<m> @> |> eval
+     let x19 = <@ max 5.0<m> 3.0<m> @> |> eval
+     let x20 = <@ min 5.0<m> 3.0<m> @> |> eval
+     let x21 = <@ typeof<float<m>> @> |> eval
+
+     // check the types and values!
+     test "x1" (x1 = 6.0<kg>)
+     test "x2" (x2 = -2.0<s>)
+     test "x3" (x3 = 0.5<m/s>)
+     test "x3a" (x3a = 0.5)
+     test "x3b" (x3b = 0.25<1/s>)
+     test "x3c" (x3c = 0.25<m>)
+     test "x4" (x4 = 8.0<m s>)
+     test "x4a" (x4a = 8.0<m^2>)
+     test "x4b" (x4b = 8.0<m>)
+     test "x4c" (x4c = 8.0<m>)
+     test "x5" (x5 = 2.0<m>)
+     test "x6" (x6 = -2.0<m>)
+     test "x7" (x7 = 2.0<m>)
+     test "x8" (x8 = 2.0<m>)
+     test "x9" (x9 = [1.0<m>; 2.0<m>; 3.0<m>; 4.0<m>])
+     test "x10" (x10 = 1)
+     test "x12" (x12 = 5.0<m^2>)
+     test "x12a" (x12a = 13.0<m^4>)
+     test "x13" (x13 = 2.5<m^2>)
+     test "x13a" (x13a = 6.5<m^2>)
+     test "x14" (x14 = 9.0<m^2>)
+     test "x15" (x15 = false)
+     test "x16" (x16 = false)
+     test "x17" (x17 = true)
+     test "x18" (x18 = true)
+     test "x19" (x19 = 5.0<m>)
+     test "x20" (x20 = 3.0<m>)
+     test "x21" (x21 = typeof<float>)
+     test "x22" (x22<m>() = typeof<float>)
+      
+
+    [<Test>]
+    member this.Float32Tests() = 
+
+     let y1 = <@ 2.0f<kg> + 4.0f<kg>  @> |> eval
+     let y2 = <@ 2.0f<s> - 4.0f<s>  @> |> eval
+     let y3 = <@ 2.0f<m> / 4.0f<s>  @> |> eval
+     let y3a = <@ 2.0f<m> / 4.0f<m>  @> |> eval
+     let y3b = <@ 1.0f / 4.0f<s>  @> |> eval
+     let y3c = <@ 1.0f<m> / 4.0f  @> |> eval
+     let y4 = <@ 2.0f<m> * 4.0f<s>  @> |> eval
+     let y4a = <@ 2.0f<m> * 4.0f<m>  @> |> eval
+     let y4b = <@ 2.0f * 4.0f<m>  @> |> eval
+     let y4c = <@ 2.0f<m> * 4.0f  @> |> eval
+     let y5 = <@ 5.0f<m> % 3.0f<m>  @> |> eval
+     let y6 = <@ - (2.0f<m>)  @> |> eval
+     let y7 = <@ abs (2.0f<m>)  @> |> eval
+     let y8 = <@ sqrt (4.0f<sqrm>)  @> |> eval
+     let y9 = <@ [ 1.0f<m> .. 1.0f<m> .. 4.0f<m> ]  @> |> eval
+     let y10 = <@ sign (3.0f<m/s>)  @> |> eval
+     let y11 = <@ atan2 4.4f<s^3> 5.4f<s^3>  @> |> eval
+     let x11a : float32<1> = <@ acos 4.4f<1>   @> |> eval
+     let x11b : float32<1> = <@ asin 4.4f<1>   @> |> eval
+     let x11c : float32<1> = <@ atan 4.4f<1>   @> |> eval
+     let x11d : float32<1> = <@ ceil 4.4f<1>   @> |> eval
+     let x11e : float32<1> = <@ cos 4.4f<1>   @> |> eval
+     let x11f : float32<1> = <@ cosh 4.4f<1>   @> |> eval
+     let x11g : float32<1> = <@ exp 4.4f<1>   @> |> eval
+     let x11h : float32<1> = <@ floor 4.4f<1>   @> |> eval
+     let x11i : float32<1> = <@ log 4.4f<1>   @> |> eval
+     let x11j : float32<1> = <@ log10 4.4f<1>   @> |> eval
+     let x11k : float32<1> = <@ 4.4f<1> ** 3.0f<1>  @> |> eval
+     //let x11l : float32<1> = <@ pown 4.4f<1> 3  @> |> eval
+     let x11m : float32<1> = <@ round 4.4f<1>   @> |> eval
+     let x11n : int = <@ sign 4.4f<1>   @> |> eval
+     let x11o : float32<1> = <@ sin 4.4f<1>   @> |> eval
+     let x11p : float32<1> = <@ sinh 4.4f<1>   @> |> eval
+     let x11q : float32<1> = <@ sqrt 4.4f<1>   @> |> eval
+     let x11r : float32<1> = <@ tan 4.4f<1>   @> |> eval
+     let x11s : float32<1> = <@ tanh 4.4f<1>   @> |> eval
+     let y12 = <@ Seq.sum [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+     let y12a = <@ Seq.sumBy (fun y -> y*y) [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+     let y13 = <@ Seq.average [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+     let y13a = <@ Seq.averageBy (fun y -> y*y) [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+
+     // check the types and values!
+     test "y1" (y1 = 6.0f<kg>)
+     test "y2" (y2 = -2.0f<s>)
+     test "y3" (y3 = 0.5f<m/s>)
+     test "y3a" (y3a = 0.5f)
+     test "y3b" (y3b = 0.25f<1/s>)
+     test "y3c" (y3c = 0.25f<m>)
+     test "y4" (y4 = 8.0f<m s>)
+     test "y4a" (y4a = 8.0f<m^2>)
+     test "y4b" (y4b = 8.0f<m>)
+     test "y4c" (y4c = 8.0f<m>)
+     test "y5" (y5 = 2.0f<m>)
+     test "y6" (y6 = -2.0f<m>)
+     test "y7" (y7 = 2.0f<m>)
+     test "y8" (y8 = 2.0f<m>)
+     test "y9" (y9 = [1.0f<m>; 2.0f<m>; 3.0f<m>; 4.0f<m>])
+     test "y10" (y10 = 1)
+     test "y12" (y12 = 5.0f<m^2>)
+     test "y12a" (y12a = 13.0f<m^4>)
+     test "y13" (y13 = 2.5f<m^2>)
+     test "y13a" (y13a = 6.5f<m^4>)
+      
+
+    [<Test>]
+    member this.DecimalTests() = 
+
+     let z1 = <@ 2.0M<kg> + 4.0M<kg>  @> |> eval
+     let z2 = <@ 2.0M<s> - 4.0M<s>  @> |> eval
+     let z3 = <@ 2.0M<m> / 4.0M<s>  @> |> eval
+     let z3a = <@ 2.0M<m> / 4.0M<m>  @> |> eval
+     let z3b = <@ 1.0M / 4.0M<s>  @> |> eval
+     let z3c = <@ 1.0M<m> / 4.0M  @> |> eval
+     let z4 = <@ 2.0M<m> * 4.0M<s>  @> |> eval
+     let z4a = <@ 2.0M<m> * 4.0M<m>  @> |> eval
+     let z4b = <@ 2.0M * 4.0M<m>  @> |> eval
+     let z4c = <@ 2.0M<m> * 4.0M  @> |> eval
+     let z5 = <@ 5.0M<m> % 3.0M<m>  @> |> eval
+     let z6 = <@ - (2.0M<m>)  @> |> eval
+     let z7 = <@ abs (2.0M<m>)  @> |> eval
+    // let z9 = <@ [ 1.0M<m> .. 4.0M<m> ]
+     let z10 = <@ sign (3.0M<m/s>)  @> |> eval
+
+     let x1d : decimal = <@ ceil 4.4M   @> |> eval
+     let x1h : decimal = <@ floor 4.4M   @> |> eval
+     //let x1l : decimal = <@ pown 4.4M 3  @> |> eval
+#if FX_NO_DEFAULT_DECIMAL_ROUND
+#else
+     let x1m : decimal = <@ round 4.4M   @> |> eval
+#endif
+     let x1n : int = <@ sign 4.4M   @> |> eval
+
+     //let x11d : decimal<1> = <@ ceil 4.4M<1> 
+     //let x11h : decimal<1> = <@ floor 4.4M<1> 
+     //let x11m : decimal<1> = <@ round 4.4M<1> 
+     //let x11l : decimal<1> = <@ pown 4.4M<1> 3  @> |> eval
+     let x11n : int = <@ sign 4.4M<1>   @> |> eval
+
+     //let z12 = <@ Seq.sum [2.0M<sqrm>; 3.0M<m^2>]  @> |> eval
+     //let z12a = <@ Seq.sumBy (fun z -> z*z) [2.0M<sqrm>; 3.0M<m^2>]  @> |> eval
+     //let z13 = <@ Seq.average [2.0M<sqrm>; 3.0M<m^2>]  @> |> eval
+     //let z13a = <@ Seq.averageBy (fun z -> z*z) [2.0M<sqrm>; 3.0M<m^2>]  @> |> eval
+
+
+     // check the types and values!
+     test "z1" (z1 = 6.0M<kg>)
+     test "z2" (z2 = -2.0M<s>)
+     test "z3" (z3 = 0.5M<m/s>)
+     test "z3a" (z3a = 0.5M)
+     test "z3b" (z3b = 0.25M<1/s>)
+     test "z3c" (z3c = 0.25M<m>)
+     test "z4" (z4 = 8.0M<m s>)
+     test "z4a" (z4a = 8.0M<m^2>)
+     test "z4b" (z4b = 8.0M<m>)
+     test "z4c" (z4c = 8.0M<m>)
+     test "z5" (z5 = 2.0M<m>)
+     test "z6" (z6 = -2.0M<m>)
+     test "z7" (z7 = 2.0M<m>)
+     test "z10" (z10 = 1)
+     //test "z12" (z12 = 5.0M<m^2>)
+     //test "z12a" (z12a = 13.0M<m^4>)
+     //test "z13" (z13 = 2.5M<m^2>)
+     //test "z13a" (z13a = 6.5M<m^4>)
+
+
+
+    [<Test>]
+    member this.EvaluationTests() = 
+
+        let f () = () 
+
+        checkEval "cwe90wecmp" (<@ f ()  @> ) ()
+
+        checkEval "vlwjvrwe90" (<@ let f (x:int) (y:int) = x + y in f 1 2  @>) 3
+
+        //debug <- true
+
+
+        checkEval "slnvrwe90" (<@ let rec f (x:int) : int = f x in 1  @>) 1
+
+        checkEval "2ver9ewva" (<@ let rec f1 (x:int) : int = f2 x 
+                                  and f2 x = f1 x 
+                                  1  @>) 1
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 x 
+              and f2 x = f3 x 
+              and f3 x = f1 x 
+              1  @>) 
+          1
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = fend (x-1) 
+              and fend x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = f4 (x-1) 
+              and f4 x = fend (x-1) 
+              and fend x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = f4 (x-1) 
+              and f4 x = f5 (x-1) 
+              and f5 x = fend (x-1) 
+              and fend x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = f4 (x-1) 
+              and f4 x = f5 (x-1) 
+              and f5 x = f6 (x-1) 
+              and f6 x = fend (x-1) 
+              and fend x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = f4 (x-1) 
+              and f4 x = f5 (x-1) 
+              and f5 x = f6 (x-1) 
+              and f6 x = f7 (x-1) 
+              and f7 x = fend (x-1) 
+              and fend x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+
+
+        checkEval "2ver9ewv1" (<@ let rec f (x:int) : int = x+x in f 2  @>) 4
+
+        eval <@ let rec fib x = if x <= 2 then 1 else fib (x-1) + fib (x-2) in fib 36 @> |> ignore 
+        //(let rec fib x = if x <= 2 then 1 else fib (x-1) + fib (x-2) in fib 36)
+
+        //2.53/0.35
+
+        checkEval "2ver9ewv2" (<@ if true then 1 else 0  @>) 1
+        checkEval "2ver9ewv3" (<@ if false then 1 else 0  @>) 0
+        checkEval "2ver9ewv4" (<@ true && true @>) true
+        checkEval "2ver9ewv5" (<@ true && false @>) false
+        check "2ver9ewv6" (try eval <@ failwith "fail" : int @> with Failure "fail" -> 1 | _ -> 0) 1 
+        check "2ver9ewv7" (try eval <@ true && (failwith "fail") @> with Failure "fail" -> true | _ -> false) true
+        checkEval "2ver9ewv8" (<@ 0x001 &&& 0x100 @>) (0x001 &&& 0x100)
+        checkEval "2ver9ewv9" (<@ 0x001 ||| 0x100 @>) (0x001 ||| 0x100)
+        checkEval "2ver9ewvq" (<@ 0x011 ^^^ 0x110 @>) (0x011 ^^^ 0x110)
+        checkEval "2ver9ewvw" (<@ ~~~0x011 @>) (~~~0x011)
+
+        let _ = 1
+        checkEval "2ver9ewve" (<@ () @>) ()
+        check "2ver9ewvr" (eval <@ (fun x -> x + 1) @> (3)) 4
+        check "2ver9ewvt" (eval <@ (fun (x,y) -> x + 1) @> (3,4)) 4
+        check "2ver9ewvy" (eval <@ (fun (x1,x2,x3) -> x1 + x2 + x3) @> (3,4,5)) (3+4+5)
+        check "2ver9ewvu" (eval <@ (fun (x1,x2,x3,x4) -> x1 + x2 + x3 + x4) @> (3,4,5,6)) (3+4+5+6)
+        check "2ver9ewvi" (eval <@ (fun (x1,x2,x3,x4,x5) -> x1 + x2 + x3 + x4 + x5) @> (3,4,5,6,7)) (3+4+5+6+7)
+        check "2ver9ewvo" (eval <@ (fun (x1,x2,x3,x4,x5,x6) -> x1 + x2 + x3 + x4 + x5 + x6) @> (3,4,5,6,7,8)) (3+4+5+6+7+8)
+        check "2ver9ewvp" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7) -> x1 + x2 + x3 + x4 + x5 + x6 + x7) @> (3,4,5,6,7,8,9)) (3+4+5+6+7+8+9)
+        check "2ver9ewva" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7,x8) -> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8) @> (3,4,5,6,7,8,9,10)) (3+4+5+6+7+8+9+10)
+        check "2ver9ewvs" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7,x8,x9) -> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9) @> (3,4,5,6,7,8,9,10,11)) (3+4+5+6+7+8+9+10+11)
+        check "2ver9ewvd" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) -> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10) @> (3,4,5,6,7,8,9,10,11,12)) (3+4+5+6+7+8+9+10+11+12)
+        check "2ver9ewvf" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11) -> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11) @> (3,4,5,6,7,8,9,10,11,12,13)) (3+4+5+6+7+8+9+10+11+12+13)
+        check "2ver9ewvg" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12) -> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12) @> (3,4,5,6,7,8,9,10,11,12,13,14)) (3+4+5+6+7+8+9+10+11+12+13+14)
+
+        checkEval "2ver9ewvh" (<@ while false do ()  @>) ()
+        checkEval "2ver9ewvj" (<@ let rec f (x:int) : int = f x in 1  @>) 1
+
+        checkEval "2ver9ewvk" (<@ 1 + 1 @>) 2
+        checkEval "2ver9ewvl" (<@ 1 > 1 @>) false
+        checkEval "2ver9ewvz" (<@ 1 < 1 @>) false
+        checkEval "2ver9ewvx" (<@ 1 <= 1 @>) true
+        checkEval "2ver9ewvc" (<@ 1 >= 1 @>) true
+        eval <@ System.DateTime.Now @> |> ignore
+        checkEval "2ver9ewvv" (<@ System.Int32.MaxValue @>) System.Int32.MaxValue  // literal field!
+        checkEval "2ver9ewvb" (<@ None  : int option @>) None
+        checkEval "2ver9ewvn" (<@ Some(1)  @>) (Some(1))
+        checkEval "2ver9ewvm" (<@ [] : int list @>) []
+        checkEval "2ver9ewqq" (<@ [1] @>) [1]
+        checkEval "2ver9ewqq" (<@ ["1"] @>) ["1"]
+        checkEval "2ver9ewqq" (<@ ["1";"2"] @>) ["1";"2"]
+        check "2ver9ewww" (eval <@ (fun x -> x + 1) @> 3) 4
+
+        let v = (1,2)
+        checkEval "2ver9ewer" (<@ v @>) (1,2)
+        checkEval "2ver9ewet" (<@ let x = 1 in x @>) 1
+        checkEval "2ver9ewed" (<@ let x = 1+1 in x+x @>) 4
+        let x = ref 0
+        let incrx () = incr x
+
+        checkEval "2ver9ewvec" (<@ !x @>) 0
+        checkEval "2ver9ewev" (<@ incrx() @>) ()
+        checkEval "2ver9eweb" (<@ !x @>) 3  // NOTE: checkEval evaluates the quotation three times :-)
+        checkEval "2ver9ewen" (<@ while !x < 10 do incrx() @>) ()
+        checkEval "2ver9ewem" (<@ !x @>) 10
+
+        check "2ver9ewveq" (try eval <@ raise (new System.Exception("hello")) : bool @> with :? System.Exception -> true | _ -> false) true
+
+        
+        check "2ver9ewrf" (let v2 = (3,4) in eval <@ v2 @>) (3,4)
+        
+        check "2ver9ewrg" (let v2 = (3,4) in eval <@ v2,v2 @>) ((3,4),(3,4))
+
+        checkEval "2ver9ewrt" (<@ (1,2) @>) (1,2)
+        checkEval "2ver9ewvk" (<@ (1,2,3) @>) (1,2,3)
+        checkEval "2ver9ewrh" (<@ (1,2,3,4) @>) (1,2,3,4)
+        checkEval "2ver9ewrj" (<@ (1,2,3,4,5) @>) (1,2,3,4,5)
+        checkEval "2ver9ewrk" (<@ (1,2,3,4,5,6) @>) (1,2,3,4,5,6)
+        checkEval "2ver9ewrl" (<@ (1,2,3,4,5,6,7) @>) (1,2,3,4,5,6,7)
+        checkEval "2ver9ewra" (<@ (1,2,3,4,5,6,7,8) @>) (1,2,3,4,5,6,7,8)
+        checkEval "2ver9ewrs" (<@ (1,2,3,4,5,6,7,8,9) @>) (1,2,3,4,5,6,7,8,9)
+        checkEval "2ver9ewrx" (<@ (1,2,3,4,5,6,7,8,9,10) @>) (1,2,3,4,5,6,7,8,9,10)
+        checkEval "2ver9ewrc" (<@ (1,2,3,4,5,6,7,8,9,10,11) @>) (1,2,3,4,5,6,7,8,9,10,11)
+        checkEval "2ver9ewrv" (<@ (1,2,3,4,5,6,7,8,9,10,11,12) @>) (1,2,3,4,5,6,7,8,9,10,11,12)
+        checkEval "2ver9ewrb" (<@ System.DateTime.Now.DayOfWeek @>) System.DateTime.Now.DayOfWeek
+        checkEval "2ver9ewrn" (<@ Checked.(+) 1 1 @>) 2
+        checkEval "2ver9ewrm" (<@ Checked.(-) 1 1 @>) 0
+        checkEval "2ver9ewrw" (<@ Checked.( * ) 1 1 @>) 1
+        // TODO (let) : let v2 = (3,4) in eval <@ match v2 with (x,y) -> x + y @>
+        // TODO: eval <@ "1" = "2" @>
+
+    [<Test>]
+    member this.NonGenericRecdTests() = 
+        let c1 = { Name="Don"; Data=6 }
+        let c2 = { Name="Peter"; Data=7 }
+        let c3 = { Name="Freddy"; Data=8 }
+        checkEval "2ver9e1rw1" (<@ c1.Name @>) "Don"
+        checkEval "2ver9e2rw2" (<@ c2.Name @>) "Peter"
+        checkEval "2ver9e3rw3" (<@ c2.Data @>) 7
+        checkEval "2ver9e7rw4" (<@ { Name = "Don"; Data = 6 } @>) { Name="Don"; Data=6 }
+        checkEval "2ver9e7rw5" (<@ { Name = "Don"; Data = 6 } @>) { Name="Don"; Data=6 }
+
+    [<Test>]
+    member this.GenericRecdTests() = 
+        let c1 : CustomerG<int> = { Name="Don"; Data=6 }
+        let c2 : CustomerG<int> = { Name="Peter"; Data=7 }
+        let c3 : CustomerG<string> = { Name="Freddy"; Data="8" }
+        checkEval "2ver9e4rw6" (<@ c1.Name @>) "Don"
+        checkEval "2ver9e5rw7" (<@ c2.Name @>) "Peter"
+        checkEval "2ver9e6rw8" (<@ c2.Data @>) 7
+        checkEval "2ver9e7rw9" (<@ c3.Data @>) "8"
+        checkEval "2ver9e7rwQ" (<@ { Name = "Don"; Data = 6 } @>) { Name="Don"; Data=6 }
+        checkEval "2ver9e7rwW" (<@ c1.Name <- "Ali Baba" @>) ()
+        checkEval "2ver9e7rwE" (<@ c1.Name  @>) "Ali Baba"
+
+    [<Test>]
+    member this.ArrayTests() = 
+        checkEval "2ver9e8rwR1" (<@ [| |]  @>) ([| |] : int array)
+        checkEval "2ver9e8rwR2" (<@ [| 0 |]  @>) ([| 0 |] : int array)
+        checkEval "2ver9e8rwR3" (<@ [| 0  |].[0]  @>) 0
+        checkEval "2ver9e8rwR4" (<@ [| 1; 2  |].[0]  @>) 1
+        checkEval "2ver9e8rwR5" (<@ [| 1; 2  |].[1]  @>) 2
+
+    [<Test>]
+    member this.Array2DTests() = 
+        checkEval "2ver9e8rwR6" (<@ (Array2D.init 3 4 (fun i j -> i + j)).[0,0] @>) 0
+        checkEval "2ver9e8rwR7" (<@ (Array2D.init 3 4 (fun i j -> i + j)).[1,2] @>) 3
+        checkEval "2ver9e8rwR8" (<@ (Array2D.init 3 4 (fun i j -> i + j)) |> Array2D.base1 @>) 0
+        checkEval "2ver9e8rwR9" (<@ (Array2D.init 3 4 (fun i j -> i + j)) |> Array2D.base2 @>) 0
+        checkEval "2ver9e8rwRQ" (<@ (Array2D.init 3 4 (fun i j -> i + j)) |> Array2D.length1 @>) 3
+        checkEval "2ver9e8rwRW" (<@ (Array2D.init 3 4 (fun i j -> i + j)) |> Array2D.length2 @>) 4
+
+
+    [<Test>]
+    member this.Array3DTests() = 
+        checkEval "2ver9e8rwRE" (<@ (Array3D.init 3 4 5 (fun i j k -> i + j)).[0,0,0] @>) 0
+        checkEval "2ver9e8rwRR" (<@ (Array3D.init 3 4 5 (fun i j k -> i + j + k)).[1,2,3] @>) 6
+        checkEval "2ver9e8rwRT" (<@ (Array3D.init 3 4 5 (fun i j k -> i + j)) |> Array3D.length1 @>) 3
+        checkEval "2ver9e8rwRY" (<@ (Array3D.init 3 4 5 (fun i j k -> i + j)) |> Array3D.length2 @>) 4
+        checkEval "2ver9e8rwRU" (<@ (Array3D.init 3 4 5 (fun i j k -> i + j)) |> Array3D.length3 @>) 5
+
+    [<Test>]
+    member this.ExceptionTests() = 
+        let c1 = E0
+        let c2 = E1 "1"
+        let c3 = E1 "2"
+        checkEval "2ver9e8rwR" (<@ E0  @>) E0
+        checkEval "2ver9e8rwT" (<@ E1 "1"  @>) (E1 "1")
+        checkEval "2ver9eQrwY" (<@ match c1 with E0 -> 1 | _ -> 2  @>) 1
+        checkEval "2ver9eQrwU" (<@ match c2 with E0 -> 1 | _ -> 2  @>) 2
+        checkEval "2ver9eQrwI" (<@ match c2 with E0 -> 1 | E1 _  -> 2 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwO" (<@ match c2 with E1 _  -> 2 | E0 -> 1 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwP" (<@ match c2 with E1 "1"  -> 2 | E0 -> 1 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwA" (<@ match c2 with E1 "2"  -> 2 | E0 -> 1 | _ -> 3  @>) 3
+        checkEval "2ver9eQrwS" (<@ match c3 with E1 "2"  -> 2 | E0 -> 1 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwD1" (<@ try failwith "" with _ -> 2  @>) 2
+        checkEval "2ver9eQrwD2" (<@ let x = ref 0 in 
+                                    try 
+                                           try failwith "" 
+                                           finally incr x 
+                                    with _ -> !x @>) 1
+        checkEval "2ver9eQrwD3" (<@ let x = ref 0 in 
+                                    (try incr x; incr x
+                                     finally incr x )
+                                    x.Value @>) 3
+        checkEval "2ver9eQrwD4" (<@ try 3 finally () @>) 3
+        checkEval "2ver9eQrwD5" (<@ try () finally () @>) ()
+        checkEval "2ver9eQrwD6" (<@ try () with _ -> () @>) ()
+        checkEval "2ver9eQrwD7" (<@ try raise E0 with E0 -> 2  @>) 2
+        checkEval "2ver9eQrwF" (<@ try raise c1 with E0 -> 2  @>) 2
+        checkEval "2ver9eQrwG" (<@ try raise c2 with E0 -> 2 | E1 "1" -> 3 @>) 3
+        checkEval "2ver9eQrwH" (<@ try raise c2 with E1 "1" -> 3 | E0 -> 2  @>) 3
+
+    [<Test>]
+    member this.TypeTests() = 
+        let c1 = C0()
+        let c2 = C1 "1"
+        let c3 = C1 "2"
+        checkEval "2ver9e8rwJ" (<@ C0().P  @>) 1
+        checkEval "2ver9e8rwK" (<@ C1("1").P  @>)  "1"
+        checkEval "2ver9eQrwL" (<@ match box c1 with :? C0 -> 1 | _ -> 2  @>) 1
+        checkEval "2ver9eQrwZ" (<@ match box c2 with :? C0 -> 1 | _ -> 2  @>) 2
+        checkEval "2ver9eQrwX" (<@ match box c2 with :? C0 -> 1 | :? C1   -> 2 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwC" (<@ match box c2 with :? C1   -> 2 | :? C0 -> 1 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwV" (<@ match box c2 with :? C1  -> 2 | :? C0 -> 1 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwN" (<@ match box c3 with :? C1  as c1 when c1.P = "2"  -> 2 | :? C0 -> 1 | _ -> 3  @>) 2
+
+    [<Test>]
+    member this.NonGenericUnionTests0() = 
+        let c1 = Union10.Case1 "meow"
+        let c2 = Union10.Case2
+        checkEval "2ver9e8rw11" (<@ Union10.Case1 "sss" @>) (Union10.Case1 "sss")
+        checkEval "2ver9e9rw12" (<@ Union10.Case2 @>) Union10.Case2
+        checkEval "2ver9eQrw13" (<@ match c1 with Union10.Case1 _ -> 2 | Union10.Case2 -> 1 @>) 2
+        checkEval "2ver9eWrw14" (<@ match c1 with Union10.Case1 s -> s | Union10.Case2 -> "woof" @>) "meow"
+        checkEval "2ver9eErw15" (<@ match c2 with Union10.Case1 s -> s | Union10.Case2 -> "woof" @>) "woof"
+
+    [<Test>]
+    member this.NonGenericUnionTests1() = 
+        let c1 = Union1.Case1 "meow"
+        checkEval "2ver9e8rw16" (<@ Union1.Case1 "sss" @>) (Union1.Case1 "sss")
+        checkEval "2ver9eQrw17" (<@ match c1 with Union1.Case1 _ -> 2  @>) 2
+        checkEval "2ver9eWrw18" (<@ match c1 with Union1.Case1 s -> s  @>) "meow"
+
+    [<Test>]
+    member this.NonGenericUnionTests2() = 
+        let c1 = Union11.Case1 "meow"
+        let c2 = Union11.Case2 "woof"
+        checkEval "2ver9e8rw19" (<@ Union11.Case1 "sss" @>) (Union11.Case1 "sss")
+        checkEval "2ver9e9rw20" (<@ Union11.Case2 "bowwow" @>) (Union11.Case2 "bowwow")
+        checkEval "2ver9eQrw21" (<@ match c1 with Union11.Case1 _ -> 2 | Union11.Case2  _ -> 1 @>) 2
+        checkEval "2ver9eWrw22" (<@ match c1 with Union11.Case1 s -> s | Union11.Case2 s -> s @>) "meow"
+        checkEval "2ver9eErw23" (<@ match c2 with Union11.Case1 s -> s | Union11.Case2 s -> s @>) "woof"
+
+    [<Test>]
+    member this.NonGenericUnionTests3() = 
+        let c1 = Union1111.Case1 "meow"
+        let c2 = Union1111.Case2 "woof"
+        checkEval "2ver9e8rw24" (<@ Union1111.Case1 "sss" @>) (Union1111.Case1 "sss")
+        checkEval "2ver9e9rw25" (<@ Union1111.Case2 "bowwow" @>) (Union1111.Case2 "bowwow")
+        checkEval "2ver9eQrw26" (<@ match c1 with Union1111.Case1 _ -> 2 | _ -> 1 @>) 2
+        checkEval "2ver9eWrw27" (<@ match c1 with Union1111.Case1 s -> s | _ -> "woof" @>) "meow"
+        checkEval "2ver9eErw28" (<@ match c2 with Union1111.Case1 s -> s | Union1111.Case2 s -> s | _ -> "bark" @>) "woof"
+
+
+    [<Test>]
+    member this.GenericUnionTests() = 
+        let c1 = GUnion10.Case1 "meow"
+        let c2 = GUnion10<string>.Case2
+        checkEval "2ver9e8rw29" (<@ GUnion10.Case1 "sss" @>) (GUnion10.Case1 "sss")
+        checkEval "2ver9e9rw30" (<@ GUnion10.Case2 @>) GUnion10.Case2
+        checkEval "2ver9eQrw31" (<@ match c1 with GUnion10.Case1 _ -> 2 | GUnion10.Case2 -> 1 @>) 2
+        checkEval "2ver9eWrw32" (<@ match c1 with GUnion10.Case1 s -> s | GUnion10.Case2 -> "woof" @>) "meow"
+        checkEval "2ver9eErw33" (<@ match c2 with GUnion10.Case1 s -> s | GUnion10.Case2 -> "woof" @>) "woof"
+
+    [<Test>]
+    member this.InlinedOperationsStillDynamicallyAvailableTests() = 
+
+        checkEval "vroievr093" (<@ LanguagePrimitives.GenericZero<sbyte> @>)  0y
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<int16> @>)  0s
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<int32> @>)  0
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<int64> @>)  0L
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<nativeint> @>)  0n
+        checkEval "vroievr093" (<@ LanguagePrimitives.GenericZero<byte> @>)  0uy
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<uint16> @>)  0us
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<uint32> @>)  0u
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<uint64> @>)  0UL
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<unativeint> @>)  0un
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<float> @>)  0.0
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<float32> @>)  0.0f
+        checkEval "vroievr092" (<@ LanguagePrimitives.GenericZero<decimal> @>)  0M
+
+
+
+        checkEval "vroievr093" (<@ LanguagePrimitives.GenericOne<sbyte> @>)  1y
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<int16> @>)  1s
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<int32> @>)  1
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<int64> @>)  1L
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<nativeint> @>)  1n
+        checkEval "vroievr193" (<@ LanguagePrimitives.GenericOne<byte> @>)  1uy
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<uint16> @>)  1us
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<uint32> @>)  1u
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<uint64> @>)  1UL
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<unativeint> @>)  1un
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<float> @>)  1.0
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<float32> @>)  1.0f
+        checkEval "vroievr192" (<@ LanguagePrimitives.GenericOne<decimal> @>)  1M
+
+        check "vroievr0971" (LanguagePrimitives.AdditionDynamic 3y 4y) 7y
+        check "vroievr0972" (LanguagePrimitives.AdditionDynamic 3s 4s) 7s
+        check "vroievr0973" (LanguagePrimitives.AdditionDynamic 3 4) 7
+        check "vroievr0974" (LanguagePrimitives.AdditionDynamic 3L 4L) 7L
+        check "vroievr0975" (LanguagePrimitives.AdditionDynamic 3n 4n) 7n
+        check "vroievr0976" (LanguagePrimitives.AdditionDynamic 3uy 4uy) 7uy
+        check "vroievr0977" (LanguagePrimitives.AdditionDynamic 3us 4us) 7us
+        check "vroievr0978" (LanguagePrimitives.AdditionDynamic 3u 4u) 7u
+        check "vroievr0979" (LanguagePrimitives.AdditionDynamic 3UL 4UL) 7UL
+        check "vroievr0970" (LanguagePrimitives.AdditionDynamic 3un 4un) 7un
+        check "vroievr097q" (LanguagePrimitives.AdditionDynamic 3.0 4.0) 7.0
+        check "vroievr097w" (LanguagePrimitives.AdditionDynamic 3.0f 4.0f) 7.0f
+        check "vroievr097e" (LanguagePrimitives.AdditionDynamic 3.0M 4.0M) 7.0M
+
+        check "vroievr097r" (LanguagePrimitives.CheckedAdditionDynamic 3y 4y) 7y
+        check "vroievr097t" (LanguagePrimitives.CheckedAdditionDynamic 3s 4s) 7s
+        check "vroievr097y" (LanguagePrimitives.CheckedAdditionDynamic 3 4) 7
+        check "vroievr097u" (LanguagePrimitives.CheckedAdditionDynamic 3L 4L) 7L
+        check "vroievr097i" (LanguagePrimitives.CheckedAdditionDynamic 3n 4n) 7n
+        check "vroievr097o" (LanguagePrimitives.CheckedAdditionDynamic 3uy 4uy) 7uy
+        check "vroievr097p" (LanguagePrimitives.CheckedAdditionDynamic 3us 4us) 7us
+        check "vroievr097a" (LanguagePrimitives.CheckedAdditionDynamic 3u 4u) 7u
+        check "vroievr097s" (LanguagePrimitives.CheckedAdditionDynamic 3UL 4UL) 7UL
+        check "vroievr097d" (LanguagePrimitives.CheckedAdditionDynamic 3un 4un) 7un
+        check "vroievr097f" (LanguagePrimitives.CheckedAdditionDynamic 3.0 4.0) 7.0
+        check "vroievr097g" (LanguagePrimitives.CheckedAdditionDynamic 3.0f 4.0f) 7.0f
+        check "vroievr097h" (LanguagePrimitives.CheckedAdditionDynamic 3.0M 4.0M) 7.0M
+
+        check "vroievr0912q" (LanguagePrimitives.MultiplyDynamic 3y 4y) 12y
+        check "vroievr0912w" (LanguagePrimitives.MultiplyDynamic 3s 4s) 12s
+        check "vroievr0912e" (LanguagePrimitives.MultiplyDynamic 3 4) 12
+        check "vroievr0912r" (LanguagePrimitives.MultiplyDynamic 3L 4L) 12L
+        check "vroievr0912t" (LanguagePrimitives.MultiplyDynamic 3n 4n) 12n
+        check "vroievr0912y" (LanguagePrimitives.MultiplyDynamic 3uy 4uy) 12uy
+        check "vroievr0912u" (LanguagePrimitives.MultiplyDynamic 3us 4us) 12us
+        check "vroievr0912i" (LanguagePrimitives.MultiplyDynamic 3u 4u) 12u
+        check "vroievr0912o" (LanguagePrimitives.MultiplyDynamic 3UL 4UL) 12UL
+        check "vroievr0912p" (LanguagePrimitives.MultiplyDynamic 3un 4un) 12un
+        check "vroievr0912a" (LanguagePrimitives.MultiplyDynamic 3.0 4.0) 12.0
+        check "vroievr0912s" (LanguagePrimitives.MultiplyDynamic 3.0f 4.0f) 12.0f
+        check "vroievr0912d" (LanguagePrimitives.MultiplyDynamic 3.0M 4.0M) 12.0M
+
+
+        check "vroievr0912f" (LanguagePrimitives.CheckedMultiplyDynamic 3y 4y) 12y
+        check "vroievr0912g" (LanguagePrimitives.CheckedMultiplyDynamic 3s 4s) 12s
+        check "vroievr0912h" (LanguagePrimitives.CheckedMultiplyDynamic 3 4) 12
+        check "vroievr0912j" (LanguagePrimitives.CheckedMultiplyDynamic 3L 4L) 12L
+        check "vroievr0912k" (LanguagePrimitives.CheckedMultiplyDynamic 3n 4n) 12n
+        check "vroievr0912l" (LanguagePrimitives.CheckedMultiplyDynamic 3uy 4uy) 12uy
+        check "vroievr0912z" (LanguagePrimitives.CheckedMultiplyDynamic 3us 4us) 12us
+        check "vroievr0912x" (LanguagePrimitives.CheckedMultiplyDynamic 3u 4u) 12u
+        check "vroievr0912c" (LanguagePrimitives.CheckedMultiplyDynamic 3UL 4UL) 12UL
+        check "vroievr0912v" (LanguagePrimitives.CheckedMultiplyDynamic 3un 4un) 12un
+        check "vroievr0912b" (LanguagePrimitives.CheckedMultiplyDynamic 3.0 4.0) 12.0
+        check "vroievr0912n" (LanguagePrimitives.CheckedMultiplyDynamic 3.0f 4.0f) 12.0f
+        check "vroievr0912m" (LanguagePrimitives.CheckedMultiplyDynamic 3.0M 4.0M) 12.0M
+
+
+        let iarr = [| 0..1000 |]
+        let ilist = [ 0..1000 ]
+
+        let farr = [| 0.0 .. 1.0 .. 100.0 |]
+        let flist = [ 0.0 .. 1.0 .. 100.0 ]
+
+        Array.average farr |> ignore
+
+        checkEval "vrewoinrv091" (<@ farr.[0] @>) 0.0
+        checkEval "vrewoinrv092" (<@ flist.[0] @>) 0.0
+        checkEval "vrewoinrv093" (<@ iarr.[0] @>) 0
+        checkEval "vrewoinrv094" (<@ ilist.[0] @>) 0
+
+        checkEval "vrewoinrv095" (<@ farr.[0] <- 0.0 @>) ()
+        checkEval "vrewoinrv096" (<@ iarr.[0] <- 0 @>) ()
+
+        checkEval "vrewoinrv097" (<@ farr.[0] <- 1.0 @>) ()
+        checkEval "vrewoinrv098" (<@ iarr.[0] <- 1 @>) ()
+
+        checkEval "vrewoinrv099" (<@ farr.[0] @>) 1.0
+        checkEval "vrewoinrv09q" (<@ iarr.[0] @>) 1
+
+        checkEval "vrewoinrv09w" (<@ farr.[0] <- 0.0 @>) ()
+        checkEval "vrewoinrv09e" (<@ iarr.[0] <- 0 @>) ()
+
+
+        checkEval "vrewoinrv09r" (<@ Array.average farr @>) (Array.average farr)
+        checkEval "vrewoinrv09t" (<@ Array.sum farr @>) (Array.sum farr)
+        checkEval "vrewoinrv09y" (<@ Seq.sum farr @>) (Seq.sum farr)
+        checkEval "vrewoinrv09u" (<@ Seq.average farr @>) (Seq.average farr) 
+        checkEval "vrewoinrv09i" (<@ Seq.average flist @>) (Seq.average flist)
+        checkEval "vrewoinrv09o" (<@ Seq.averageBy (fun x -> x) farr @> ) (Seq.averageBy (fun x -> x) farr )
+        checkEval "vrewoinrv09p" (<@ Seq.averageBy (fun x -> x) flist @>) (Seq.averageBy (fun x -> x) flist )
+        checkEval "vrewoinrv09a" (<@ Seq.averageBy float ilist @>) (Seq.averageBy float ilist)
+        checkEval "vrewoinrv09s" (<@ List.sum flist @>) (List.sum flist)
+        checkEval "vrewoinrv09d" (<@ List.average flist @>) (List.average flist)
+        checkEval "vrewoinrv09f" (<@ List.averageBy float ilist @>) (List.averageBy float ilist)
+
+        checkEval "vrewoinrv09g1" (<@ compare 0 0 = 0 @>) true
+        checkEval "vrewoinrv09g2" (<@ compare 0 1 < 0 @>) true
+        checkEval "vrewoinrv09g3" (<@ compare 1 0 > 0 @>) true
+        checkEval "vrewoinrv09g4" (<@ 0 < 1 @>) true
+        checkEval "vrewoinrv09g5" (<@ 0 <= 1 @>) true
+        checkEval "vrewoinrv09g6" (<@ 1 <= 1 @>) true
+        checkEval "vrewoinrv09g7" (<@ 2 <= 1 @>) false
+        checkEval "vrewoinrv09g8" (<@ 0 > 1 @>) false
+        checkEval "vrewoinrv09g9" (<@ 0 >= 1 @>) false
+        checkEval "vrewoinrv09g0" (<@ 1 >= 1 @>) true
+        checkEval "vrewoinrv09gQ" (<@ 2 >= 1 @>) true
+
+        checkEval "vrewoinrv09gw" (<@ compare 0.0 0.0 = 0 @>) true
+        checkEval "vrewoinrv09ge" (<@ compare 0.0 1.0 < 0 @>) true
+        checkEval "vrewoinrv09gr" (<@ compare 1.0 0.0 > 0 @>) true
+        checkEval "vrewoinrv09gt" (<@ 0.0 < 1.0 @>) true
+        checkEval "vrewoinrv09gy" (<@ 0.0 <= 1.0 @>) true
+        checkEval "vrewoinrv09gu" (<@ 1.0 <= 1.0 @>) true
+        checkEval "vrewoinrv09gi" (<@ 2.0 <= 1.0 @>) false
+        checkEval "vrewoinrv09go" (<@ 0.0 > 1.0 @>) false
+        checkEval "vrewoinrv09gp" (<@ 0.0 >= 1.0 @>) false
+        checkEval "vrewoinrv09ga" (<@ 1.0 >= 1.0 @>) true
+        checkEval "vrewoinrv09gs" (<@ 2.0 >= 1.0 @>) true
+
+        checkEval "vrewoinrv09gd" (<@ compare 0.0f 0.0f = 0 @>) true
+        checkEval "vrewoinrv09gf" (<@ compare 0.0f 1.0f < 0 @>) true
+        checkEval "vrewoinrv09gg" (<@ compare 1.0f 0.0f > 0 @>) true
+        checkEval "vrewoinrv09gh" (<@ 0.0f < 1.0f @>) true
+        checkEval "vrewoinrv09gk" (<@ 0.0f <= 1.0f @>) true
+        checkEval "vrewoinrv09gl" (<@ 1.0f <= 1.0f @>) true
+        checkEval "vrewoinrv09gz" (<@ 2.0f <= 1.0f @>) false
+        checkEval "vrewoinrv09gx" (<@ 0.0f > 1.0f @>) false
+        checkEval "vrewoinrv09gc" (<@ 0.0f >= 1.0f @>) false
+        checkEval "vrewoinrv09gv" (<@ 1.0f >= 1.0f @>) true
+        checkEval "vrewoinrv09gb" (<@ 2.0f >= 1.0f @>) true
+
+        checkEval "vrewoinrv09gn" (<@ compare 0L 0L = 0 @>) true
+        checkEval "vrewoinrv09gm" (<@ compare 0L 1L < 0 @>) true
+        checkEval "vrewoinrv09g11" (<@ compare 1L 0L > 0 @>) true
+        checkEval "vrewoinrv09g12" (<@ 0L < 1L @>) true
+        checkEval "vrewoinrv09g13" (<@ 0L <= 1L @>) true
+        checkEval "vrewoinrv09g14" (<@ 1L <= 1L @>) true
+        checkEval "vrewoinrv09g15" (<@ 2L <= 1L @>) false
+        checkEval "vrewoinrv09g16" (<@ 0L > 1L @>) false
+        checkEval "vrewoinrv09g17" (<@ 0L >= 1L @>) false
+        checkEval "vrewoinrv09g18" (<@ 1L >= 1L @>) true
+        checkEval "vrewoinrv09g19" (<@ 2L >= 1L @>) true
+
+        checkEval "vrewoinrv09g21" (<@ compare 0y 0y = 0 @>) true
+        checkEval "vrewoinrv09g22" (<@ compare 0y 1y < 0 @>) true
+        checkEval "vrewoinrv09g23" (<@ compare 1y 0y > 0 @>) true
+        checkEval "vrewoinrv09g24" (<@ 0y < 1y @>) true
+        checkEval "vrewoinrv09g25" (<@ 0y <= 1y @>) true
+        checkEval "vrewoinrv09g26" (<@ 1y <= 1y @>) true
+        checkEval "vrewoinrv09g27" (<@ 2y <= 1y @>) false
+        checkEval "vrewoinrv09g28" (<@ 0y > 1y @>) false
+        checkEval "vrewoinrv09g29" (<@ 0y >= 1y @>) false
+        checkEval "vrewoinrv09g30" (<@ 1y >= 1y @>) true
+        checkEval "vrewoinrv09g31" (<@ 2y >= 1y @>) true
+
+        checkEval "vrewoinrv09g32" (<@ compare 0M 0M = 0 @>) true
+        checkEval "vrewoinrv09g33" (<@ compare 0M 1M < 0 @>) true
+        checkEval "vrewoinrv09g34" (<@ compare 1M 0M > 0 @>) true
+        checkEval "vrewoinrv09g35" (<@ 0M < 1M @>) true
+        checkEval "vrewoinrv09g36" (<@ 0M <= 1M @>) true
+        checkEval "vrewoinrv09g37" (<@ 1M <= 1M @>) true
+        checkEval "vrewoinrv09g38" (<@ 2M <= 1M @>) false
+        checkEval "vrewoinrv09g39" (<@ 0M > 1M @>) false
+        checkEval "vrewoinrv09g40" (<@ 0M >= 1M @>) false
+        checkEval "vrewoinrv09g41" (<@ 1M >= 1M @>) true
+        checkEval "vrewoinrv09g42" (<@ 2M >= 1M @>) true
+
+        checkEval "vrewoinrv09g43" (<@ compare 0I 0I = 0 @>) true
+        checkEval "vrewoinrv09g44" (<@ compare 0I 1I < 0 @>) true
+        checkEval "vrewoinrv09g45" (<@ compare 1I 0I > 0 @>) true
+        checkEval "vrewoinrv09g46" (<@ 0I < 1I @>) true
+        checkEval "vrewoinrv09g47" (<@ 0I <= 1I @>) true
+        checkEval "vrewoinrv09g48" (<@ 1I <= 1I @>) true
+        checkEval "vrewoinrv09g49" (<@ 2I <= 1I @>) false
+        checkEval "vrewoinrv09g50" (<@ 0I > 1I @>) false
+        checkEval "vrewoinrv09g51" (<@ 0I >= 1I @>) false
+        checkEval "vrewoinrv09g52" (<@ 1I >= 1I @>) true
+        checkEval "vrewoinrv09g53" (<@ 2I >= 1I @>) true
+
+
+        checkEval "vrewoinrv09g" (<@ sin 0.0 @>) (sin 0.0)
+        checkEval "vrewoinrv09h" (<@ sinh 0.0 @>) (sinh 0.0)
+        checkEval "vrewoinrv09j" (<@ cos 0.0 @>) (cos 0.0)
+        checkEval "vrewoinrv09k" (<@ cosh 0.0 @>) (cosh 0.0)
+        checkEval "vrewoinrv09l" (<@ tan 1.0 @>) (tan 1.0)
+        checkEval "vrewoinrv09z" (<@ tanh 1.0 @>) (tanh 1.0)
+        checkEval "vrewoinrv09x" (<@ abs -2.0 @>) (abs -2.0)
+        checkEval "vrewoinrv09c" (<@ ceil 2.0 @>) (ceil 2.0)
+        checkEval "vrewoinrv09v" (<@ sqrt 2.0 @>) (sqrt 2.0)
+        checkEval "vrewoinrv09b" (<@ sign 2.0 @>) (sign 2.0)
+#if FX_NO_TRUNCATE
+#else
+        checkEval "vrewoinrv09n" (<@ truncate 2.3 @>) (truncate 2.3)
+#endif
+        checkEval "vrewoinrv09m" (<@ floor 2.3 @>) (floor 2.3)
+        checkEval "vrewoinrv09Q" (<@ round 2.3 @>) (round 2.3)
+        checkEval "vrewoinrv09W" (<@ log 2.3 @>) (log 2.3)
+        checkEval "vrewoinrv09E" (<@ log10 2.3 @>) (log10 2.3)
+        checkEval "vrewoinrv09R" (<@ exp 2.3 @>) (exp 2.3)
+        checkEval "vrewoinrv09T" (<@ 2.3 ** 2.4 @>) (2.3 ** 2.4)
+
+        checkEval "vrewoinrv09Y" (<@ sin 0.0f @>) (sin 0.0f)
+        checkEval "vrewoinrv09U" (<@ sinh 0.0f @>) (sinh 0.0f)
+        checkEval "vrewoinrv09I" (<@ cos 0.0f @>) (cos 0.0f)
+        checkEval "vrewoinrv09O" (<@ cosh 0.0f @>) (cosh 0.0f)
+        checkEval "vrewoinrv09P" (<@ tan 1.0f @>) (tan 1.0f)
+        checkEval "vrewoinrv09A" (<@ tanh 1.0f @>) (tanh 1.0f)
+        checkEval "vrewoinrv09S" (<@ abs -2.0f @>) (abs -2.0f)
+        checkEval "vrewoinrv09D" (<@ ceil 2.0f @>) (ceil 2.0f)
+        checkEval "vrewoinrv09F" (<@ sqrt 2.0f @>) (sqrt 2.0f)
+        checkEval "vrewoinrv09G" (<@ sign 2.0f @>) (sign 2.0f)
+#if FX_NO_TRUNCATE
+#else
+        checkEval "vrewoinrv09H" (<@ truncate 2.3f @>) (truncate 2.3f)
+#endif
+        checkEval "vrewoinrv09J" (<@ floor 2.3f @>) (floor 2.3f)
+        checkEval "vrewoinrv09K" (<@ round 2.3f @>) (round 2.3f)
+        checkEval "vrewoinrv09L" (<@ log 2.3f @>) (log 2.3f)
+        checkEval "vrewoinrv09Z" (<@ log10 2.3f @>) (log10 2.3f)
+        checkEval "vrewoinrv09X" (<@ exp 2.3f @>) (exp 2.3f)
+        checkEval "vrewoinrv09C" (<@ 2.3f ** 2.4f @>) (2.3f ** 2.4f)
+
+        checkEval "vrewoinrv09V" (<@ ceil 2.0M @>) (ceil 2.0M)
+        checkEval "vrewoinrv09B" (<@ sign 2.0M @>) (sign 2.0M)
+#if FX_NO_TRUNCATE
+#else
+        checkEval "vrewoinrv09N" (<@ truncate 2.3M @>) (truncate 2.3M)
+#endif
+        checkEval "vrewoinrv09M" (<@ floor 2.3M @>) (floor 2.3M)
+
+        checkEval "vrewoinrv09QQ" (<@ sign -2 @>) (sign -2)
+        checkEval "vrewoinrv09WW" (<@ sign -2y @>) (sign -2y)
+        checkEval "vrewoinrv09EE" (<@ sign -2s @>) (sign -2s)
+        checkEval "vrewoinrv09RR" (<@ sign -2L @>) (sign -2L)
+
+        checkEval "vrewoinrv09TT" (<@ [ 0 .. 10 ] @>) [ 0 .. 10 ]
+        checkEval "vrewoinrv09YY" (<@ [ 0y .. 10y ] @>) [ 0y .. 10y ]
+        checkEval "vrewoinrv09UU" (<@ [ 0s .. 10s ] @>) [ 0s .. 10s ]
+        checkEval "vrewoinrv09II" (<@ [ 0L .. 10L ] @>) [ 0L .. 10L ]
+        checkEval "vrewoinrv09OO" (<@ [ 0u .. 10u ] @>) [ 0u .. 10u ]
+        checkEval "vrewoinrv09PP" (<@ [ 0uy .. 10uy ] @>) [ 0uy .. 10uy ]
+        checkEval "vrewoinrv09AA" (<@ [ 0us .. 10us ] @>) [ 0us .. 10us ]
+        checkEval "vrewoinrv09SS" (<@ [ 0UL .. 10UL ] @>) [ 0UL .. 10UL ]
+        
+        // op_Range dynamic disptach
+        checkEval "vrewoinrv09DD" (<@ [ 0N .. 10N ] @>) [ 0N .. 10N ]
+
+#if FX_NO_DEFAULT_DECIMAL_ROUND
+#else        
+        // Round dynamic dispatch on Decimal
+        checkEval "vrewoinrv09FF" (<@ round 2.3M @>) (round 2.3M)
+#endif
+
+        // Measure stuff:
+        checkEval "vrewoinrv09GG" (<@ atan2 3.0 4.0 @>) (atan2 3.0 4.0 )
+        
+        checkEval "vrewoinrv09HH" (<@ 1.0<kg> @>) (1.0<kg>)
+
+        // Measure stuff:
+        checkEval "vrewoinrv09JJ" (<@ 1.0<kg> + 2.0<kg> @>) (3.0<kg>)
+
+
+        eval <@ Array.average [| 0.0 .. 1.0 .. 10000.0 |] @> |> ignore 
+
+    [<Test>]
+    member this.LanguagePrimitiveCastingUnitsOfMeasure() = 
+
+        checkEval "castingunits1" (<@ 2.5 |> LanguagePrimitives.FloatWithMeasure<m> |> float @>) 2.5
+        checkEval "castingunits2" (<@ 2.5f |> LanguagePrimitives.Float32WithMeasure<m> |> float32 @>) 2.5f
+        checkEval "castingunits3" (<@ 2.0m |> LanguagePrimitives.DecimalWithMeasure<m> |> decimal @>) 2.0M
+        checkEval "castingunits4" (<@ 2 |> LanguagePrimitives.Int32WithMeasure<m> |> int @>) 2
+        checkEval "castingunits5" (<@ 2L |> LanguagePrimitives.Int64WithMeasure<m> |> int64 @>) 2L
+        checkEval "castingunits6" (<@ 2s |> LanguagePrimitives.Int16WithMeasure<m> |> int16 @>) 2s
+        checkEval "castingunits7" (<@ 2y |> LanguagePrimitives.SByteWithMeasure<m> |> sbyte @>) 2y
+
+    [<Test>]
+    member this.QuotationTests() = 
+        let (|Seq|_|) = function SpecificCall <@ seq @>(_, [_],[e]) -> Some e | _ -> None
+        let (|Append|_|) = function SpecificCall <@ Seq.append @>(_, [_],[e1;e2]) -> Some (e1,e2) | _ -> None
+        let (|Delay|_|) = function SpecificCall <@ Seq.delay @>(_, [_],[Lambda(_,e)]) -> Some e | _ -> None
+        let (|FinalFor|_|) = function SpecificCall <@ Seq.map @>(_, [_;_],[Lambda(v,e);sq]) -> Some (v,sq,e) | _ -> None
+        let (|OuterFor|_|) = function SpecificCall <@ Seq.collect @>(_, [_;_;_],[Lambda(v,e);sq]) -> Some (v,sq,e) | _ -> None
+        let (|Yield|_|) = function SpecificCall <@ Seq.singleton @>(_, [_],[e]) -> Some (e) | _ -> None
+        let (|While|_|) = function SpecificCall <@ Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.EnumerateWhile @>(_, [_],[e1;e2]) -> Some (e1,e2) | _ -> None
+        let (|TryFinally|_|) = function SpecificCall <@ Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.EnumerateThenFinally @>(_, [_],[e1;e2]) -> Some (e1,e2) | _ -> None
+        let (|Using|_|) = function SpecificCall <@ Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.EnumerateUsing @>(_, _,[e1;Lambda(v1,e2)]) -> Some (v1,e1,e2) | _ -> None
+        let (|Empty|_|) = function SpecificCall <@ Seq.empty @>(_,_,_) -> Some () | _ -> None
+        test "vrenjkr90kj1" 
+           (match <@ seq { for x in [1] -> x } @> with 
+            | Seq(Delay(FinalFor(v,Coerce(sq,_),res))) when sq = <@@ [1] @@> && res = Expr.Var(v) -> true
+            | Seq(Delay(FinalFor(v,sq,res))) -> printfn "v = %A, res = %A, sq = %A" v res sq; false
+            | Seq(Delay(sq)) -> printfn "Seq(Delay(_)), tm = %A" sq; false
+            | Seq(sq) -> printfn "Seq(_), tm = %A" sq; false 
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj2" 
+           (match <@ seq { for x in [1] do yield x } @> with 
+            | Seq(Delay(FinalFor(v,Coerce(sq,_),res))) when sq = <@@ [1] @@> && res = Expr.Var(v) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj3" 
+           (match <@ seq { for x in [1] do for y in [2] do yield x } @> with 
+            | Seq(Delay(OuterFor(v1,Coerce(sq1,_),FinalFor(v2,Coerce(sq2,_),res)))) when sq1 = <@@ [1] @@> && sq2 = <@@ [2] @@> && res = Expr.Var(v1) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj4" 
+           (match <@ seq { if true then yield 1 else yield 2 } @> with 
+            | Seq(Delay(IfThenElse(_,Yield(Int32(1)),Yield(Int32(2))))) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj5" 
+           (match <@ seq { for x in [1] do if true then yield x else yield 2 } @> with 
+            | Seq(Delay(OuterFor(vx,Coerce(sq,_),IfThenElse(_,Yield(res),Yield(Int32(2)))))) when sq = <@@ [1] @@>  && res = Expr.Var(vx) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj6" 
+           (match <@ seq { yield 1; yield 2 } @> with 
+            | Seq(Delay(Append(Yield(Int32(1)),Delay(Yield(Int32(2)))))) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj7" 
+           (match <@ seq { while true do yield 1 } @> with 
+            | Seq(Delay(While(Lambda(_,Bool(true)),Delay(Yield(Int32(1)))))) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj8" 
+           (match <@ seq { while true do yield 1 } @> with 
+            | Seq(Delay(While(Lambda(_,Bool(true)),Delay(Yield(Int32(1)))))) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj9" 
+           (match <@ seq { try yield 1 finally () } @> with 
+            | Seq(Delay(TryFinally(Delay(Yield(Int32(1))), Lambda(_,Unit)))) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj9" 
+           (match <@ seq { use ie = failwith "" in yield! Seq.empty } @> with 
+            | Seq(Delay(Using(v1,e1,Empty))) when v1.Name = "ie" -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kjA" 
+           (match <@ (3 :> obj) @> with 
+            | Coerce(Int32(3),ty) when ty = typeof<obj> -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kjB" 
+           (match <@ ("3" :> obj) @> with 
+            | Coerce(String("3"),ty) when ty = typeof<obj> -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kjC" 
+           (match <@ ("3" :> System.IComparable) @> with 
+            | Coerce(String("3"),ty) when ty = typeof<System.IComparable> -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+(*
+    test "vrenjkr90kjD" 
+       (match <@ (new obj() :?> System.IComparable) @> with 
+        | Coerce(NewObject(_),ty) when ty = typeof<System.IComparable> -> true
+        | sq -> printfn "tm = %A" sq; false) 
+
+    test "vrenjkr90kjE" 
+       (match <@ (new obj() :?> obj) @> with 
+        | NewObject(_) -> true
+        | sq -> printfn "tm = %A" sq; false) 
+*)
+
+
+    [<Test>]
+    member this.LargerAutomaticDiferentiationTest_FSharp_1_0_Bug_3498() = 
+
+          let q = 
+              <@ (fun (x1:double) -> 
+                     let fwd6 = 
+                         let y3 = x1 * x1
+                         (y3, (fun yb4 -> yb4 * 2.0 * x1))
+                     let rev5 = snd fwd6
+                     let w0 = fst fwd6
+
+                     let fwd14 = 
+                         let y11 = w0 + 1.0
+                         (y11, (fun yb12 -> yb12 * 1.0))
+                     let rev13 = snd fwd14
+                     let y8 = fst fwd14
+                     (y8, (fun y8b10 -> 
+                                let w0b2 = 0.0 
+                                let x1b1 = 0.0 
+                                let dxs15 = rev13 y8b10 
+                                let w0b2 = w0b2 + dxs15 
+                                let dxs7 = rev5 w0b2 
+                                let x1b1 = x1b1 + dxs7 
+                                x1b1))) @>
+
+          let r,rd = (q.Eval()) 4.0
+          test "vrknlwerwe90" (r = 17.0)
+          test "cew90jkml0rv" (rd 0.1 = 0.8)
+
+    [<Test>]
+    member this.FunkyMethodRepresentations() = 
+        // The IsSome and IsNone properties are represented as static methods because
+        // option uses 'null' as a representation
+        checkEval "clkedw0" (<@ let x : int option = None in x.IsSome @>) false
+        checkEval "clkedw1" (<@ let x : int option = None in x.IsNone @>) true
+        checkEval "clkedw2" (<@ let x : int option = Some 1 in x.Value @>) 1
+        //checkEval "clkedw3" (<@ let x : int option = Some 1 in x.ToString() @> |> eval  ) "Some(1)"
+
+    [<Test>]
+    member this.Extensions() = 
+
+        let v = new obj()
+        checkEval "ecnowe0" (<@ v.ExtensionMethod0() @>)  3
+        checkEval "ecnowe1" (<@ v.ExtensionMethod1() @>)  ()
+        checkEval "ecnowe2" (<@ v.ExtensionMethod2(3) @>) 3
+        checkEval "ecnowe3" (<@ v.ExtensionMethod3(3) @>)  ()
+        checkEval "ecnowe4" (<@ v.ExtensionMethod4(3,4) @>)  7
+        checkEval "ecnowe5" (<@ v.ExtensionMethod5(3,4) @>)  (3,4)
+        checkEval "ecnowe6" (<@ v.ExtensionProperty1 @>) 3
+        checkEval "ecnowe7" (<@ v.ExtensionProperty2 @>) 3
+        checkEval "ecnowe8" (<@ v.ExtensionProperty3 <- 4 @>)  ()
+        checkEval "ecnowe9" (<@ v.ExtensionIndexer1(3) @>) 3
+        checkEval "ecnowea" (<@ v.ExtensionIndexer2(3) <- 4 @>)  ()
+
+        check "ecnoweb" (eval (<@ v.ExtensionMethod0 @>) ()) 3 
+        check "ecnowec" (eval (<@ v.ExtensionMethod1 @>) ()) ()
+        check "ecnowed" (eval (<@ v.ExtensionMethod2 @>) 3) 3
+        check "ecnowee" (eval (<@ v.ExtensionMethod3 @>) 3) ()
+        check "ecnowef" (eval (<@ v.ExtensionMethod4 @>) (3,4)) 7
+        check "ecnoweg" (eval (<@ v.ExtensionMethod5 @>) (3,4)) (3,4)
+
+        let v2 = 3
+        let mutable v2b = 3
+        checkEval "ecnweh0" (<@ v2.ExtensionMethod0() @>) 3
+        checkEval "ecnweh1" (<@ v2.ExtensionMethod1() @>) ()
+        checkEval "ecnweh2" (<@ v2.ExtensionMethod2(3) @>) 3
+        checkEval "ecnweh3" (<@ v2.ExtensionMethod3(3) @>) ()
+        checkEval "ecnweh4" (<@ v2.ExtensionMethod4(3,4) @>) 7
+        checkEval "ecnweh5" (<@ v2.ExtensionMethod5(3,4) @>) (3,4)
+        checkEval "ecnweh6" (<@ v2.ExtensionProperty1 @>) 3
+        checkEval "ecnweh7" (<@ v2.ExtensionProperty2 @>) 3
+        checkEval "ecnweh8" (<@ v2b.ExtensionProperty3 <- 4 @>)  ()
+        checkEval "ecnweh9" (<@ v2.ExtensionIndexer1(3) @>) 3
+        checkEval "ecnweha" (<@ v2b.ExtensionIndexer2(3) <- 4 @>)  ()
+[<TestFixture>]
+type QuotationOfComparisonTest() =
+    let testComparisonOnEqualValues v1 =
+        <@ v1 = v1 @>.Eval() |> Assert.IsTrue
+        <@ v1 <> v1 @>.Eval() |> Assert.IsFalse
+        <@ v1 < v1 @>.Eval() |> Assert.IsFalse
+        <@ v1 > v1 @>.Eval() |> Assert.IsFalse
+        <@ v1 <= v1 @>.Eval() |> Assert.IsTrue
+        <@ v1 >= v1 @>.Eval() |> Assert.IsTrue
+
+    let testComparisonOnOrderedValues v1 v2 =
+        <@ v1 = v2 @>.Eval() |> Assert.IsFalse
+        <@ v1 <> v2 @>.Eval() |> Assert.IsTrue
+        <@ v1 < v2 @>.Eval() |> Assert.IsTrue
+        <@ v1 > v2 @>.Eval() |> Assert.IsFalse
+        <@ v1 <= v2 @>.Eval() |> Assert.IsTrue
+        <@ v1 >= v2 @>.Eval() |> Assert.IsFalse
+
+    
+    [<Test>]
+    member this.TestRecordEquality() =
+        let value1 = { field1 = 1; field2 = 1; }
+        testComparisonOnEqualValues value1
+
+    [<Test>]
+    member this.TestRecordInequality() =
+        let value1 = { field1 = 1; field2 = 1; }
+        let value2 = { field1 = 1; field2 = 2; }
+        testComparisonOnOrderedValues value1 value2
+
+    [<Test>]
+    member this.TestStringEquality() =
+        let value1 = "ABC"
+        testComparisonOnEqualValues value1
+
+    [<Test>]
+    member this.TestStringInequality() =
+        let value1 = "ABC"
+        let value2 = "ABD"
+        testComparisonOnOrderedValues value1 value2
+
+    [<Test>]
+    member this.TestValueTypeEquality() =
+        let value1 = 1
+        testComparisonOnEqualValues value1
+
+    [<Test>]
+    member this.TestValueTypeInequality() =
+        let value1 = 1
+        let value2 = 2
+        testComparisonOnOrderedValues value1 value2
+
+    [<Test>]
+    member this.TestUnionEquality() =
+        let value1 = Union1111.Case1 "ABC"
+        testComparisonOnEqualValues value1
+
+    [<Test>]
+    member this.TestUnionInequality() =
+        let value1 = Union1111.Case1 "ABC"
+        let value2 = Union1111.Case1 "XYZ"
+        testComparisonOnOrderedValues value1 value2
+
+
+module QuotationCompilation =
+    let eval (q: Expr<_>) = 
+        q.ToLinqExpression() |> ignore 
+        q.Compile() |> ignore  
+        q.Eval()
+        
+    // This tried to use non-existent 'Action' delegate with 5 type arguments
+    let q =
+        <@  (fun () -> 
+                let a = ref 0
+                let b = 0
+                let c = 0
+                let d = 0
+                let e = 0
+                a := b + c + d + e ) @>
+    check "qceva0" ((eval q) ()) ()
+
+
+
+
+    
+module IQueryableTests =
+    
+    type Customer = { mutable Name:string; Data: int; Cost:float; Sizes: int list }
+    let c1 = { Name="Don"; Data=6; Cost=6.2; Sizes=[1;2;3;4] }
+    let c2 = { Name="Peter"; Data=7; Cost=4.2; Sizes=[10;20;30;40] }
+    let c3 = { Name="Freddy"; Data=8; Cost=9.2; Sizes=[11;12;13;14] }
+    let c4 = { Name="Freddi"; Data=8; Cost=1.0; Sizes=[21;22;23;24] }
+    
+    let data = [c1;c2;c3;c4]
+    let db = System.Linq.Queryable.AsQueryable<Customer>(data |> List.toSeq)
+
+    printfn "db = %A" (Reflection.FSharpType.GetRecordFields (typeof<Customer>, System.Reflection.BindingFlags.Public ||| System.Reflection.BindingFlags.NonPublic))
+    let q1 = <@ seq { for i in db -> i.Name } @>
+    let q2 = <@ c1.Name @>
+    printfn "q2 = %A" q2
+    
+    printfn "db = %A" db.Expression
+
+    let checkCommuteSeq s q =
+        check s (query q |> Seq.toList) (q.Eval() |> Seq.toList)
+
+    let checkCommuteVal s q =
+        check s (query q) (q.Eval())
+
+    let q = <@ System.DateTime.Now - System.DateTime.Now @>
+    q.Eval() |> ignore
+    
+    checkCommuteSeq "cnewnc01" <@ db @>
+    //debug <- true
+    checkCommuteSeq "cnewnc02" <@ seq { for i in db -> i }  @>
+    checkCommuteSeq "cnewnc03" <@ seq { for i in db -> i.Name }  @>
+    checkCommuteSeq "cnewnc04" <@ [ for i in db -> i.Name ]  @>
+    checkCommuteSeq "cnewnc05" <@ [ for i in db do yield i.Name ]  @>
+    checkCommuteSeq "cnewnc06" <@ [ for i in db do 
+                                      for j in db do 
+                                          yield (i.Name,j.Name) ] @>
+
+    checkCommuteSeq "cnewnc07" <@ [ for i in db do 
+                                      for j in db do 
+                                          if i.Data = j.Data then 
+                                              yield (i.Data,i.Name,j.Name) ] @>
+
+    checkCommuteSeq "cnewnc08"  <@ [ for i in db do 
+                                      if i.Data = 8 then 
+                                          for j in db do 
+                                              if i.Data = j.Data then 
+                                                  yield (i.Data,i.Name,j.Name) ] @>
+
+    checkCommuteSeq "cnewnc08"  <@ [ for i in db do 
+                                      match i.Data with 
+                                      | 8 -> 
+                                          for j in db do 
+                                              if i.Data = j.Data then 
+                                                  yield (i.Data,i.Name,j.Name) 
+                                      | _ -> 
+                                          () ] @>
+
+
+
+    // EXPECT PASS
+    checkCommuteSeq "cnewnc08"  <@  seq { for i in db do for j in db do yield (i.Data) }  @>
+    checkCommuteSeq "cnewnc08"  <@  db |> Seq.take 3 @>
+    checkCommuteVal "cnewnc08"  <@  db |> Seq.take 3 |> Seq.length @>
+    checkCommuteVal "cnewnc08"  <@  Seq.length (seq { for i in db do for j in db do yield (i.Data) })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.length (seq { for i in db do for j in db do yield (i.Data) })   @> 
+    checkCommuteVal "cnewnc08"  <@  (seq { for i in db do for j in db do yield (i.Data) })  |> Seq.length  @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.max (seq { for i in db do for j in db do yield (i.Data) })   @> 
+    checkCommuteVal "cnewnc08"  <@  seq { for i in db do for j in db do yield (i.Data) } |> Seq.max   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.min (seq { for i in db do for j in db do yield (i.Data) })   @> 
+    checkCommuteVal "cnewnc08"  <@  seq { for i in db do for j in db do yield (i.Data) } |> Seq.min  @> 
+    checkCommuteSeq "cnewnc08"  <@ Seq.distinct (seq { for i in db do for j in db do yield i }) @>
+    checkCommuteSeq "cnewnc08"  <@ seq { for i in db do for j in db do yield i } |> Seq.distinct @>
+    checkCommuteVal "cnewnc08"  <@  Seq.max (seq { for i in db do for j in db do yield float i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.max (seq { for i in db do for j in db do yield float32 i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.max (seq { for i in db do for j in db do yield decimal i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.min (seq { for i in db do for j in db do yield float i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.min (seq { for i in db do for j in db do yield float32 i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.min (seq { for i in db do for j in db do yield decimal i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.average (seq { for i in db do for j in db do yield i.Cost })   @> 
+    checkCommuteVal "cnewnc08"  <@   (seq { for i in db do for j in db do yield i.Cost })  |> Seq.average @> 
+
+    checkCommuteSeq "cnewnc08"  (<@ Microsoft.FSharp.Linq.Query.groupBy
+                                        (fun x -> x) 
+                                        (seq { for i in db do yield i.Data })  |> Seq.map Seq.toList |> Seq.toList @> ) 
+
+
+    checkCommuteSeq "cnewnc08"  (<@ Microsoft.FSharp.Linq.Query.join 
+                                        (seq { for i in db do yield i.Data }) 
+                                        (seq { for i in db do yield i.Data })  
+                                        (fun x -> x) 
+                                        (fun x -> x) 
+                                        (fun x y -> x + y) @> ) 
+
+    checkCommuteSeq "cnewnc08"  (<@ Microsoft.FSharp.Linq.Query.groupJoin 
+                                        (seq { for i in db do yield i.Data }) 
+                                        (seq { for i in db do yield i.Data }) 
+                                        (fun x -> x) 
+                                        (fun x -> x) 
+                                        (fun x y -> x + Seq.length y)  @> ) 
+
+    check "cnewnc08"  (query <@  Seq.average (seq { for i in db do for j in db do yield (i.Cost) })   @>  - 5.15 <= 0.0000001) true
+
+    // By design: no 'distinctBy', "maxBy", "minBy", "groupBy" support in queries
+    check "lcvkneio" (try let _ = query <@ Seq.distinctBy (fun x -> x) (seq { for i in db do for j in db do yield i })  @> in  false with _ -> true) true
+    check "lcvkneio" (try let _ = query <@ Seq.maxBy (fun x -> x) (seq { for i in db do for j in db do yield i })  @> in  false with _ -> true) true
+    check "lcvkneio" (try let _ = query <@ Seq.minBy (fun x -> x) (seq { for i in db do for j in db do yield i })  @> in  false with _ -> true) true
+    check "lcvkneio" (try let _ = query <@ Seq.groupBy (fun x -> x) (seq { for i in db do for j in db do yield i })  @> in  false with _ -> true) true
+
+module CheckedTests = 
+    open Microsoft.FSharp.Core.Operators.Checked
+          
+    [<TestFixture>]
+    type public QuotationEvalCheckedTests() =
+      
+        [<Test>]
+        member this.FloatCheckedTests() = 
+
+         // set up bindings
+         let x1 = <@ 2.0<kg> + 4.0<kg>  @> |> eval
+         let x2 = <@ 2.0<s> - 4.0<s>  @> |> eval
+         let x3 = <@ 2.0<m> / 4.0<s>  @> |> eval
+         let x3a = <@ 2.0<m> / 4.0<m>  @> |> eval
+         let x3b = <@ 1.0 / 4.0<s>  @> |> eval
+         let x3c = <@ 1.0<m> / 4.0  @> |> eval
+         let x4 = <@ 2.0<m> * 4.0<s>  @> |> eval
+         let x4a = <@ 2.0<m> * 4.0<m>  @> |> eval
+         let x4b = <@ 2.0 * 4.0<m>  @> |> eval
+         let x4c = <@ 2.0<m> * 4.0  @> |> eval
+         let x5 = <@ 5.0<m> % 3.0<m>  @> |> eval
+         let x6 = <@ - (2.0<m>)  @> |> eval
+         let x7 = <@ abs (-2.0<m>)  @> |> eval
+         let x8 = <@ sqrt (4.0<sqrm>)  @> |> eval
+         let x9 = <@ [ 1.0<m> .. 1.0<m> .. 4.0<m> ]  @> |> eval
+         let x10 = <@ sign (3.0<m/s>)  @> |> eval
+         let x11 = <@ atan2 4.4<s^3> 5.4<s^3>  @> |> eval
+         let x12 = <@ Seq.sum [2.0<sqrm>; 3.0<m^2>]  @> |> eval
+         let x12a = <@ Seq.sumBy (fun x -> x*x) [(2.0<sqrm> : area); 3.0<m^2>]  @> |> eval
+         let x13 = <@ (Seq.average [2.0<sqrm>; 3.0<m^2>]) : area  @> |> eval
+         let x13a = <@ Seq.averageBy (fun x -> x*x) [2.0<m^2/m>; 3.0<m>]  @> |> eval
+         let x14 = <@ x13 + x13a  @> |> eval
+
+         // check the types and values!
+         test "x1" (x1 = 6.0<kg>)
+         test "x2" (x2 = -2.0<s>)
+         test "x3" (x3 = 0.5<m/s>)
+         test "x3a" (x3a = 0.5)
+         test "x3b" (x3b = 0.25<1/s>)
+         test "x3c" (x3c = 0.25<m>)
+         test "x4" (x4 = 8.0<m s>)
+         test "x4a" (x4a = 8.0<m^2>)
+         test "x4b" (x4b = 8.0<m>)
+         test "x4c" (x4c = 8.0<m>)
+         test "x5" (x5 = 2.0<m>)
+         test "x6" (x6 = -2.0<m>)
+         test "x7" (x7 = 2.0<m>)
+         test "x8" (x8 = 2.0<m>)
+         test "x9" (x9 = [1.0<m>; 2.0<m>; 3.0<m>; 4.0<m>])
+         test "x10" (x10 = 1)
+         test "x12" (x12 = 5.0<m^2>)
+         test "x12a" (x12a = 13.0<m^4>)
+         test "x13" (x13 = 2.5<m^2>)
+         test "x13a" (x13a = 6.5<m^2>)
+          
+
+        [<Test>]
+        member this.Float32CheckedTests() = 
+
+
+         let y1 = <@ 2.0f<kg> + 4.0f<kg>  @> |> eval
+         let y2 = <@ 2.0f<s> - 4.0f<s>  @> |> eval
+         let y3 = <@ 2.0f<m> / 4.0f<s>  @> |> eval
+         let y3a = <@ 2.0f<m> / 4.0f<m>  @> |> eval
+         let y3b = <@ 1.0f / 4.0f<s>  @> |> eval
+         let y3c = <@ 1.0f<m> / 4.0f  @> |> eval
+         let y4 = <@ 2.0f<m> * 4.0f<s>  @> |> eval
+         let y4a = <@ 2.0f<m> * 4.0f<m>  @> |> eval
+         let y4b = <@ 2.0f * 4.0f<m>  @> |> eval
+         let y4c = <@ 2.0f<m> * 4.0f  @> |> eval
+         let y5 = <@ 5.0f<m> % 3.0f<m>  @> |> eval
+         let y6 = <@ - (2.0f<m>)  @> |> eval
+         let y7 = <@ abs (2.0f<m>)  @> |> eval
+         let y8 = <@ sqrt (4.0f<sqrm>)  @> |> eval
+         let y9 = <@ [ 1.0f<m> .. 1.0f<m> .. 4.0f<m> ]  @> |> eval
+         let y10 = <@ sign (3.0f<m/s>)  @> |> eval
+         let y11 = <@ atan2 4.4f<s^3> 5.4f<s^3>  @> |> eval
+         let y12 = <@ Seq.sum [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+         let y12a = <@ Seq.sumBy (fun y -> y*y) [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+         let y13 = <@ Seq.average [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+         let y13a = <@ Seq.averageBy (fun y -> y*y) [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+
+         // check the types and values!
+         test "y1" (y1 = 6.0f<kg>)
+         test "y2" (y2 = -2.0f<s>)
+         test "y3" (y3 = 0.5f<m/s>)
+         test "y3a" (y3a = 0.5f)
+         test "y3b" (y3b = 0.25f<1/s>)
+         test "y3c" (y3c = 0.25f<m>)
+         test "y4" (y4 = 8.0f<m s>)
+         test "y4a" (y4a = 8.0f<m^2>)
+         test "y4b" (y4b = 8.0f<m>)
+         test "y4c" (y4c = 8.0f<m>)
+         test "y5" (y5 = 2.0f<m>)
+         test "y6" (y6 = -2.0f<m>)
+         test "y7" (y7 = 2.0f<m>)
+         test "y8" (y8 = 2.0f<m>)
+         test "y9" (y9 = [1.0f<m>; 2.0f<m>; 3.0f<m>; 4.0f<m>])
+         test "y10" (y10 = 1)
+         test "y12" (y12 = 5.0f<m^2>)
+         test "y12a" (y12a = 13.0f<m^4>)
+         test "y13" (y13 = 2.5f<m^2>)
+         test "y13a" (y13a = 6.5f<m^4>)
+          
+
+        [<Test>]
+        member this.DecimalCheckedTests() = 
+
+         let z1 = <@ 2.0M<kg> + 4.0M<kg>  @> |> eval
+         let z2 = <@ 2.0M<s> - 4.0M<s>  @> |> eval
+         let z3 = <@ 2.0M<m> / 4.0M<s>  @> |> eval
+         let z3a = <@ 2.0M<m> / 4.0M<m>  @> |> eval
+         let z3b = <@ 1.0M / 4.0M<s>  @> |> eval
+         let z3c = <@ 1.0M<m> / 4.0M  @> |> eval
+         let z4 = <@ 2.0M<m> * 4.0M<s>  @> |> eval
+         let z4a = <@ 2.0M<m> * 4.0M<m>  @> |> eval
+         let z4b = <@ 2.0M * 4.0M<m>  @> |> eval
+         let z4c = <@ 2.0M<m> * 4.0M  @> |> eval
+         let z5 = <@ 5.0M<m> % 3.0M<m>  @> |> eval
+         let z6 = <@ - (2.0M<m>)  @> |> eval
+         let z7 = <@ abs (2.0M<m>)  @> |> eval
+        // let z9 = <@ [ 1.0M<m> .. 4.0M<m> ]
+         let z10 = <@ sign (3.0M<m/s>)  @> |> eval
+
+
+         // check the types and values!
+         test "z1" (z1 = 6.0M<kg>)
+         test "z2" (z2 = -2.0M<s>)
+         test "z3" (z3 = 0.5M<m/s>)
+         test "z3a" (z3a = 0.5M)
+         test "z3b" (z3b = 0.25M<1/s>)
+         test "z3c" (z3c = 0.25M<m>)
+         test "z4" (z4 = 8.0M<m s>)
+         test "z4a" (z4a = 8.0M<m^2>)
+         test "z4b" (z4b = 8.0M<m>)
+         test "z4c" (z4c = 8.0M<m>)
+         test "z5" (z5 = 2.0M<m>)
+         test "z6" (z6 = -2.0M<m>)
+         test "z7" (z7 = 2.0M<m>)
+         test "z10" (z10 = 1)
+          
+ 
diff --git a/src/FSharp.PowerPack.Unittests/SetMapTests.fs b/src/FSharp.PowerPack.Unittests/SetMapTests.fs
new file mode 100755
index 0000000..7a7ea0c
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/SetMapTests.fs
@@ -0,0 +1,245 @@
+namespace FSharp.PowerPack.Unittests
+
+open NUnit.Framework
+open System.Collections.Generic
+
+#nowarn "40"
+
+type ComparerA() = 
+  interface IComparer<int> with
+     override __.Compare(x,y) = compare (unbox<int> x) (unbox<int> y)
+
+type ComparerB() = 
+  interface IComparer<int> with
+     override __.Compare(x,y) = compare (unbox<int> y) (unbox<int> x)
+
+[<TestFixture>]
+type public MapFunctorTests() =
+  
+    let Z5Map = Map.Make(fun (x:int) (y:int) -> compare (x mod 5) (y mod 5))
+    let z5MapEqRange n m x = 
+
+      for i = n to m do 
+        test "ew9wef" ((Z5Map.find i x / 100) mod 5 = i mod 5);
+      done;
+      for i = n to m do 
+        test "ew9wef" (match Z5Map.tryfind i x with Some n -> (n/100) % 5 = i % 5 | None -> failwith "test failed");
+      done
+
+
+    [<Test>]
+    member this.BasicTests_z5test39342() = 
+          let x = Z5Map.empty 
+          let x = Z5Map.add 1 100 x
+          let x = Z5Map.add 2 200 x
+          let x = Z5Map.add 3 300 x
+          let x = Z5Map.add 4 400 x
+          let x = Z5Map.add 5 500 x
+          let x = Z5Map.add 6 600 x
+          let x = Z5Map.add 7 700 x
+          let x = Z5Map.add 8 800 x
+          let x = Z5Map.add 9 900 x
+          let x = Z5Map.add 10 1000 x
+          let x = Z5Map.add 11 1100 x
+          let x = Z5Map.add 12 1200 x
+          let x = Z5Map.add 13 1300 x
+          let x = Z5Map.add 14 1400 x
+          let x = Z5Map.add 15 1500 x
+          z5MapEqRange 1 15 x 
+
+    [<Test>]
+    member this.BasicTests_z5test39343() = 
+          let x = Z5Map.empty 
+          let x = Z5Map.add 15 1500 x
+          let x = Z5Map.add 14 1400 x
+          let x = Z5Map.add 13 1300 x
+          let x = Z5Map.add 12 1200 x
+          let x = Z5Map.add 11 1100 x
+          let x = Z5Map.add 10 1000 x
+          let x = Z5Map.add 9 900 x
+          let x = Z5Map.add 8 800 x
+          let x = Z5Map.add 7 700 x
+          let x = Z5Map.add 6 600 x
+          let x = Z5Map.add 5 500 x
+          let x = Z5Map.add 4 400 x
+          let x = Z5Map.add 3 300 x
+          let x = Z5Map.add 2 200 x
+          let x = Z5Map.add 1 100 x
+          z5MapEqRange 1 15 x 
+
+    [<Test>]
+    member this.BasicTests_z5test39344() = 
+          let x = Z5Map.empty 
+          let x = Z5Map.add 4 400 x
+          z5MapEqRange 4 4 x 
+
+
+    [<Test>]
+    member this.BasicTests_z5test39345() = 
+        let x = Z5Map.empty 
+        let x = Z5Map.add 4 400 x
+        let x = Z5Map.add 4 400 x
+        z5MapEqRange 4 4 x 
+
+
+    [<Test>]
+    member this.BasicTests_z5test39346() = 
+        let x = Z5Map.empty 
+        let x = Z5Map.add 4 400 x
+        let x = Z5Map.remove 4 x
+        z5MapEqRange 4 3 x 
+
+
+    [<Test>]
+    member this.BasicTests_z5test39347() = 
+        let x = Z5Map.empty 
+        let x = Z5Map.add 1 100 x
+        let x = Z5Map.add 2 200 x
+        let x = Z5Map.add 3 300 x
+        let x = Z5Map.add 4 400 x
+        let x = Z5Map.add 5 500 x
+        let x = Z5Map.remove 0 x
+        let x = Z5Map.remove 2 x
+        let x = Z5Map.remove 1 x
+        z5MapEqRange 3 4 x 
+
+    [<Test>]
+    member this.BasicTests_Comparer() = 
+        check "4i4cnio1" (Z5Map.empty.Comparer.Compare (2,7)) 0
+        check "4i4cnio2" (Z5Map.empty.Comparer.Compare (2,3)) -1
+        check "4i4cnio3" (Z5Map.empty.Comparer.Compare (2,8)) -1
+        check "4i4cnio4" (Z5Map.empty.Comparer.Compare (3,2)) 1
+        check "4i4cnio5" (Z5Map.empty.Comparer.Compare (8,2)) 1
+
+    [<Test>]
+    member this.Repro4884() = 
+        (* #r "FSharp.PowerPack" *)
+        let m0 = Tagged.Map<int,int,Comparer<int>>.Empty(Comparer.Default)
+        let m1 = Tagged.Map<int,int,Comparer<int>>.Empty(Comparer.Default)
+        let mres = m0 > m1
+        do check "set of sets comparison" false mres
+
+type intSet = int Tagged.Set
+type intSetSet = intSet Tagged.Set
+
+[<TestFixture>]
+type public SetFunctorTests() =
+  
+    let Z3Set = Set.Make(fun (x:int) (y:int) -> compare (x mod 3) (y mod 3))
+
+    [<Test>]
+    member this.BasicTests1() = 
+
+        do check "set comparison" 0 (Z3Set.compare Z3Set.empty Z3Set.empty)
+        do check "set comparison" 0   (Z3Set.compare (Z3Set.add 1 Z3Set.empty) (Z3Set.add 1 Z3Set.empty))
+        do check "set comparison" 0   (Z3Set.compare (Z3Set.add 3 Z3Set.empty) (Z3Set.add 0 Z3Set.empty))
+        do check "set comparison" 0   (Z3Set.compare (Z3Set.add 1 (Z3Set.add 2 Z3Set.empty)) (Z3Set.add 2 (Z3Set.add 1 Z3Set.empty)))
+        do check "set comparison" 0   (Z3Set.compare (Z3Set.add 1 (Z3Set.add 2 (Z3Set.add 3 Z3Set.empty))) (Z3Set.add 3 (Z3Set.add 2 (Z3Set.add 1 Z3Set.empty))))
+        do check "set comparison" 0   (Z3Set.compare (Z3Set.add 1 (Z3Set.add 2 (Z3Set.add 0 Z3Set.empty))) (Z3Set.add 3 (Z3Set.add 2 (Z3Set.add 1 Z3Set.empty))))
+           
+           
+        do check "set comparison" false (0 = Z3Set.compare Z3Set.empty (Z3Set.add 1 Z3Set.empty))
+        do check "set comparison" false  (0 = Z3Set.compare (Z3Set.add 1 Z3Set.empty) (Z3Set.add 2 Z3Set.empty))
+        do check "set comparison" false  (0 = Z3Set.compare (Z3Set.add 0 (Z3Set.add 1 Z3Set.empty)) (Z3Set.add 2 (Z3Set.add 1 Z3Set.empty)))
+        do check "set comparison" false  (0 = Z3Set.compare (Z3Set.add 1 (Z3Set.add 0 (Z3Set.add 1 Z3Set.empty))) (Z3Set.add 5 (Z3Set.add 4 (Z3Set.add 3 Z3Set.empty))))
+
+
+        let Z3SetSet = Set.Make(Z3Set.compare)
+
+        let one = Z3Set.add 0 Z3Set.empty
+        let two = Z3Set.add 1 one
+        let three = Z3Set.add 2 two
+
+        do check "set of sets comparison" 0 (Z3SetSet.compare Z3SetSet.empty Z3SetSet.empty)
+        do check "set of sets comparison" 0   (Z3SetSet.compare (Z3SetSet.add one Z3SetSet.empty) (Z3SetSet.add one Z3SetSet.empty))
+        do check "set of sets comparison" 0   (Z3SetSet.compare (Z3SetSet.add one (Z3SetSet.add two Z3SetSet.empty)) (Z3SetSet.add two (Z3SetSet.add one Z3SetSet.empty)))
+        do check "set of sets comparison" 0   (Z3SetSet.compare (Z3SetSet.add one (Z3SetSet.add two (Z3SetSet.add three Z3SetSet.empty))) (Z3SetSet.add three (Z3SetSet.add two (Z3SetSet.add one Z3SetSet.empty))))
+           
+        do check "set of sets comparison" false (0 = Z3SetSet.compare Z3SetSet.empty (Z3SetSet.add one Z3SetSet.empty))
+        do check "set of sets comparison" false  (0 = Z3SetSet.compare (Z3SetSet.add one Z3SetSet.empty) (Z3SetSet.add two Z3SetSet.empty))
+        do check "set of sets comparison" false  (0 = Z3SetSet.compare (Z3SetSet.add one (Z3SetSet.add two Z3SetSet.empty)) (Z3SetSet.add three (Z3SetSet.add one Z3SetSet.empty)))
+
+        let checkReflexive f x y = (f x y = - f y x)
+        do check "set of sets comparison" true (checkReflexive Z3SetSet.compare Z3SetSet.empty (Z3SetSet.add one Z3SetSet.empty))
+        do check "set of sets comparison" true (checkReflexive Z3SetSet.compare (Z3SetSet.add one Z3SetSet.empty) (Z3SetSet.add two Z3SetSet.empty))
+        do check "set of sets comparison" true (checkReflexive Z3SetSet.compare (Z3SetSet.add one (Z3SetSet.add two Z3SetSet.empty)) (Z3SetSet.add three (Z3SetSet.add one Z3SetSet.empty)))
+
+    member this.BasicTests_Comparer() = 
+        check "4i4cnio1" (Z3Set.empty.Comparer.Compare (2,5)) 0
+        check "4i4cnio2" (Z3Set.empty.Comparer.Compare (0,1)) -1
+        check "4i4cnio3" (Z3Set.empty.Comparer.Compare (0,4)) -1
+        check "4i4cnio4" (Z3Set.empty.Comparer.Compare (1,0)) 1
+        check "4i4cnio5" (Z3Set.empty.Comparer.Compare (4,0)) 1
+
+    [<Test>]
+    member this.Repro4884() = 
+        let s0 = Tagged.Set<int,Comparer<int>>.Empty(Comparer.Default)
+        let s1 = Tagged.Set<int,Comparer<int>>.Empty(Comparer.Default)
+        let sres = s0 > s1
+        do  System.Console.WriteLine("Regression 4884")
+        do check "set of sets comparison" false sres
+
+
+    [<Test>]
+    // Bug 4883: TaggedCollections should override Equals()
+    member this.Repro4883() = 
+        let compA = ComparerA()
+        let nA1  = Tagged.Map<int,int,ComparerA>.Empty(compA)
+        let nA2  = Tagged.Map<int,int,ComparerA>.Empty(compA)
+             
+        let mA1  = Tagged.Map<int,int,ComparerA>.Empty(ComparerA())
+        let mA2  = Tagged.Map<int,int,ComparerA>.Empty(ComparerA())
+        let mA1x = mA1.Add(1,1)
+        let mA2x = mA2.Add(1,1)
+        let mB1  = Tagged.Map<int,int,ComparerB>.Empty(ComparerB())
+        let mB2  = Tagged.Map<int,int,ComparerB>.Empty(ComparerB())
+        let mB1x = mB1.Add(1,1)
+        let mB2x = mB2.Add(1,1)
+
+        (*let check str x y = if x=y then printf "-OK-: %s\n" str else printf "FAIL: %s\n" str*)
+             
+        do  check "Bug4883.map.A1  = A1"   (mA1  = mA1)            true   (* empty     / empty     and identical *)
+        do  check "Bug4883.map.A1  = A2"   (mA1  = mA2)            true   (* empty     / empty     and non-identical *)
+        do  check "Bug4883.map.A1  = A1x"  (mA1  = mA1x)           false  (* empty     / non-empty *)
+        do  check "Bug4883.map.A1x = A1x"  (mA1x = mA1x)           true   (* non-empty / non-empty and identical *)
+        do  check "Bug4883.map.A1x = A2x"  (mA1x = mA2x)           true   (* non-empty / non-empty and non-identical *)
+
+        do  check "Bug4883.map.A1  eq A1"  (mA1.Equals(box mA1))   true
+        do  check "Bug4883.map.A1  eq A2"  (mA1.Equals(box mA2))   true
+        do  check "Bug4883.map.A1  eq A1x" (mA1.Equals(box mA1x))  false
+        do  check "Bug4883.map.A1x eq A1x" (mA1x.Equals(box mA1x)) true
+        do  check "Bug4883.map.A1x eq A2x" (mA1x.Equals(box mA2x)) true
+
+        do  check "Bug4883.map.A1  eq B1"  (mA1.Equals(box mB1))   false  (* empty     / empty     and different comparers *)
+        do  check "Bug4883.map.A1  eq B1x" (mA1.Equals(box mB1))   false  (* empty     / non-empty and different comparers *)
+        do  check "Bug4883.map.A1x eq B1x" (mA1x.Equals(box mB1))  false  (* non-empty / empty     and different comparers *)
+        do  check "Bug4883.map.A1x eq B1x" (mA1x.Equals(box mB1x)) false  (* non-empty / non-empty and different comparers *)
+
+        let sA1  = Tagged.Set<int,ComparerA>.Empty(ComparerA())
+        let sA2  = Tagged.Set<int,ComparerA>.Empty(ComparerA())
+        let sA1x = sA1.Add(1)
+        let sA2x = sA2.Add(1)
+        let sB1  = Tagged.Set<int,ComparerB>.Empty(ComparerB())
+        let sB2  = Tagged.Set<int,ComparerB>.Empty(ComparerB())
+        let sB1x = sB1.Add(1)
+        let sB2x = sB2.Add(1)       
+
+        do  check "Bug4883.map.A1  = A1"   (sA1  = sA1)            true   (* empty     / empty     and identical *)
+        do  check "Bug4883.map.A1  = A2"   (sA1  = sA2)            true   (* empty     / empty     and non-identical *)
+        do  check "Bug4883.map.A1  = A1x"  (sA1  = sA1x)           false  (* empty     / non-empty *)
+        do  check "Bug4883.map.A1x = A1x"  (sA1x = sA1x)           true   (* non-empty / non-empty and identical *)
+        do  check "Bug4883.map.A1x = A2x"  (sA1x = sA2x)           true   (* non-empty / non-empty and non-identical *)
+
+        do  check "Bug4883.map.A1  eq A1"  (sA1.Equals(box sA1))   true
+        do  check "Bug4883.map.A1  eq A2"  (sA1.Equals(box sA2))   true
+        do  check "Bug4883.map.A1  eq A1x" (sA1.Equals(box sA1x))  false
+        do  check "Bug4883.map.A1x eq A1x" (sA1x.Equals(box sA1x)) true
+        do  check "Bug4883.map.A1x eq A2x" (sA1x.Equals(box sA2x)) true
+
+        do  check "Bug4883.map.A1  eq B1"  (sA1.Equals(box sB1))   false  (* empty     / empty     and different comparers *)
+        do  check "Bug4883.map.A1  eq B1x" (sA1.Equals(box sB1))   false  (* empty     / non-empty and different comparers *)
+        do  check "Bug4883.map.A1x eq B1x" (sA1x.Equals(box sB1))  false  (* non-empty / empty     and different comparers *)
+        do  check "Bug4883.map.A1x eq B1x" (sA1x.Equals(box sB1x)) false  (* non-empty / non-empty and different comparers *)
+
+        do  System.Console.WriteLine("Regression 4883")
+
diff --git a/src/FSharp.PowerPack.Unittests/StructuredFormatTests.fs b/src/FSharp.PowerPack.Unittests/StructuredFormatTests.fs
new file mode 100755
index 0000000..cf528fc
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/StructuredFormatTests.fs
@@ -0,0 +1,11 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Linq.QuotationEvaluation
+open Microsoft.FSharp.Text.StructuredFormat
+
+module StructuredFormat_MiscBitsAndPiecesToCompiler = 
+    let opts = { FormatOptions.Default with 
+                   PrintWidth=30; 
+                   ShowIEnumerable=true;
+                   ShowProperties=true }
diff --git a/src/FSharp.PowerPack.Unittests/Utilities.fs b/src/FSharp.PowerPack.Unittests/Utilities.fs
new file mode 100755
index 0000000..7fb28c4
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/Utilities.fs
@@ -0,0 +1,125 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open System
+open System.Collections.Generic
+
+[<AutoOpen>]
+module Utilities = 
+    let test msg b = Assert.IsTrue(b, "MiniTest '" + msg + "'")
+    let logMessage msg = 
+        System.Console.WriteLine("LOG:" + msg)
+//        System.Diagnostics.Trace.WriteLine("LOG:" + msg)
+    let check msg v1 v2 = test msg (v1 = v2)
+    let reportFailure msg = Assert.Fail msg
+    let numActiveEnumerators = ref 0
+    let throws f = try f() |> ignore; false with e -> true
+
+    let countEnumeratorsAndCheckedDisposedAtMostOnceAtEnd (seq: seq<'a>) =
+       let enumerator() = 
+                 numActiveEnumerators := !numActiveEnumerators + 1;
+                 let disposed = ref false in
+                 let endReached = ref false in
+                 let ie = seq.GetEnumerator() in
+                 { new System.Collections.Generic.IEnumerator<'a> with 
+                      member x.Current =
+                          test "rvlrve0" (not !endReached);
+                          test "rvlrve1" (not !disposed);
+                          ie.Current
+                      member x.Dispose() = 
+                          test "rvlrve2" !endReached;
+                          test "rvlrve4" (not !disposed);
+                          numActiveEnumerators := !numActiveEnumerators - 1;
+                          disposed := true;
+                          ie.Dispose() 
+                   interface System.Collections.IEnumerator with 
+                      member x.MoveNext() = 
+                          test "rvlrve0" (not !endReached);
+                          test "rvlrve3" (not !disposed);
+                          endReached := not (ie.MoveNext());
+                          not !endReached
+                      member x.Current = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          box ie.Current
+                      member x.Reset() = 
+                          ie.Reset()
+                   } in
+
+       { new seq<'a> with 
+             member x.GetEnumerator() =  enumerator() 
+         interface System.Collections.IEnumerable with 
+             member x.GetEnumerator() =  (enumerator() :> _) }
+
+    let countEnumeratorsAndCheckedDisposedAtMostOnce (seq: seq<'a>) =
+       let enumerator() = 
+                 let disposed = ref false in
+                 let endReached = ref false in
+                 let ie = seq.GetEnumerator() in
+                 numActiveEnumerators := !numActiveEnumerators + 1;
+                 { new System.Collections.Generic.IEnumerator<'a> with 
+                      member x.Current =
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          ie.Current
+                      member x.Dispose() = 
+                          test "qrvlrve4" (not !disposed);
+                          numActiveEnumerators := !numActiveEnumerators - 1;
+                          disposed := true;
+                          ie.Dispose() 
+                   interface System.Collections.IEnumerator with 
+                      member x.MoveNext() = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve3" (not !disposed);
+                          endReached := not (ie.MoveNext());
+                          not !endReached
+                      member x.Current = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          box ie.Current
+                      member x.Reset() = 
+                          ie.Reset()
+                   } in
+
+       { new seq<'a> with 
+             member x.GetEnumerator() =  enumerator() 
+         interface System.Collections.IEnumerable with 
+             member x.GetEnumerator() =  (enumerator() :> _) }
+
+    // Verifies two sequences are equal (same length, equiv elements)
+    let verifySeqsEqual seq1 seq2 =
+        if Seq.length seq1 <> Seq.length seq2 then Assert.Fail()
+        
+        let zippedElements = Seq.zip seq1 seq2
+        if zippedElements |> Seq.forall (fun (a, b) -> a = b) 
+        then ()
+        else Assert.Fail()
+        
+    /// Check that the lamda throws an exception of the given type. Otherwise
+    /// calls Assert.Fail()
+    let private checkThrowsExn<'a when 'a :> exn> (f : unit -> unit) =
+        let funcThrowsAsExpected =
+            try
+                let _ = f ()
+                false // Did not throw!
+            with
+            | :? 'a
+                -> true   // Thew null ref, OK
+            | _ -> false  // Did now throw a null ref exception!
+        if funcThrowsAsExpected
+        then ()
+        else Assert.Fail()
+
+    // Illegitimate exceptions. Once we've scrubbed the library, we should add an
+    // attribute to flag these exception's usage as a bug.
+    let checkThrowsNullRefException      f = checkThrowsExn<NullReferenceException>   f
+    let checkThrowsIndexOutRangException f = checkThrowsExn<IndexOutOfRangeException> f
+
+    // Legit exceptions
+    let checkThrowsNotSupportedException f = checkThrowsExn<NotSupportedException>    f
+    let checkThrowsArgumentException     f = checkThrowsExn<ArgumentException>        f
+    let checkThrowsArgumentNullException f = checkThrowsExn<ArgumentNullException>    f
+    let checkThrowsKeyNotFoundException  f = checkThrowsExn<KeyNotFoundException>     f
+    let checkThrowsDivideByZeroException f = checkThrowsExn<DivideByZeroException>    f
+    let checkThrowsInvalidOperationExn   f = checkThrowsExn<InvalidOperationException> f
+
+       
\ No newline at end of file
diff --git a/src/FSharp.PowerPack.Unittests/northwnd.cs b/src/FSharp.PowerPack.Unittests/northwnd.cs
new file mode 100755
index 0000000..af5ec8e
--- /dev/null
+++ b/src/FSharp.PowerPack.Unittests/northwnd.cs
@@ -0,0 +1,4136 @@
+#pragma warning disable 1591
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.1434
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Data.Linq;
+using System.Data.Linq.Mapping;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+
+
+
+public partial class NORTHWND : System.Data.Linq.DataContext
+{
+	
+	private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
+	
+  #region Extensibility Method Definitions
+  partial void OnCreated();
+  partial void InsertCategories(Categories instance);
+  partial void UpdateCategories(Categories instance);
+  partial void DeleteCategories(Categories instance);
+  partial void InsertContacts(Contacts instance);
+  partial void UpdateContacts(Contacts instance);
+  partial void DeleteContacts(Contacts instance);
+  partial void InsertCustomerCustomerDemo(CustomerCustomerDemo instance);
+  partial void UpdateCustomerCustomerDemo(CustomerCustomerDemo instance);
+  partial void DeleteCustomerCustomerDemo(CustomerCustomerDemo instance);
+  partial void InsertCustomerDemographics(CustomerDemographics instance);
+  partial void UpdateCustomerDemographics(CustomerDemographics instance);
+  partial void DeleteCustomerDemographics(CustomerDemographics instance);
+  partial void InsertCustomers(Customers instance);
+  partial void UpdateCustomers(Customers instance);
+  partial void DeleteCustomers(Customers instance);
+  partial void InsertEmployees(Employees instance);
+  partial void UpdateEmployees(Employees instance);
+  partial void DeleteEmployees(Employees instance);
+  partial void InsertEmployeeTerritories(EmployeeTerritories instance);
+  partial void UpdateEmployeeTerritories(EmployeeTerritories instance);
+  partial void DeleteEmployeeTerritories(EmployeeTerritories instance);
+  partial void InsertOrderDetails(OrderDetails instance);
+  partial void UpdateOrderDetails(OrderDetails instance);
+  partial void DeleteOrderDetails(OrderDetails instance);
+  partial void InsertOrders(Orders instance);
+  partial void UpdateOrders(Orders instance);
+  partial void DeleteOrders(Orders instance);
+  partial void InsertProducts(Products instance);
+  partial void UpdateProducts(Products instance);
+  partial void DeleteProducts(Products instance);
+  partial void InsertRegion(Region instance);
+  partial void UpdateRegion(Region instance);
+  partial void DeleteRegion(Region instance);
+  partial void InsertShippers(Shippers instance);
+  partial void UpdateShippers(Shippers instance);
+  partial void DeleteShippers(Shippers instance);
+  partial void InsertSuppliers(Suppliers instance);
+  partial void UpdateSuppliers(Suppliers instance);
+  partial void DeleteSuppliers(Suppliers instance);
+  partial void InsertTerritories(Territories instance);
+  partial void UpdateTerritories(Territories instance);
+  partial void DeleteTerritories(Territories instance);
+  #endregion
+	
+	public NORTHWND(string connection) : 
+			base(connection, mappingSource)
+	{
+		OnCreated();
+	}
+	
+	public NORTHWND(System.Data.IDbConnection connection) : 
+			base(connection, mappingSource)
+	{
+		OnCreated();
+	}
+	
+	public NORTHWND(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) : 
+			base(connection, mappingSource)
+	{
+		OnCreated();
+	}
+	
+	public NORTHWND(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) : 
+			base(connection, mappingSource)
+	{
+		OnCreated();
+	}
+	
+	public System.Data.Linq.Table<Categories> Categories
+	{
+		get
+		{
+			return this.GetTable<Categories>();
+		}
+	}
+	
+	public System.Data.Linq.Table<Contacts> Contacts
+	{
+		get
+		{
+			return this.GetTable<Contacts>();
+		}
+	}
+	
+	public System.Data.Linq.Table<CustomerCustomerDemo> CustomerCustomerDemo
+	{
+		get
+		{
+			return this.GetTable<CustomerCustomerDemo>();
+		}
+	}
+	
+	public System.Data.Linq.Table<CustomerDemographics> CustomerDemographics
+	{
+		get
+		{
+			return this.GetTable<CustomerDemographics>();
+		}
+	}
+	
+	public System.Data.Linq.Table<Customers> Customers
+	{
+		get
+		{
+			return this.GetTable<Customers>();
+		}
+	}
+	
+	public System.Data.Linq.Table<Employees> Employees
+	{
+		get
+		{
+			return this.GetTable<Employees>();
+		}
+	}
+	
+	public System.Data.Linq.Table<EmployeeTerritories> EmployeeTerritories
+	{
+		get
+		{
+			return this.GetTable<EmployeeTerritories>();
+		}
+	}
+	
+	public System.Data.Linq.Table<OrderDetails> OrderDetails
+	{
+		get
+		{
+			return this.GetTable<OrderDetails>();
+		}
+	}
+	
+	public System.Data.Linq.Table<Orders> Orders
+	{
+		get
+		{
+			return this.GetTable<Orders>();
+		}
+	}
+	
+	public System.Data.Linq.Table<Products> Products
+	{
+		get
+		{
+			return this.GetTable<Products>();
+		}
+	}
+	
+	public System.Data.Linq.Table<Region> Region
+	{
+		get
+		{
+			return this.GetTable<Region>();
+		}
+	}
+	
+	public System.Data.Linq.Table<Shippers> Shippers
+	{
+		get
+		{
+			return this.GetTable<Shippers>();
+		}
+	}
+	
+	public System.Data.Linq.Table<Suppliers> Suppliers
+	{
+		get
+		{
+			return this.GetTable<Suppliers>();
+		}
+	}
+	
+	public System.Data.Linq.Table<Territories> Territories
+	{
+		get
+		{
+			return this.GetTable<Territories>();
+		}
+	}
+}
+
+[Table(Name="dbo.Categories")]
+public partial class Categories : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private int _CategoryID;
+	
+	private string _CategoryName;
+	
+	private string _Description;
+	
+	private System.Data.Linq.Binary _Picture;
+	
+	private EntitySet<Products> _Products;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnCategoryIDChanging(int value);
+    partial void OnCategoryIDChanged();
+    partial void OnCategoryNameChanging(string value);
+    partial void OnCategoryNameChanged();
+    partial void OnDescriptionChanging(string value);
+    partial void OnDescriptionChanged();
+    partial void OnPictureChanging(System.Data.Linq.Binary value);
+    partial void OnPictureChanged();
+    #endregion
+	
+	public Categories()
+	{
+		this._Products = new EntitySet<Products>(new Action<Products>(this.attach_Products), new Action<Products>(this.detach_Products));
+		OnCreated();
+	}
+	
+	[Column(Storage="_CategoryID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+	public int CategoryID
+	{
+		get
+		{
+			return this._CategoryID;
+		}
+		set
+		{
+			if ((this._CategoryID != value))
+			{
+				this.OnCategoryIDChanging(value);
+				this.SendPropertyChanging();
+				this._CategoryID = value;
+				this.SendPropertyChanged("CategoryID");
+				this.OnCategoryIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_CategoryName", DbType="NVarChar(15) NOT NULL", CanBeNull=false)]
+	public string CategoryName
+	{
+		get
+		{
+			return this._CategoryName;
+		}
+		set
+		{
+			if ((this._CategoryName != value))
+			{
+				this.OnCategoryNameChanging(value);
+				this.SendPropertyChanging();
+				this._CategoryName = value;
+				this.SendPropertyChanged("CategoryName");
+				this.OnCategoryNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Description", DbType="NText", UpdateCheck=UpdateCheck.Never)]
+	public string Description
+	{
+		get
+		{
+			return this._Description;
+		}
+		set
+		{
+			if ((this._Description != value))
+			{
+				this.OnDescriptionChanging(value);
+				this.SendPropertyChanging();
+				this._Description = value;
+				this.SendPropertyChanged("Description");
+				this.OnDescriptionChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Picture", DbType="Image", CanBeNull=true, UpdateCheck=UpdateCheck.Never)]
+	public System.Data.Linq.Binary Picture
+	{
+		get
+		{
+			return this._Picture;
+		}
+		set
+		{
+			if ((this._Picture != value))
+			{
+				this.OnPictureChanging(value);
+				this.SendPropertyChanging();
+				this._Picture = value;
+				this.SendPropertyChanged("Picture");
+				this.OnPictureChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_Products_Categories", Storage="_Products", OtherKey="CategoryID", DeleteRule="NO ACTION")]
+	public EntitySet<Products> Products
+	{
+		get
+		{
+			return this._Products;
+		}
+		set
+		{
+			this._Products.Assign(value);
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+	
+	private void attach_Products(Products entity)
+	{
+		this.SendPropertyChanging();
+		entity.Categories = this;
+	}
+	
+	private void detach_Products(Products entity)
+	{
+		this.SendPropertyChanging();
+		entity.Categories = null;
+	}
+}
+
+[Table(Name="dbo.Contacts")]
+public partial class Contacts : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private int _ContactID;
+	
+	private string _ContactType;
+	
+	private string _CompanyName;
+	
+	private string _ContactName;
+	
+	private string _ContactTitle;
+	
+	private string _Address;
+	
+	private string _City;
+	
+	private string _Region;
+	
+	private string _PostalCode;
+	
+	private string _Country;
+	
+	private string _Phone;
+	
+	private string _Extension;
+	
+	private string _Fax;
+	
+	private string _HomePage;
+	
+	private string _PhotoPath;
+	
+	private System.Data.Linq.Binary _Photo;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnContactIDChanging(int value);
+    partial void OnContactIDChanged();
+    partial void OnContactTypeChanging(string value);
+    partial void OnContactTypeChanged();
+    partial void OnCompanyNameChanging(string value);
+    partial void OnCompanyNameChanged();
+    partial void OnContactNameChanging(string value);
+    partial void OnContactNameChanged();
+    partial void OnContactTitleChanging(string value);
+    partial void OnContactTitleChanged();
+    partial void OnAddressChanging(string value);
+    partial void OnAddressChanged();
+    partial void OnCityChanging(string value);
+    partial void OnCityChanged();
+    partial void OnRegionChanging(string value);
+    partial void OnRegionChanged();
+    partial void OnPostalCodeChanging(string value);
+    partial void OnPostalCodeChanged();
+    partial void OnCountryChanging(string value);
+    partial void OnCountryChanged();
+    partial void OnPhoneChanging(string value);
+    partial void OnPhoneChanged();
+    partial void OnExtensionChanging(string value);
+    partial void OnExtensionChanged();
+    partial void OnFaxChanging(string value);
+    partial void OnFaxChanged();
+    partial void OnHomePageChanging(string value);
+    partial void OnHomePageChanged();
+    partial void OnPhotoPathChanging(string value);
+    partial void OnPhotoPathChanged();
+    partial void OnPhotoChanging(System.Data.Linq.Binary value);
+    partial void OnPhotoChanged();
+    #endregion
+	
+	public Contacts()
+	{
+		OnCreated();
+	}
+	
+	[Column(Storage="_ContactID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+	public int ContactID
+	{
+		get
+		{
+			return this._ContactID;
+		}
+		set
+		{
+			if ((this._ContactID != value))
+			{
+				this.OnContactIDChanging(value);
+				this.SendPropertyChanging();
+				this._ContactID = value;
+				this.SendPropertyChanged("ContactID");
+				this.OnContactIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ContactType", DbType="NVarChar(50)")]
+	public string ContactType
+	{
+		get
+		{
+			return this._ContactType;
+		}
+		set
+		{
+			if ((this._ContactType != value))
+			{
+				this.OnContactTypeChanging(value);
+				this.SendPropertyChanging();
+				this._ContactType = value;
+				this.SendPropertyChanged("ContactType");
+				this.OnContactTypeChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+	public string CompanyName
+	{
+		get
+		{
+			return this._CompanyName;
+		}
+		set
+		{
+			if ((this._CompanyName != value))
+			{
+				this.OnCompanyNameChanging(value);
+				this.SendPropertyChanging();
+				this._CompanyName = value;
+				this.SendPropertyChanged("CompanyName");
+				this.OnCompanyNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ContactName", DbType="NVarChar(30)")]
+	public string ContactName
+	{
+		get
+		{
+			return this._ContactName;
+		}
+		set
+		{
+			if ((this._ContactName != value))
+			{
+				this.OnContactNameChanging(value);
+				this.SendPropertyChanging();
+				this._ContactName = value;
+				this.SendPropertyChanged("ContactName");
+				this.OnContactNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ContactTitle", DbType="NVarChar(30)")]
+	public string ContactTitle
+	{
+		get
+		{
+			return this._ContactTitle;
+		}
+		set
+		{
+			if ((this._ContactTitle != value))
+			{
+				this.OnContactTitleChanging(value);
+				this.SendPropertyChanging();
+				this._ContactTitle = value;
+				this.SendPropertyChanged("ContactTitle");
+				this.OnContactTitleChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Address", DbType="NVarChar(60)")]
+	public string Address
+	{
+		get
+		{
+			return this._Address;
+		}
+		set
+		{
+			if ((this._Address != value))
+			{
+				this.OnAddressChanging(value);
+				this.SendPropertyChanging();
+				this._Address = value;
+				this.SendPropertyChanged("Address");
+				this.OnAddressChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_City", DbType="NVarChar(15)")]
+	public string City
+	{
+		get
+		{
+			return this._City;
+		}
+		set
+		{
+			if ((this._City != value))
+			{
+				this.OnCityChanging(value);
+				this.SendPropertyChanging();
+				this._City = value;
+				this.SendPropertyChanged("City");
+				this.OnCityChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Region", DbType="NVarChar(15)")]
+	public string Region
+	{
+		get
+		{
+			return this._Region;
+		}
+		set
+		{
+			if ((this._Region != value))
+			{
+				this.OnRegionChanging(value);
+				this.SendPropertyChanging();
+				this._Region = value;
+				this.SendPropertyChanged("Region");
+				this.OnRegionChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_PostalCode", DbType="NVarChar(10)")]
+	public string PostalCode
+	{
+		get
+		{
+			return this._PostalCode;
+		}
+		set
+		{
+			if ((this._PostalCode != value))
+			{
+				this.OnPostalCodeChanging(value);
+				this.SendPropertyChanging();
+				this._PostalCode = value;
+				this.SendPropertyChanged("PostalCode");
+				this.OnPostalCodeChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Country", DbType="NVarChar(15)")]
+	public string Country
+	{
+		get
+		{
+			return this._Country;
+		}
+		set
+		{
+			if ((this._Country != value))
+			{
+				this.OnCountryChanging(value);
+				this.SendPropertyChanging();
+				this._Country = value;
+				this.SendPropertyChanged("Country");
+				this.OnCountryChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Phone", DbType="NVarChar(24)")]
+	public string Phone
+	{
+		get
+		{
+			return this._Phone;
+		}
+		set
+		{
+			if ((this._Phone != value))
+			{
+				this.OnPhoneChanging(value);
+				this.SendPropertyChanging();
+				this._Phone = value;
+				this.SendPropertyChanged("Phone");
+				this.OnPhoneChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Extension", DbType="NVarChar(4)")]
+	public string Extension
+	{
+		get
+		{
+			return this._Extension;
+		}
+		set
+		{
+			if ((this._Extension != value))
+			{
+				this.OnExtensionChanging(value);
+				this.SendPropertyChanging();
+				this._Extension = value;
+				this.SendPropertyChanged("Extension");
+				this.OnExtensionChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Fax", DbType="NVarChar(24)")]
+	public string Fax
+	{
+		get
+		{
+			return this._Fax;
+		}
+		set
+		{
+			if ((this._Fax != value))
+			{
+				this.OnFaxChanging(value);
+				this.SendPropertyChanging();
+				this._Fax = value;
+				this.SendPropertyChanged("Fax");
+				this.OnFaxChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_HomePage", DbType="NText", UpdateCheck=UpdateCheck.Never)]
+	public string HomePage
+	{
+		get
+		{
+			return this._HomePage;
+		}
+		set
+		{
+			if ((this._HomePage != value))
+			{
+				this.OnHomePageChanging(value);
+				this.SendPropertyChanging();
+				this._HomePage = value;
+				this.SendPropertyChanged("HomePage");
+				this.OnHomePageChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_PhotoPath", DbType="NVarChar(255)")]
+	public string PhotoPath
+	{
+		get
+		{
+			return this._PhotoPath;
+		}
+		set
+		{
+			if ((this._PhotoPath != value))
+			{
+				this.OnPhotoPathChanging(value);
+				this.SendPropertyChanging();
+				this._PhotoPath = value;
+				this.SendPropertyChanged("PhotoPath");
+				this.OnPhotoPathChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Photo", DbType="Image", CanBeNull=true, UpdateCheck=UpdateCheck.Never)]
+	public System.Data.Linq.Binary Photo
+	{
+		get
+		{
+			return this._Photo;
+		}
+		set
+		{
+			if ((this._Photo != value))
+			{
+				this.OnPhotoChanging(value);
+				this.SendPropertyChanging();
+				this._Photo = value;
+				this.SendPropertyChanged("Photo");
+				this.OnPhotoChanged();
+			}
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+}
+
+[Table(Name="dbo.CustomerCustomerDemo")]
+public partial class CustomerCustomerDemo : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private string _CustomerID;
+	
+	private string _CustomerTypeID;
+	
+	private EntityRef<CustomerDemographics> _CustomerDemographics;
+	
+	private EntityRef<Customers> _Customers;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnCustomerIDChanging(string value);
+    partial void OnCustomerIDChanged();
+    partial void OnCustomerTypeIDChanging(string value);
+    partial void OnCustomerTypeIDChanged();
+    #endregion
+	
+	public CustomerCustomerDemo()
+	{
+		this._CustomerDemographics = default(EntityRef<CustomerDemographics>);
+		this._Customers = default(EntityRef<Customers>);
+		OnCreated();
+	}
+	
+	[Column(Storage="_CustomerID", DbType="NChar(5) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+	public string CustomerID
+	{
+		get
+		{
+			return this._CustomerID;
+		}
+		set
+		{
+			if ((this._CustomerID != value))
+			{
+				if (this._Customers.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnCustomerIDChanging(value);
+				this.SendPropertyChanging();
+				this._CustomerID = value;
+				this.SendPropertyChanged("CustomerID");
+				this.OnCustomerIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_CustomerTypeID", DbType="NChar(10) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+	public string CustomerTypeID
+	{
+		get
+		{
+			return this._CustomerTypeID;
+		}
+		set
+		{
+			if ((this._CustomerTypeID != value))
+			{
+				if (this._CustomerDemographics.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnCustomerTypeIDChanging(value);
+				this.SendPropertyChanging();
+				this._CustomerTypeID = value;
+				this.SendPropertyChanged("CustomerTypeID");
+				this.OnCustomerTypeIDChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_CustomerCustomerDemo", Storage="_CustomerDemographics", ThisKey="CustomerTypeID", IsForeignKey=true)]
+	public CustomerDemographics CustomerDemographics
+	{
+		get
+		{
+			return this._CustomerDemographics.Entity;
+		}
+		set
+		{
+			CustomerDemographics previousValue = this._CustomerDemographics.Entity;
+			if (((previousValue != value) 
+						|| (this._CustomerDemographics.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._CustomerDemographics.Entity = null;
+					previousValue.CustomerCustomerDemo.Remove(this);
+				}
+				this._CustomerDemographics.Entity = value;
+				if ((value != null))
+				{
+					value.CustomerCustomerDemo.Add(this);
+					this._CustomerTypeID = value.CustomerTypeID;
+				}
+				else
+				{
+					this._CustomerTypeID = default(string);
+				}
+				this.SendPropertyChanged("CustomerDemographics");
+			}
+		}
+	}
+	
+	[Association(Name="FK_CustomerCustomerDemo_Customers", Storage="_Customers", ThisKey="CustomerID", IsForeignKey=true)]
+	public Customers Customers
+	{
+		get
+		{
+			return this._Customers.Entity;
+		}
+		set
+		{
+			Customers previousValue = this._Customers.Entity;
+			if (((previousValue != value) 
+						|| (this._Customers.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Customers.Entity = null;
+					previousValue.CustomerCustomerDemo.Remove(this);
+				}
+				this._Customers.Entity = value;
+				if ((value != null))
+				{
+					value.CustomerCustomerDemo.Add(this);
+					this._CustomerID = value.CustomerID;
+				}
+				else
+				{
+					this._CustomerID = default(string);
+				}
+				this.SendPropertyChanged("Customers");
+			}
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+}
+
+[Table(Name="dbo.CustomerDemographics")]
+public partial class CustomerDemographics : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private string _CustomerTypeID;
+	
+	private string _CustomerDesc;
+	
+	private EntitySet<CustomerCustomerDemo> _CustomerCustomerDemo;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnCustomerTypeIDChanging(string value);
+    partial void OnCustomerTypeIDChanged();
+    partial void OnCustomerDescChanging(string value);
+    partial void OnCustomerDescChanged();
+    #endregion
+	
+	public CustomerDemographics()
+	{
+		this._CustomerCustomerDemo = new EntitySet<CustomerCustomerDemo>(new Action<CustomerCustomerDemo>(this.attach_CustomerCustomerDemo), new Action<CustomerCustomerDemo>(this.detach_CustomerCustomerDemo));
+		OnCreated();
+	}
+	
+	[Column(Storage="_CustomerTypeID", DbType="NChar(10) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+	public string CustomerTypeID
+	{
+		get
+		{
+			return this._CustomerTypeID;
+		}
+		set
+		{
+			if ((this._CustomerTypeID != value))
+			{
+				this.OnCustomerTypeIDChanging(value);
+				this.SendPropertyChanging();
+				this._CustomerTypeID = value;
+				this.SendPropertyChanged("CustomerTypeID");
+				this.OnCustomerTypeIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_CustomerDesc", DbType="NText", UpdateCheck=UpdateCheck.Never)]
+	public string CustomerDesc
+	{
+		get
+		{
+			return this._CustomerDesc;
+		}
+		set
+		{
+			if ((this._CustomerDesc != value))
+			{
+				this.OnCustomerDescChanging(value);
+				this.SendPropertyChanging();
+				this._CustomerDesc = value;
+				this.SendPropertyChanged("CustomerDesc");
+				this.OnCustomerDescChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_CustomerCustomerDemo", Storage="_CustomerCustomerDemo", OtherKey="CustomerTypeID", DeleteRule="NO ACTION")]
+	public EntitySet<CustomerCustomerDemo> CustomerCustomerDemo
+	{
+		get
+		{
+			return this._CustomerCustomerDemo;
+		}
+		set
+		{
+			this._CustomerCustomerDemo.Assign(value);
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+	
+	private void attach_CustomerCustomerDemo(CustomerCustomerDemo entity)
+	{
+		this.SendPropertyChanging();
+		entity.CustomerDemographics = this;
+	}
+	
+	private void detach_CustomerCustomerDemo(CustomerCustomerDemo entity)
+	{
+		this.SendPropertyChanging();
+		entity.CustomerDemographics = null;
+	}
+}
+
+[Table(Name="dbo.Customers")]
+public partial class Customers : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private string _CustomerID;
+	
+	private string _CompanyName;
+	
+	private string _ContactName;
+	
+	private string _ContactTitle;
+	
+	private string _Address;
+	
+	private string _City;
+	
+	private string _Region;
+	
+	private string _PostalCode;
+	
+	private string _Country;
+	
+	private string _Phone;
+	
+	private string _Fax;
+	
+	private EntitySet<CustomerCustomerDemo> _CustomerCustomerDemo;
+	
+	private EntitySet<Orders> _Orders;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnCustomerIDChanging(string value);
+    partial void OnCustomerIDChanged();
+    partial void OnCompanyNameChanging(string value);
+    partial void OnCompanyNameChanged();
+    partial void OnContactNameChanging(string value);
+    partial void OnContactNameChanged();
+    partial void OnContactTitleChanging(string value);
+    partial void OnContactTitleChanged();
+    partial void OnAddressChanging(string value);
+    partial void OnAddressChanged();
+    partial void OnCityChanging(string value);
+    partial void OnCityChanged();
+    partial void OnRegionChanging(string value);
+    partial void OnRegionChanged();
+    partial void OnPostalCodeChanging(string value);
+    partial void OnPostalCodeChanged();
+    partial void OnCountryChanging(string value);
+    partial void OnCountryChanged();
+    partial void OnPhoneChanging(string value);
+    partial void OnPhoneChanged();
+    partial void OnFaxChanging(string value);
+    partial void OnFaxChanged();
+    #endregion
+	
+	public Customers()
+	{
+		this._CustomerCustomerDemo = new EntitySet<CustomerCustomerDemo>(new Action<CustomerCustomerDemo>(this.attach_CustomerCustomerDemo), new Action<CustomerCustomerDemo>(this.detach_CustomerCustomerDemo));
+		this._Orders = new EntitySet<Orders>(new Action<Orders>(this.attach_Orders), new Action<Orders>(this.detach_Orders));
+		OnCreated();
+	}
+	
+	[Column(Storage="_CustomerID", DbType="NChar(5) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+	public string CustomerID
+	{
+		get
+		{
+			return this._CustomerID;
+		}
+		set
+		{
+			if ((this._CustomerID != value))
+			{
+				this.OnCustomerIDChanging(value);
+				this.SendPropertyChanging();
+				this._CustomerID = value;
+				this.SendPropertyChanged("CustomerID");
+				this.OnCustomerIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+	public string CompanyName
+	{
+		get
+		{
+			return this._CompanyName;
+		}
+		set
+		{
+			if ((this._CompanyName != value))
+			{
+				this.OnCompanyNameChanging(value);
+				this.SendPropertyChanging();
+				this._CompanyName = value;
+				this.SendPropertyChanged("CompanyName");
+				this.OnCompanyNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ContactName", DbType="NVarChar(30)")]
+	public string ContactName
+	{
+		get
+		{
+			return this._ContactName;
+		}
+		set
+		{
+			if ((this._ContactName != value))
+			{
+				this.OnContactNameChanging(value);
+				this.SendPropertyChanging();
+				this._ContactName = value;
+				this.SendPropertyChanged("ContactName");
+				this.OnContactNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ContactTitle", DbType="NVarChar(30)")]
+	public string ContactTitle
+	{
+		get
+		{
+			return this._ContactTitle;
+		}
+		set
+		{
+			if ((this._ContactTitle != value))
+			{
+				this.OnContactTitleChanging(value);
+				this.SendPropertyChanging();
+				this._ContactTitle = value;
+				this.SendPropertyChanged("ContactTitle");
+				this.OnContactTitleChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Address", DbType="NVarChar(60)")]
+	public string Address
+	{
+		get
+		{
+			return this._Address;
+		}
+		set
+		{
+			if ((this._Address != value))
+			{
+				this.OnAddressChanging(value);
+				this.SendPropertyChanging();
+				this._Address = value;
+				this.SendPropertyChanged("Address");
+				this.OnAddressChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_City", DbType="NVarChar(15)")]
+	public string City
+	{
+		get
+		{
+			return this._City;
+		}
+		set
+		{
+			if ((this._City != value))
+			{
+				this.OnCityChanging(value);
+				this.SendPropertyChanging();
+				this._City = value;
+				this.SendPropertyChanged("City");
+				this.OnCityChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Region", DbType="NVarChar(15)")]
+	public string Region
+	{
+		get
+		{
+			return this._Region;
+		}
+		set
+		{
+			if ((this._Region != value))
+			{
+				this.OnRegionChanging(value);
+				this.SendPropertyChanging();
+				this._Region = value;
+				this.SendPropertyChanged("Region");
+				this.OnRegionChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_PostalCode", DbType="NVarChar(10)")]
+	public string PostalCode
+	{
+		get
+		{
+			return this._PostalCode;
+		}
+		set
+		{
+			if ((this._PostalCode != value))
+			{
+				this.OnPostalCodeChanging(value);
+				this.SendPropertyChanging();
+				this._PostalCode = value;
+				this.SendPropertyChanged("PostalCode");
+				this.OnPostalCodeChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Country", DbType="NVarChar(15)")]
+	public string Country
+	{
+		get
+		{
+			return this._Country;
+		}
+		set
+		{
+			if ((this._Country != value))
+			{
+				this.OnCountryChanging(value);
+				this.SendPropertyChanging();
+				this._Country = value;
+				this.SendPropertyChanged("Country");
+				this.OnCountryChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Phone", DbType="NVarChar(24)")]
+	public string Phone
+	{
+		get
+		{
+			return this._Phone;
+		}
+		set
+		{
+			if ((this._Phone != value))
+			{
+				this.OnPhoneChanging(value);
+				this.SendPropertyChanging();
+				this._Phone = value;
+				this.SendPropertyChanged("Phone");
+				this.OnPhoneChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Fax", DbType="NVarChar(24)")]
+	public string Fax
+	{
+		get
+		{
+			return this._Fax;
+		}
+		set
+		{
+			if ((this._Fax != value))
+			{
+				this.OnFaxChanging(value);
+				this.SendPropertyChanging();
+				this._Fax = value;
+				this.SendPropertyChanged("Fax");
+				this.OnFaxChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_CustomerCustomerDemo_Customers", Storage="_CustomerCustomerDemo", OtherKey="CustomerID", DeleteRule="NO ACTION")]
+	public EntitySet<CustomerCustomerDemo> CustomerCustomerDemo
+	{
+		get
+		{
+			return this._CustomerCustomerDemo;
+		}
+		set
+		{
+			this._CustomerCustomerDemo.Assign(value);
+		}
+	}
+	
+	[Association(Name="FK_Orders_Customers", Storage="_Orders", OtherKey="CustomerID", DeleteRule="NO ACTION")]
+	public EntitySet<Orders> Orders
+	{
+		get
+		{
+			return this._Orders;
+		}
+		set
+		{
+			this._Orders.Assign(value);
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+	
+	private void attach_CustomerCustomerDemo(CustomerCustomerDemo entity)
+	{
+		this.SendPropertyChanging();
+		entity.Customers = this;
+	}
+	
+	private void detach_CustomerCustomerDemo(CustomerCustomerDemo entity)
+	{
+		this.SendPropertyChanging();
+		entity.Customers = null;
+	}
+	
+	private void attach_Orders(Orders entity)
+	{
+		this.SendPropertyChanging();
+		entity.Customers = this;
+	}
+	
+	private void detach_Orders(Orders entity)
+	{
+		this.SendPropertyChanging();
+		entity.Customers = null;
+	}
+}
+
+[Table(Name="dbo.Employees")]
+public partial class Employees : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private int _EmployeeID;
+	
+	private string _LastName;
+	
+	private string _FirstName;
+	
+	private string _Title;
+	
+	private string _TitleOfCourtesy;
+	
+	private System.Nullable<System.DateTime> _BirthDate;
+	
+	private System.Nullable<System.DateTime> _HireDate;
+	
+	private string _Address;
+	
+	private string _City;
+	
+	private string _Region;
+	
+	private string _PostalCode;
+	
+	private string _Country;
+	
+	private string _HomePhone;
+	
+	private string _Extension;
+	
+	private System.Data.Linq.Binary _Photo;
+	
+	private string _Notes;
+	
+	private System.Nullable<int> _ReportsTo;
+	
+	private string _PhotoPath;
+	
+	private EntityRef<Employees> _ReportsToEmployees;
+	
+	private EntitySet<Employees> _Employee;
+	
+	private EntitySet<EmployeeTerritories> _EmployeeTerritories;
+	
+	private EntitySet<Orders> _Orders;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnEmployeeIDChanging(int value);
+    partial void OnEmployeeIDChanged();
+    partial void OnLastNameChanging(string value);
+    partial void OnLastNameChanged();
+    partial void OnFirstNameChanging(string value);
+    partial void OnFirstNameChanged();
+    partial void OnTitleChanging(string value);
+    partial void OnTitleChanged();
+    partial void OnTitleOfCourtesyChanging(string value);
+    partial void OnTitleOfCourtesyChanged();
+    partial void OnBirthDateChanging(System.Nullable<System.DateTime> value);
+    partial void OnBirthDateChanged();
+    partial void OnHireDateChanging(System.Nullable<System.DateTime> value);
+    partial void OnHireDateChanged();
+    partial void OnAddressChanging(string value);
+    partial void OnAddressChanged();
+    partial void OnCityChanging(string value);
+    partial void OnCityChanged();
+    partial void OnRegionChanging(string value);
+    partial void OnRegionChanged();
+    partial void OnPostalCodeChanging(string value);
+    partial void OnPostalCodeChanged();
+    partial void OnCountryChanging(string value);
+    partial void OnCountryChanged();
+    partial void OnHomePhoneChanging(string value);
+    partial void OnHomePhoneChanged();
+    partial void OnExtensionChanging(string value);
+    partial void OnExtensionChanged();
+    partial void OnPhotoChanging(System.Data.Linq.Binary value);
+    partial void OnPhotoChanged();
+    partial void OnNotesChanging(string value);
+    partial void OnNotesChanged();
+    partial void OnReportsToChanging(System.Nullable<int> value);
+    partial void OnReportsToChanged();
+    partial void OnPhotoPathChanging(string value);
+    partial void OnPhotoPathChanged();
+    #endregion
+	
+	public Employees()
+	{
+		this._ReportsToEmployees = default(EntityRef<Employees>);
+		this._Employee = new EntitySet<Employees>(new Action<Employees>(this.attach_Employee), new Action<Employees>(this.detach_Employee));
+		this._EmployeeTerritories = new EntitySet<EmployeeTerritories>(new Action<EmployeeTerritories>(this.attach_EmployeeTerritories), new Action<EmployeeTerritories>(this.detach_EmployeeTerritories));
+		this._Orders = new EntitySet<Orders>(new Action<Orders>(this.attach_Orders), new Action<Orders>(this.detach_Orders));
+		OnCreated();
+	}
+	
+	[Column(Storage="_EmployeeID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+	public int EmployeeID
+	{
+		get
+		{
+			return this._EmployeeID;
+		}
+		set
+		{
+			if ((this._EmployeeID != value))
+			{
+				this.OnEmployeeIDChanging(value);
+				this.SendPropertyChanging();
+				this._EmployeeID = value;
+				this.SendPropertyChanged("EmployeeID");
+				this.OnEmployeeIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_LastName", DbType="NVarChar(20) NOT NULL", CanBeNull=false)]
+	public string LastName
+	{
+		get
+		{
+			return this._LastName;
+		}
+		set
+		{
+			if ((this._LastName != value))
+			{
+				this.OnLastNameChanging(value);
+				this.SendPropertyChanging();
+				this._LastName = value;
+				this.SendPropertyChanged("LastName");
+				this.OnLastNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_FirstName", DbType="NVarChar(10) NOT NULL", CanBeNull=false)]
+	public string FirstName
+	{
+		get
+		{
+			return this._FirstName;
+		}
+		set
+		{
+			if ((this._FirstName != value))
+			{
+				this.OnFirstNameChanging(value);
+				this.SendPropertyChanging();
+				this._FirstName = value;
+				this.SendPropertyChanged("FirstName");
+				this.OnFirstNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Title", DbType="NVarChar(30)")]
+	public string Title
+	{
+		get
+		{
+			return this._Title;
+		}
+		set
+		{
+			if ((this._Title != value))
+			{
+				this.OnTitleChanging(value);
+				this.SendPropertyChanging();
+				this._Title = value;
+				this.SendPropertyChanged("Title");
+				this.OnTitleChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_TitleOfCourtesy", DbType="NVarChar(25)")]
+	public string TitleOfCourtesy
+	{
+		get
+		{
+			return this._TitleOfCourtesy;
+		}
+		set
+		{
+			if ((this._TitleOfCourtesy != value))
+			{
+				this.OnTitleOfCourtesyChanging(value);
+				this.SendPropertyChanging();
+				this._TitleOfCourtesy = value;
+				this.SendPropertyChanged("TitleOfCourtesy");
+				this.OnTitleOfCourtesyChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_BirthDate", DbType="DateTime")]
+	public System.Nullable<System.DateTime> BirthDate
+	{
+		get
+		{
+			return this._BirthDate;
+		}
+		set
+		{
+			if ((this._BirthDate != value))
+			{
+				this.OnBirthDateChanging(value);
+				this.SendPropertyChanging();
+				this._BirthDate = value;
+				this.SendPropertyChanged("BirthDate");
+				this.OnBirthDateChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_HireDate", DbType="DateTime")]
+	public System.Nullable<System.DateTime> HireDate
+	{
+		get
+		{
+			return this._HireDate;
+		}
+		set
+		{
+			if ((this._HireDate != value))
+			{
+				this.OnHireDateChanging(value);
+				this.SendPropertyChanging();
+				this._HireDate = value;
+				this.SendPropertyChanged("HireDate");
+				this.OnHireDateChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Address", DbType="NVarChar(60)")]
+	public string Address
+	{
+		get
+		{
+			return this._Address;
+		}
+		set
+		{
+			if ((this._Address != value))
+			{
+				this.OnAddressChanging(value);
+				this.SendPropertyChanging();
+				this._Address = value;
+				this.SendPropertyChanged("Address");
+				this.OnAddressChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_City", DbType="NVarChar(15)")]
+	public string City
+	{
+		get
+		{
+			return this._City;
+		}
+		set
+		{
+			if ((this._City != value))
+			{
+				this.OnCityChanging(value);
+				this.SendPropertyChanging();
+				this._City = value;
+				this.SendPropertyChanged("City");
+				this.OnCityChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Region", DbType="NVarChar(15)")]
+	public string Region
+	{
+		get
+		{
+			return this._Region;
+		}
+		set
+		{
+			if ((this._Region != value))
+			{
+				this.OnRegionChanging(value);
+				this.SendPropertyChanging();
+				this._Region = value;
+				this.SendPropertyChanged("Region");
+				this.OnRegionChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_PostalCode", DbType="NVarChar(10)")]
+	public string PostalCode
+	{
+		get
+		{
+			return this._PostalCode;
+		}
+		set
+		{
+			if ((this._PostalCode != value))
+			{
+				this.OnPostalCodeChanging(value);
+				this.SendPropertyChanging();
+				this._PostalCode = value;
+				this.SendPropertyChanged("PostalCode");
+				this.OnPostalCodeChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Country", DbType="NVarChar(15)")]
+	public string Country
+	{
+		get
+		{
+			return this._Country;
+		}
+		set
+		{
+			if ((this._Country != value))
+			{
+				this.OnCountryChanging(value);
+				this.SendPropertyChanging();
+				this._Country = value;
+				this.SendPropertyChanged("Country");
+				this.OnCountryChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_HomePhone", DbType="NVarChar(24)")]
+	public string HomePhone
+	{
+		get
+		{
+			return this._HomePhone;
+		}
+		set
+		{
+			if ((this._HomePhone != value))
+			{
+				this.OnHomePhoneChanging(value);
+				this.SendPropertyChanging();
+				this._HomePhone = value;
+				this.SendPropertyChanged("HomePhone");
+				this.OnHomePhoneChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Extension", DbType="NVarChar(4)")]
+	public string Extension
+	{
+		get
+		{
+			return this._Extension;
+		}
+		set
+		{
+			if ((this._Extension != value))
+			{
+				this.OnExtensionChanging(value);
+				this.SendPropertyChanging();
+				this._Extension = value;
+				this.SendPropertyChanged("Extension");
+				this.OnExtensionChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Photo", DbType="Image", CanBeNull=true, UpdateCheck=UpdateCheck.Never)]
+	public System.Data.Linq.Binary Photo
+	{
+		get
+		{
+			return this._Photo;
+		}
+		set
+		{
+			if ((this._Photo != value))
+			{
+				this.OnPhotoChanging(value);
+				this.SendPropertyChanging();
+				this._Photo = value;
+				this.SendPropertyChanged("Photo");
+				this.OnPhotoChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Notes", DbType="NText", UpdateCheck=UpdateCheck.Never)]
+	public string Notes
+	{
+		get
+		{
+			return this._Notes;
+		}
+		set
+		{
+			if ((this._Notes != value))
+			{
+				this.OnNotesChanging(value);
+				this.SendPropertyChanging();
+				this._Notes = value;
+				this.SendPropertyChanged("Notes");
+				this.OnNotesChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ReportsTo", DbType="Int")]
+	public System.Nullable<int> ReportsTo
+	{
+		get
+		{
+			return this._ReportsTo;
+		}
+		set
+		{
+			if ((this._ReportsTo != value))
+			{
+				if (this._ReportsToEmployees.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnReportsToChanging(value);
+				this.SendPropertyChanging();
+				this._ReportsTo = value;
+				this.SendPropertyChanged("ReportsTo");
+				this.OnReportsToChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_PhotoPath", DbType="NVarChar(255)")]
+	public string PhotoPath
+	{
+		get
+		{
+			return this._PhotoPath;
+		}
+		set
+		{
+			if ((this._PhotoPath != value))
+			{
+				this.OnPhotoPathChanging(value);
+				this.SendPropertyChanging();
+				this._PhotoPath = value;
+				this.SendPropertyChanged("PhotoPath");
+				this.OnPhotoPathChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_Employees_Employees", Storage="_ReportsToEmployees", ThisKey="ReportsTo", IsForeignKey=true)]
+	public Employees ReportsToEmployees
+	{
+		get
+		{
+			return this._ReportsToEmployees.Entity;
+		}
+		set
+		{
+			Employees previousValue = this._ReportsToEmployees.Entity;
+			if (((previousValue != value) 
+						|| (this._ReportsToEmployees.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._ReportsToEmployees.Entity = null;
+					previousValue.Employee.Remove(this);
+				}
+				this._ReportsToEmployees.Entity = value;
+				if ((value != null))
+				{
+					value.Employee.Add(this);
+					this._ReportsTo = value.EmployeeID;
+				}
+				else
+				{
+					this._ReportsTo = default(Nullable<int>);
+				}
+				this.SendPropertyChanged("ReportsToEmployees");
+			}
+		}
+	}
+	
+	[Association(Name="FK_Employees_Employees", Storage="_Employee", OtherKey="ReportsTo", DeleteRule="NO ACTION")]
+	public EntitySet<Employees> Employee
+	{
+		get
+		{
+			return this._Employee;
+		}
+		set
+		{
+			this._Employee.Assign(value);
+		}
+	}
+	
+	[Association(Name="FK_EmployeeTerritories_Employees", Storage="_EmployeeTerritories", OtherKey="EmployeeID", DeleteRule="NO ACTION")]
+	public EntitySet<EmployeeTerritories> EmployeeTerritories
+	{
+		get
+		{
+			return this._EmployeeTerritories;
+		}
+		set
+		{
+			this._EmployeeTerritories.Assign(value);
+		}
+	}
+	
+	[Association(Name="FK_Orders_Employees", Storage="_Orders", OtherKey="EmployeeID", DeleteRule="NO ACTION")]
+	public EntitySet<Orders> Orders
+	{
+		get
+		{
+			return this._Orders;
+		}
+		set
+		{
+			this._Orders.Assign(value);
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+	
+	private void attach_Employee(Employees entity)
+	{
+		this.SendPropertyChanging();
+		entity.ReportsToEmployees = this;
+	}
+	
+	private void detach_Employee(Employees entity)
+	{
+		this.SendPropertyChanging();
+		entity.ReportsToEmployees = null;
+	}
+	
+	private void attach_EmployeeTerritories(EmployeeTerritories entity)
+	{
+		this.SendPropertyChanging();
+		entity.Employees = this;
+	}
+	
+	private void detach_EmployeeTerritories(EmployeeTerritories entity)
+	{
+		this.SendPropertyChanging();
+		entity.Employees = null;
+	}
+	
+	private void attach_Orders(Orders entity)
+	{
+		this.SendPropertyChanging();
+		entity.Employees = this;
+	}
+	
+	private void detach_Orders(Orders entity)
+	{
+		this.SendPropertyChanging();
+		entity.Employees = null;
+	}
+}
+
+[Table(Name="dbo.EmployeeTerritories")]
+public partial class EmployeeTerritories : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private int _EmployeeID;
+	
+	private string _TerritoryID;
+	
+	private EntityRef<Employees> _Employees;
+	
+	private EntityRef<Territories> _Territories;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnEmployeeIDChanging(int value);
+    partial void OnEmployeeIDChanged();
+    partial void OnTerritoryIDChanging(string value);
+    partial void OnTerritoryIDChanged();
+    #endregion
+	
+	public EmployeeTerritories()
+	{
+		this._Employees = default(EntityRef<Employees>);
+		this._Territories = default(EntityRef<Territories>);
+		OnCreated();
+	}
+	
+	[Column(Storage="_EmployeeID", DbType="Int NOT NULL", IsPrimaryKey=true)]
+	public int EmployeeID
+	{
+		get
+		{
+			return this._EmployeeID;
+		}
+		set
+		{
+			if ((this._EmployeeID != value))
+			{
+				if (this._Employees.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnEmployeeIDChanging(value);
+				this.SendPropertyChanging();
+				this._EmployeeID = value;
+				this.SendPropertyChanged("EmployeeID");
+				this.OnEmployeeIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_TerritoryID", DbType="NVarChar(20) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+	public string TerritoryID
+	{
+		get
+		{
+			return this._TerritoryID;
+		}
+		set
+		{
+			if ((this._TerritoryID != value))
+			{
+				if (this._Territories.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnTerritoryIDChanging(value);
+				this.SendPropertyChanging();
+				this._TerritoryID = value;
+				this.SendPropertyChanged("TerritoryID");
+				this.OnTerritoryIDChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_EmployeeTerritories_Employees", Storage="_Employees", ThisKey="EmployeeID", IsForeignKey=true)]
+	public Employees Employees
+	{
+		get
+		{
+			return this._Employees.Entity;
+		}
+		set
+		{
+			Employees previousValue = this._Employees.Entity;
+			if (((previousValue != value) 
+						|| (this._Employees.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Employees.Entity = null;
+					previousValue.EmployeeTerritories.Remove(this);
+				}
+				this._Employees.Entity = value;
+				if ((value != null))
+				{
+					value.EmployeeTerritories.Add(this);
+					this._EmployeeID = value.EmployeeID;
+				}
+				else
+				{
+					this._EmployeeID = default(int);
+				}
+				this.SendPropertyChanged("Employees");
+			}
+		}
+	}
+	
+	[Association(Name="FK_EmployeeTerritories_Territories", Storage="_Territories", ThisKey="TerritoryID", IsForeignKey=true)]
+	public Territories Territories
+	{
+		get
+		{
+			return this._Territories.Entity;
+		}
+		set
+		{
+			Territories previousValue = this._Territories.Entity;
+			if (((previousValue != value) 
+						|| (this._Territories.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Territories.Entity = null;
+					previousValue.EmployeeTerritories.Remove(this);
+				}
+				this._Territories.Entity = value;
+				if ((value != null))
+				{
+					value.EmployeeTerritories.Add(this);
+					this._TerritoryID = value.TerritoryID;
+				}
+				else
+				{
+					this._TerritoryID = default(string);
+				}
+				this.SendPropertyChanged("Territories");
+			}
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+}
+
+[Table(Name="dbo.Order Details")]
+public partial class OrderDetails : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private int _OrderID;
+	
+	private int _ProductID;
+	
+	private decimal _UnitPrice;
+	
+	private short _Quantity;
+	
+	private float _Discount;
+	
+	private EntityRef<Orders> _Orders;
+	
+	private EntityRef<Products> _Products;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnOrderIDChanging(int value);
+    partial void OnOrderIDChanged();
+    partial void OnProductIDChanging(int value);
+    partial void OnProductIDChanged();
+    partial void OnUnitPriceChanging(decimal value);
+    partial void OnUnitPriceChanged();
+    partial void OnQuantityChanging(short value);
+    partial void OnQuantityChanged();
+    partial void OnDiscountChanging(float value);
+    partial void OnDiscountChanged();
+    #endregion
+	
+	public OrderDetails()
+	{
+		this._Orders = default(EntityRef<Orders>);
+		this._Products = default(EntityRef<Products>);
+		OnCreated();
+	}
+	
+	[Column(Storage="_OrderID", DbType="Int NOT NULL", IsPrimaryKey=true)]
+	public int OrderID
+	{
+		get
+		{
+			return this._OrderID;
+		}
+		set
+		{
+			if ((this._OrderID != value))
+			{
+				if (this._Orders.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnOrderIDChanging(value);
+				this.SendPropertyChanging();
+				this._OrderID = value;
+				this.SendPropertyChanged("OrderID");
+				this.OnOrderIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ProductID", DbType="Int NOT NULL", IsPrimaryKey=true)]
+	public int ProductID
+	{
+		get
+		{
+			return this._ProductID;
+		}
+		set
+		{
+			if ((this._ProductID != value))
+			{
+				if (this._Products.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnProductIDChanging(value);
+				this.SendPropertyChanging();
+				this._ProductID = value;
+				this.SendPropertyChanged("ProductID");
+				this.OnProductIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_UnitPrice", DbType="Money NOT NULL")]
+	public decimal UnitPrice
+	{
+		get
+		{
+			return this._UnitPrice;
+		}
+		set
+		{
+			if ((this._UnitPrice != value))
+			{
+				this.OnUnitPriceChanging(value);
+				this.SendPropertyChanging();
+				this._UnitPrice = value;
+				this.SendPropertyChanged("UnitPrice");
+				this.OnUnitPriceChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Quantity", DbType="SmallInt NOT NULL")]
+	public short Quantity
+	{
+		get
+		{
+			return this._Quantity;
+		}
+		set
+		{
+			if ((this._Quantity != value))
+			{
+				this.OnQuantityChanging(value);
+				this.SendPropertyChanging();
+				this._Quantity = value;
+				this.SendPropertyChanged("Quantity");
+				this.OnQuantityChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Discount", DbType="Real NOT NULL")]
+	public float Discount
+	{
+		get
+		{
+			return this._Discount;
+		}
+		set
+		{
+			if ((this._Discount != value))
+			{
+				this.OnDiscountChanging(value);
+				this.SendPropertyChanging();
+				this._Discount = value;
+				this.SendPropertyChanged("Discount");
+				this.OnDiscountChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_Order_Details_Orders", Storage="_Orders", ThisKey="OrderID", IsForeignKey=true)]
+	public Orders Orders
+	{
+		get
+		{
+			return this._Orders.Entity;
+		}
+		set
+		{
+			Orders previousValue = this._Orders.Entity;
+			if (((previousValue != value) 
+						|| (this._Orders.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Orders.Entity = null;
+					previousValue.OrderDetails.Remove(this);
+				}
+				this._Orders.Entity = value;
+				if ((value != null))
+				{
+					value.OrderDetails.Add(this);
+					this._OrderID = value.OrderID;
+				}
+				else
+				{
+					this._OrderID = default(int);
+				}
+				this.SendPropertyChanged("Orders");
+			}
+		}
+	}
+	
+	[Association(Name="FK_Order_Details_Products", Storage="_Products", ThisKey="ProductID", IsForeignKey=true)]
+	public Products Products
+	{
+		get
+		{
+			return this._Products.Entity;
+		}
+		set
+		{
+			Products previousValue = this._Products.Entity;
+			if (((previousValue != value) 
+						|| (this._Products.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Products.Entity = null;
+					previousValue.OrderDetails.Remove(this);
+				}
+				this._Products.Entity = value;
+				if ((value != null))
+				{
+					value.OrderDetails.Add(this);
+					this._ProductID = value.ProductID;
+				}
+				else
+				{
+					this._ProductID = default(int);
+				}
+				this.SendPropertyChanged("Products");
+			}
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+}
+
+[Table(Name="dbo.Orders")]
+public partial class Orders : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private int _OrderID;
+	
+	private string _CustomerID;
+	
+	private System.Nullable<int> _EmployeeID;
+	
+	private System.Nullable<System.DateTime> _OrderDate;
+	
+	private System.Nullable<System.DateTime> _RequiredDate;
+	
+	private System.Nullable<System.DateTime> _ShippedDate;
+	
+	private System.Nullable<int> _ShipVia;
+	
+	private System.Nullable<decimal> _Freight;
+	
+	private string _ShipName;
+	
+	private string _ShipAddress;
+	
+	private string _ShipCity;
+	
+	private string _ShipRegion;
+	
+	private string _ShipPostalCode;
+	
+	private string _ShipCountry;
+	
+	private EntitySet<OrderDetails> _OrderDetails;
+	
+	private EntityRef<Customers> _Customers;
+	
+	private EntityRef<Employees> _Employees;
+	
+	private EntityRef<Shippers> _Shippers;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnOrderIDChanging(int value);
+    partial void OnOrderIDChanged();
+    partial void OnCustomerIDChanging(string value);
+    partial void OnCustomerIDChanged();
+    partial void OnEmployeeIDChanging(System.Nullable<int> value);
+    partial void OnEmployeeIDChanged();
+    partial void OnOrderDateChanging(System.Nullable<System.DateTime> value);
+    partial void OnOrderDateChanged();
+    partial void OnRequiredDateChanging(System.Nullable<System.DateTime> value);
+    partial void OnRequiredDateChanged();
+    partial void OnShippedDateChanging(System.Nullable<System.DateTime> value);
+    partial void OnShippedDateChanged();
+    partial void OnShipViaChanging(System.Nullable<int> value);
+    partial void OnShipViaChanged();
+    partial void OnFreightChanging(System.Nullable<decimal> value);
+    partial void OnFreightChanged();
+    partial void OnShipNameChanging(string value);
+    partial void OnShipNameChanged();
+    partial void OnShipAddressChanging(string value);
+    partial void OnShipAddressChanged();
+    partial void OnShipCityChanging(string value);
+    partial void OnShipCityChanged();
+    partial void OnShipRegionChanging(string value);
+    partial void OnShipRegionChanged();
+    partial void OnShipPostalCodeChanging(string value);
+    partial void OnShipPostalCodeChanged();
+    partial void OnShipCountryChanging(string value);
+    partial void OnShipCountryChanged();
+    #endregion
+	
+	public Orders()
+	{
+		this._OrderDetails = new EntitySet<OrderDetails>(new Action<OrderDetails>(this.attach_OrderDetails), new Action<OrderDetails>(this.detach_OrderDetails));
+		this._Customers = default(EntityRef<Customers>);
+		this._Employees = default(EntityRef<Employees>);
+		this._Shippers = default(EntityRef<Shippers>);
+		OnCreated();
+	}
+	
+	[Column(Storage="_OrderID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+	public int OrderID
+	{
+		get
+		{
+			return this._OrderID;
+		}
+		set
+		{
+			if ((this._OrderID != value))
+			{
+				this.OnOrderIDChanging(value);
+				this.SendPropertyChanging();
+				this._OrderID = value;
+				this.SendPropertyChanged("OrderID");
+				this.OnOrderIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_CustomerID", DbType="NChar(5)")]
+	public string CustomerID
+	{
+		get
+		{
+			return this._CustomerID;
+		}
+		set
+		{
+			if ((this._CustomerID != value))
+			{
+				if (this._Customers.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnCustomerIDChanging(value);
+				this.SendPropertyChanging();
+				this._CustomerID = value;
+				this.SendPropertyChanged("CustomerID");
+				this.OnCustomerIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_EmployeeID", DbType="Int")]
+	public System.Nullable<int> EmployeeID
+	{
+		get
+		{
+			return this._EmployeeID;
+		}
+		set
+		{
+			if ((this._EmployeeID != value))
+			{
+				if (this._Employees.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnEmployeeIDChanging(value);
+				this.SendPropertyChanging();
+				this._EmployeeID = value;
+				this.SendPropertyChanged("EmployeeID");
+				this.OnEmployeeIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_OrderDate", DbType="DateTime")]
+	public System.Nullable<System.DateTime> OrderDate
+	{
+		get
+		{
+			return this._OrderDate;
+		}
+		set
+		{
+			if ((this._OrderDate != value))
+			{
+				this.OnOrderDateChanging(value);
+				this.SendPropertyChanging();
+				this._OrderDate = value;
+				this.SendPropertyChanged("OrderDate");
+				this.OnOrderDateChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_RequiredDate", DbType="DateTime")]
+	public System.Nullable<System.DateTime> RequiredDate
+	{
+		get
+		{
+			return this._RequiredDate;
+		}
+		set
+		{
+			if ((this._RequiredDate != value))
+			{
+				this.OnRequiredDateChanging(value);
+				this.SendPropertyChanging();
+				this._RequiredDate = value;
+				this.SendPropertyChanged("RequiredDate");
+				this.OnRequiredDateChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ShippedDate", DbType="DateTime")]
+	public System.Nullable<System.DateTime> ShippedDate
+	{
+		get
+		{
+			return this._ShippedDate;
+		}
+		set
+		{
+			if ((this._ShippedDate != value))
+			{
+				this.OnShippedDateChanging(value);
+				this.SendPropertyChanging();
+				this._ShippedDate = value;
+				this.SendPropertyChanged("ShippedDate");
+				this.OnShippedDateChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ShipVia", DbType="Int")]
+	public System.Nullable<int> ShipVia
+	{
+		get
+		{
+			return this._ShipVia;
+		}
+		set
+		{
+			if ((this._ShipVia != value))
+			{
+				if (this._Shippers.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnShipViaChanging(value);
+				this.SendPropertyChanging();
+				this._ShipVia = value;
+				this.SendPropertyChanged("ShipVia");
+				this.OnShipViaChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Freight", DbType="Money")]
+	public System.Nullable<decimal> Freight
+	{
+		get
+		{
+			return this._Freight;
+		}
+		set
+		{
+			if ((this._Freight != value))
+			{
+				this.OnFreightChanging(value);
+				this.SendPropertyChanging();
+				this._Freight = value;
+				this.SendPropertyChanged("Freight");
+				this.OnFreightChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ShipName", DbType="NVarChar(40)")]
+	public string ShipName
+	{
+		get
+		{
+			return this._ShipName;
+		}
+		set
+		{
+			if ((this._ShipName != value))
+			{
+				this.OnShipNameChanging(value);
+				this.SendPropertyChanging();
+				this._ShipName = value;
+				this.SendPropertyChanged("ShipName");
+				this.OnShipNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ShipAddress", DbType="NVarChar(60)")]
+	public string ShipAddress
+	{
+		get
+		{
+			return this._ShipAddress;
+		}
+		set
+		{
+			if ((this._ShipAddress != value))
+			{
+				this.OnShipAddressChanging(value);
+				this.SendPropertyChanging();
+				this._ShipAddress = value;
+				this.SendPropertyChanged("ShipAddress");
+				this.OnShipAddressChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ShipCity", DbType="NVarChar(15)")]
+	public string ShipCity
+	{
+		get
+		{
+			return this._ShipCity;
+		}
+		set
+		{
+			if ((this._ShipCity != value))
+			{
+				this.OnShipCityChanging(value);
+				this.SendPropertyChanging();
+				this._ShipCity = value;
+				this.SendPropertyChanged("ShipCity");
+				this.OnShipCityChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ShipRegion", DbType="NVarChar(15)")]
+	public string ShipRegion
+	{
+		get
+		{
+			return this._ShipRegion;
+		}
+		set
+		{
+			if ((this._ShipRegion != value))
+			{
+				this.OnShipRegionChanging(value);
+				this.SendPropertyChanging();
+				this._ShipRegion = value;
+				this.SendPropertyChanged("ShipRegion");
+				this.OnShipRegionChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ShipPostalCode", DbType="NVarChar(10)")]
+	public string ShipPostalCode
+	{
+		get
+		{
+			return this._ShipPostalCode;
+		}
+		set
+		{
+			if ((this._ShipPostalCode != value))
+			{
+				this.OnShipPostalCodeChanging(value);
+				this.SendPropertyChanging();
+				this._ShipPostalCode = value;
+				this.SendPropertyChanged("ShipPostalCode");
+				this.OnShipPostalCodeChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ShipCountry", DbType="NVarChar(15)")]
+	public string ShipCountry
+	{
+		get
+		{
+			return this._ShipCountry;
+		}
+		set
+		{
+			if ((this._ShipCountry != value))
+			{
+				this.OnShipCountryChanging(value);
+				this.SendPropertyChanging();
+				this._ShipCountry = value;
+				this.SendPropertyChanged("ShipCountry");
+				this.OnShipCountryChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_Order_Details_Orders", Storage="_OrderDetails", OtherKey="OrderID", DeleteRule="NO ACTION")]
+	public EntitySet<OrderDetails> OrderDetails
+	{
+		get
+		{
+			return this._OrderDetails;
+		}
+		set
+		{
+			this._OrderDetails.Assign(value);
+		}
+	}
+	
+	[Association(Name="FK_Orders_Customers", Storage="_Customers", ThisKey="CustomerID", IsForeignKey=true)]
+	public Customers Customers
+	{
+		get
+		{
+			return this._Customers.Entity;
+		}
+		set
+		{
+			Customers previousValue = this._Customers.Entity;
+			if (((previousValue != value) 
+						|| (this._Customers.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Customers.Entity = null;
+					previousValue.Orders.Remove(this);
+				}
+				this._Customers.Entity = value;
+				if ((value != null))
+				{
+					value.Orders.Add(this);
+					this._CustomerID = value.CustomerID;
+				}
+				else
+				{
+					this._CustomerID = default(string);
+				}
+				this.SendPropertyChanged("Customers");
+			}
+		}
+	}
+	
+	[Association(Name="FK_Orders_Employees", Storage="_Employees", ThisKey="EmployeeID", IsForeignKey=true)]
+	public Employees Employees
+	{
+		get
+		{
+			return this._Employees.Entity;
+		}
+		set
+		{
+			Employees previousValue = this._Employees.Entity;
+			if (((previousValue != value) 
+						|| (this._Employees.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Employees.Entity = null;
+					previousValue.Orders.Remove(this);
+				}
+				this._Employees.Entity = value;
+				if ((value != null))
+				{
+					value.Orders.Add(this);
+					this._EmployeeID = value.EmployeeID;
+				}
+				else
+				{
+					this._EmployeeID = default(Nullable<int>);
+				}
+				this.SendPropertyChanged("Employees");
+			}
+		}
+	}
+	
+	[Association(Name="FK_Orders_Shippers", Storage="_Shippers", ThisKey="ShipVia", IsForeignKey=true)]
+	public Shippers Shippers
+	{
+		get
+		{
+			return this._Shippers.Entity;
+		}
+		set
+		{
+			Shippers previousValue = this._Shippers.Entity;
+			if (((previousValue != value) 
+						|| (this._Shippers.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Shippers.Entity = null;
+					previousValue.Orders.Remove(this);
+				}
+				this._Shippers.Entity = value;
+				if ((value != null))
+				{
+					value.Orders.Add(this);
+					this._ShipVia = value.ShipperID;
+				}
+				else
+				{
+					this._ShipVia = default(Nullable<int>);
+				}
+				this.SendPropertyChanged("Shippers");
+			}
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+	
+	private void attach_OrderDetails(OrderDetails entity)
+	{
+		this.SendPropertyChanging();
+		entity.Orders = this;
+	}
+	
+	private void detach_OrderDetails(OrderDetails entity)
+	{
+		this.SendPropertyChanging();
+		entity.Orders = null;
+	}
+}
+
+[Table(Name="dbo.Products")]
+public partial class Products : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private int _ProductID;
+	
+	private string _ProductName;
+	
+	private System.Nullable<int> _SupplierID;
+	
+	private System.Nullable<int> _CategoryID;
+	
+	private string _QuantityPerUnit;
+	
+	private System.Nullable<decimal> _UnitPrice;
+	
+	private System.Nullable<short> _UnitsInStock;
+	
+	private System.Nullable<short> _UnitsOnOrder;
+	
+	private System.Nullable<short> _ReorderLevel;
+	
+	private bool _Discontinued;
+	
+	private EntitySet<OrderDetails> _OrderDetails;
+	
+	private EntityRef<Categories> _Categories;
+	
+	private EntityRef<Suppliers> _Suppliers;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnProductIDChanging(int value);
+    partial void OnProductIDChanged();
+    partial void OnProductNameChanging(string value);
+    partial void OnProductNameChanged();
+    partial void OnSupplierIDChanging(System.Nullable<int> value);
+    partial void OnSupplierIDChanged();
+    partial void OnCategoryIDChanging(System.Nullable<int> value);
+    partial void OnCategoryIDChanged();
+    partial void OnQuantityPerUnitChanging(string value);
+    partial void OnQuantityPerUnitChanged();
+    partial void OnUnitPriceChanging(System.Nullable<decimal> value);
+    partial void OnUnitPriceChanged();
+    partial void OnUnitsInStockChanging(System.Nullable<short> value);
+    partial void OnUnitsInStockChanged();
+    partial void OnUnitsOnOrderChanging(System.Nullable<short> value);
+    partial void OnUnitsOnOrderChanged();
+    partial void OnReorderLevelChanging(System.Nullable<short> value);
+    partial void OnReorderLevelChanged();
+    partial void OnDiscontinuedChanging(bool value);
+    partial void OnDiscontinuedChanged();
+    #endregion
+	
+	public Products()
+	{
+		this._OrderDetails = new EntitySet<OrderDetails>(new Action<OrderDetails>(this.attach_OrderDetails), new Action<OrderDetails>(this.detach_OrderDetails));
+		this._Categories = default(EntityRef<Categories>);
+		this._Suppliers = default(EntityRef<Suppliers>);
+		OnCreated();
+	}
+	
+	[Column(Storage="_ProductID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+	public int ProductID
+	{
+		get
+		{
+			return this._ProductID;
+		}
+		set
+		{
+			if ((this._ProductID != value))
+			{
+				this.OnProductIDChanging(value);
+				this.SendPropertyChanging();
+				this._ProductID = value;
+				this.SendPropertyChanged("ProductID");
+				this.OnProductIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+	public string ProductName
+	{
+		get
+		{
+			return this._ProductName;
+		}
+		set
+		{
+			if ((this._ProductName != value))
+			{
+				this.OnProductNameChanging(value);
+				this.SendPropertyChanging();
+				this._ProductName = value;
+				this.SendPropertyChanged("ProductName");
+				this.OnProductNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_SupplierID", DbType="Int")]
+	public System.Nullable<int> SupplierID
+	{
+		get
+		{
+			return this._SupplierID;
+		}
+		set
+		{
+			if ((this._SupplierID != value))
+			{
+				if (this._Suppliers.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnSupplierIDChanging(value);
+				this.SendPropertyChanging();
+				this._SupplierID = value;
+				this.SendPropertyChanged("SupplierID");
+				this.OnSupplierIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_CategoryID", DbType="Int")]
+	public System.Nullable<int> CategoryID
+	{
+		get
+		{
+			return this._CategoryID;
+		}
+		set
+		{
+			if ((this._CategoryID != value))
+			{
+				if (this._Categories.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnCategoryIDChanging(value);
+				this.SendPropertyChanging();
+				this._CategoryID = value;
+				this.SendPropertyChanged("CategoryID");
+				this.OnCategoryIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_QuantityPerUnit", DbType="NVarChar(20)")]
+	public string QuantityPerUnit
+	{
+		get
+		{
+			return this._QuantityPerUnit;
+		}
+		set
+		{
+			if ((this._QuantityPerUnit != value))
+			{
+				this.OnQuantityPerUnitChanging(value);
+				this.SendPropertyChanging();
+				this._QuantityPerUnit = value;
+				this.SendPropertyChanged("QuantityPerUnit");
+				this.OnQuantityPerUnitChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_UnitPrice", DbType="Money")]
+	public System.Nullable<decimal> UnitPrice
+	{
+		get
+		{
+			return this._UnitPrice;
+		}
+		set
+		{
+			if ((this._UnitPrice != value))
+			{
+				this.OnUnitPriceChanging(value);
+				this.SendPropertyChanging();
+				this._UnitPrice = value;
+				this.SendPropertyChanged("UnitPrice");
+				this.OnUnitPriceChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_UnitsInStock", DbType="SmallInt")]
+	public System.Nullable<short> UnitsInStock
+	{
+		get
+		{
+			return this._UnitsInStock;
+		}
+		set
+		{
+			if ((this._UnitsInStock != value))
+			{
+				this.OnUnitsInStockChanging(value);
+				this.SendPropertyChanging();
+				this._UnitsInStock = value;
+				this.SendPropertyChanged("UnitsInStock");
+				this.OnUnitsInStockChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_UnitsOnOrder", DbType="SmallInt")]
+	public System.Nullable<short> UnitsOnOrder
+	{
+		get
+		{
+			return this._UnitsOnOrder;
+		}
+		set
+		{
+			if ((this._UnitsOnOrder != value))
+			{
+				this.OnUnitsOnOrderChanging(value);
+				this.SendPropertyChanging();
+				this._UnitsOnOrder = value;
+				this.SendPropertyChanged("UnitsOnOrder");
+				this.OnUnitsOnOrderChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ReorderLevel", DbType="SmallInt")]
+	public System.Nullable<short> ReorderLevel
+	{
+		get
+		{
+			return this._ReorderLevel;
+		}
+		set
+		{
+			if ((this._ReorderLevel != value))
+			{
+				this.OnReorderLevelChanging(value);
+				this.SendPropertyChanging();
+				this._ReorderLevel = value;
+				this.SendPropertyChanged("ReorderLevel");
+				this.OnReorderLevelChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Discontinued", DbType="Bit NOT NULL")]
+	public bool Discontinued
+	{
+		get
+		{
+			return this._Discontinued;
+		}
+		set
+		{
+			if ((this._Discontinued != value))
+			{
+				this.OnDiscontinuedChanging(value);
+				this.SendPropertyChanging();
+				this._Discontinued = value;
+				this.SendPropertyChanged("Discontinued");
+				this.OnDiscontinuedChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_Order_Details_Products", Storage="_OrderDetails", OtherKey="ProductID", DeleteRule="NO ACTION")]
+	public EntitySet<OrderDetails> OrderDetails
+	{
+		get
+		{
+			return this._OrderDetails;
+		}
+		set
+		{
+			this._OrderDetails.Assign(value);
+		}
+	}
+	
+	[Association(Name="FK_Products_Categories", Storage="_Categories", ThisKey="CategoryID", IsForeignKey=true)]
+	public Categories Categories
+	{
+		get
+		{
+			return this._Categories.Entity;
+		}
+		set
+		{
+			Categories previousValue = this._Categories.Entity;
+			if (((previousValue != value) 
+						|| (this._Categories.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Categories.Entity = null;
+					previousValue.Products.Remove(this);
+				}
+				this._Categories.Entity = value;
+				if ((value != null))
+				{
+					value.Products.Add(this);
+					this._CategoryID = value.CategoryID;
+				}
+				else
+				{
+					this._CategoryID = default(Nullable<int>);
+				}
+				this.SendPropertyChanged("Categories");
+			}
+		}
+	}
+	
+	[Association(Name="FK_Products_Suppliers", Storage="_Suppliers", ThisKey="SupplierID", IsForeignKey=true)]
+	public Suppliers Suppliers
+	{
+		get
+		{
+			return this._Suppliers.Entity;
+		}
+		set
+		{
+			Suppliers previousValue = this._Suppliers.Entity;
+			if (((previousValue != value) 
+						|| (this._Suppliers.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Suppliers.Entity = null;
+					previousValue.Products.Remove(this);
+				}
+				this._Suppliers.Entity = value;
+				if ((value != null))
+				{
+					value.Products.Add(this);
+					this._SupplierID = value.SupplierID;
+				}
+				else
+				{
+					this._SupplierID = default(Nullable<int>);
+				}
+				this.SendPropertyChanged("Suppliers");
+			}
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+	
+	private void attach_OrderDetails(OrderDetails entity)
+	{
+		this.SendPropertyChanging();
+		entity.Products = this;
+	}
+	
+	private void detach_OrderDetails(OrderDetails entity)
+	{
+		this.SendPropertyChanging();
+		entity.Products = null;
+	}
+}
+
+[Table(Name="dbo.Region")]
+public partial class Region : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private int _RegionID;
+	
+	private string _RegionDescription;
+	
+	private EntitySet<Territories> _Territories;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnRegionIDChanging(int value);
+    partial void OnRegionIDChanged();
+    partial void OnRegionDescriptionChanging(string value);
+    partial void OnRegionDescriptionChanged();
+    #endregion
+	
+	public Region()
+	{
+		this._Territories = new EntitySet<Territories>(new Action<Territories>(this.attach_Territories), new Action<Territories>(this.detach_Territories));
+		OnCreated();
+	}
+	
+	[Column(Storage="_RegionID", DbType="Int NOT NULL", IsPrimaryKey=true)]
+	public int RegionID
+	{
+		get
+		{
+			return this._RegionID;
+		}
+		set
+		{
+			if ((this._RegionID != value))
+			{
+				this.OnRegionIDChanging(value);
+				this.SendPropertyChanging();
+				this._RegionID = value;
+				this.SendPropertyChanged("RegionID");
+				this.OnRegionIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_RegionDescription", DbType="NChar(50) NOT NULL", CanBeNull=false)]
+	public string RegionDescription
+	{
+		get
+		{
+			return this._RegionDescription;
+		}
+		set
+		{
+			if ((this._RegionDescription != value))
+			{
+				this.OnRegionDescriptionChanging(value);
+				this.SendPropertyChanging();
+				this._RegionDescription = value;
+				this.SendPropertyChanged("RegionDescription");
+				this.OnRegionDescriptionChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_Territories_Region", Storage="_Territories", OtherKey="RegionID", DeleteRule="NO ACTION")]
+	public EntitySet<Territories> Territories
+	{
+		get
+		{
+			return this._Territories;
+		}
+		set
+		{
+			this._Territories.Assign(value);
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+	
+	private void attach_Territories(Territories entity)
+	{
+		this.SendPropertyChanging();
+		entity.Region = this;
+	}
+	
+	private void detach_Territories(Territories entity)
+	{
+		this.SendPropertyChanging();
+		entity.Region = null;
+	}
+}
+
+[Table(Name="dbo.Shippers")]
+public partial class Shippers : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private int _ShipperID;
+	
+	private string _CompanyName;
+	
+	private string _Phone;
+	
+	private EntitySet<Orders> _Orders;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnShipperIDChanging(int value);
+    partial void OnShipperIDChanged();
+    partial void OnCompanyNameChanging(string value);
+    partial void OnCompanyNameChanged();
+    partial void OnPhoneChanging(string value);
+    partial void OnPhoneChanged();
+    #endregion
+	
+	public Shippers()
+	{
+		this._Orders = new EntitySet<Orders>(new Action<Orders>(this.attach_Orders), new Action<Orders>(this.detach_Orders));
+		OnCreated();
+	}
+	
+	[Column(Storage="_ShipperID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+	public int ShipperID
+	{
+		get
+		{
+			return this._ShipperID;
+		}
+		set
+		{
+			if ((this._ShipperID != value))
+			{
+				this.OnShipperIDChanging(value);
+				this.SendPropertyChanging();
+				this._ShipperID = value;
+				this.SendPropertyChanged("ShipperID");
+				this.OnShipperIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+	public string CompanyName
+	{
+		get
+		{
+			return this._CompanyName;
+		}
+		set
+		{
+			if ((this._CompanyName != value))
+			{
+				this.OnCompanyNameChanging(value);
+				this.SendPropertyChanging();
+				this._CompanyName = value;
+				this.SendPropertyChanged("CompanyName");
+				this.OnCompanyNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Phone", DbType="NVarChar(24)")]
+	public string Phone
+	{
+		get
+		{
+			return this._Phone;
+		}
+		set
+		{
+			if ((this._Phone != value))
+			{
+				this.OnPhoneChanging(value);
+				this.SendPropertyChanging();
+				this._Phone = value;
+				this.SendPropertyChanged("Phone");
+				this.OnPhoneChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_Orders_Shippers", Storage="_Orders", OtherKey="ShipVia", DeleteRule="NO ACTION")]
+	public EntitySet<Orders> Orders
+	{
+		get
+		{
+			return this._Orders;
+		}
+		set
+		{
+			this._Orders.Assign(value);
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+	
+	private void attach_Orders(Orders entity)
+	{
+		this.SendPropertyChanging();
+		entity.Shippers = this;
+	}
+	
+	private void detach_Orders(Orders entity)
+	{
+		this.SendPropertyChanging();
+		entity.Shippers = null;
+	}
+}
+
+[Table(Name="dbo.Suppliers")]
+public partial class Suppliers : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private int _SupplierID;
+	
+	private string _CompanyName;
+	
+	private string _ContactName;
+	
+	private string _ContactTitle;
+	
+	private string _Address;
+	
+	private string _City;
+	
+	private string _Region;
+	
+	private string _PostalCode;
+	
+	private string _Country;
+	
+	private string _Phone;
+	
+	private string _Fax;
+	
+	private string _HomePage;
+	
+	private EntitySet<Products> _Products;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnSupplierIDChanging(int value);
+    partial void OnSupplierIDChanged();
+    partial void OnCompanyNameChanging(string value);
+    partial void OnCompanyNameChanged();
+    partial void OnContactNameChanging(string value);
+    partial void OnContactNameChanged();
+    partial void OnContactTitleChanging(string value);
+    partial void OnContactTitleChanged();
+    partial void OnAddressChanging(string value);
+    partial void OnAddressChanged();
+    partial void OnCityChanging(string value);
+    partial void OnCityChanged();
+    partial void OnRegionChanging(string value);
+    partial void OnRegionChanged();
+    partial void OnPostalCodeChanging(string value);
+    partial void OnPostalCodeChanged();
+    partial void OnCountryChanging(string value);
+    partial void OnCountryChanged();
+    partial void OnPhoneChanging(string value);
+    partial void OnPhoneChanged();
+    partial void OnFaxChanging(string value);
+    partial void OnFaxChanged();
+    partial void OnHomePageChanging(string value);
+    partial void OnHomePageChanged();
+    #endregion
+	
+	public Suppliers()
+	{
+		this._Products = new EntitySet<Products>(new Action<Products>(this.attach_Products), new Action<Products>(this.detach_Products));
+		OnCreated();
+	}
+	
+	[Column(Storage="_SupplierID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+	public int SupplierID
+	{
+		get
+		{
+			return this._SupplierID;
+		}
+		set
+		{
+			if ((this._SupplierID != value))
+			{
+				this.OnSupplierIDChanging(value);
+				this.SendPropertyChanging();
+				this._SupplierID = value;
+				this.SendPropertyChanged("SupplierID");
+				this.OnSupplierIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+	public string CompanyName
+	{
+		get
+		{
+			return this._CompanyName;
+		}
+		set
+		{
+			if ((this._CompanyName != value))
+			{
+				this.OnCompanyNameChanging(value);
+				this.SendPropertyChanging();
+				this._CompanyName = value;
+				this.SendPropertyChanged("CompanyName");
+				this.OnCompanyNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ContactName", DbType="NVarChar(30)")]
+	public string ContactName
+	{
+		get
+		{
+			return this._ContactName;
+		}
+		set
+		{
+			if ((this._ContactName != value))
+			{
+				this.OnContactNameChanging(value);
+				this.SendPropertyChanging();
+				this._ContactName = value;
+				this.SendPropertyChanged("ContactName");
+				this.OnContactNameChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_ContactTitle", DbType="NVarChar(30)")]
+	public string ContactTitle
+	{
+		get
+		{
+			return this._ContactTitle;
+		}
+		set
+		{
+			if ((this._ContactTitle != value))
+			{
+				this.OnContactTitleChanging(value);
+				this.SendPropertyChanging();
+				this._ContactTitle = value;
+				this.SendPropertyChanged("ContactTitle");
+				this.OnContactTitleChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Address", DbType="NVarChar(60)")]
+	public string Address
+	{
+		get
+		{
+			return this._Address;
+		}
+		set
+		{
+			if ((this._Address != value))
+			{
+				this.OnAddressChanging(value);
+				this.SendPropertyChanging();
+				this._Address = value;
+				this.SendPropertyChanged("Address");
+				this.OnAddressChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_City", DbType="NVarChar(15)")]
+	public string City
+	{
+		get
+		{
+			return this._City;
+		}
+		set
+		{
+			if ((this._City != value))
+			{
+				this.OnCityChanging(value);
+				this.SendPropertyChanging();
+				this._City = value;
+				this.SendPropertyChanged("City");
+				this.OnCityChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Region", DbType="NVarChar(15)")]
+	public string Region
+	{
+		get
+		{
+			return this._Region;
+		}
+		set
+		{
+			if ((this._Region != value))
+			{
+				this.OnRegionChanging(value);
+				this.SendPropertyChanging();
+				this._Region = value;
+				this.SendPropertyChanged("Region");
+				this.OnRegionChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_PostalCode", DbType="NVarChar(10)")]
+	public string PostalCode
+	{
+		get
+		{
+			return this._PostalCode;
+		}
+		set
+		{
+			if ((this._PostalCode != value))
+			{
+				this.OnPostalCodeChanging(value);
+				this.SendPropertyChanging();
+				this._PostalCode = value;
+				this.SendPropertyChanged("PostalCode");
+				this.OnPostalCodeChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Country", DbType="NVarChar(15)")]
+	public string Country
+	{
+		get
+		{
+			return this._Country;
+		}
+		set
+		{
+			if ((this._Country != value))
+			{
+				this.OnCountryChanging(value);
+				this.SendPropertyChanging();
+				this._Country = value;
+				this.SendPropertyChanged("Country");
+				this.OnCountryChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Phone", DbType="NVarChar(24)")]
+	public string Phone
+	{
+		get
+		{
+			return this._Phone;
+		}
+		set
+		{
+			if ((this._Phone != value))
+			{
+				this.OnPhoneChanging(value);
+				this.SendPropertyChanging();
+				this._Phone = value;
+				this.SendPropertyChanged("Phone");
+				this.OnPhoneChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_Fax", DbType="NVarChar(24)")]
+	public string Fax
+	{
+		get
+		{
+			return this._Fax;
+		}
+		set
+		{
+			if ((this._Fax != value))
+			{
+				this.OnFaxChanging(value);
+				this.SendPropertyChanging();
+				this._Fax = value;
+				this.SendPropertyChanged("Fax");
+				this.OnFaxChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_HomePage", DbType="NText", UpdateCheck=UpdateCheck.Never)]
+	public string HomePage
+	{
+		get
+		{
+			return this._HomePage;
+		}
+		set
+		{
+			if ((this._HomePage != value))
+			{
+				this.OnHomePageChanging(value);
+				this.SendPropertyChanging();
+				this._HomePage = value;
+				this.SendPropertyChanged("HomePage");
+				this.OnHomePageChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_Products_Suppliers", Storage="_Products", OtherKey="SupplierID", DeleteRule="NO ACTION")]
+	public EntitySet<Products> Products
+	{
+		get
+		{
+			return this._Products;
+		}
+		set
+		{
+			this._Products.Assign(value);
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+	
+	private void attach_Products(Products entity)
+	{
+		this.SendPropertyChanging();
+		entity.Suppliers = this;
+	}
+	
+	private void detach_Products(Products entity)
+	{
+		this.SendPropertyChanging();
+		entity.Suppliers = null;
+	}
+}
+
+[Table(Name="dbo.Territories")]
+public partial class Territories : INotifyPropertyChanging, INotifyPropertyChanged
+{
+	
+	private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+	
+	private string _TerritoryID;
+	
+	private string _TerritoryDescription;
+	
+	private int _RegionID;
+	
+	private EntitySet<EmployeeTerritories> _EmployeeTerritories;
+	
+	private EntityRef<Region> _Region;
+	
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnTerritoryIDChanging(string value);
+    partial void OnTerritoryIDChanged();
+    partial void OnTerritoryDescriptionChanging(string value);
+    partial void OnTerritoryDescriptionChanged();
+    partial void OnRegionIDChanging(int value);
+    partial void OnRegionIDChanged();
+    #endregion
+	
+	public Territories()
+	{
+		this._EmployeeTerritories = new EntitySet<EmployeeTerritories>(new Action<EmployeeTerritories>(this.attach_EmployeeTerritories), new Action<EmployeeTerritories>(this.detach_EmployeeTerritories));
+		this._Region = default(EntityRef<Region>);
+		OnCreated();
+	}
+	
+	[Column(Storage="_TerritoryID", DbType="NVarChar(20) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+	public string TerritoryID
+	{
+		get
+		{
+			return this._TerritoryID;
+		}
+		set
+		{
+			if ((this._TerritoryID != value))
+			{
+				this.OnTerritoryIDChanging(value);
+				this.SendPropertyChanging();
+				this._TerritoryID = value;
+				this.SendPropertyChanged("TerritoryID");
+				this.OnTerritoryIDChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_TerritoryDescription", DbType="NChar(50) NOT NULL", CanBeNull=false)]
+	public string TerritoryDescription
+	{
+		get
+		{
+			return this._TerritoryDescription;
+		}
+		set
+		{
+			if ((this._TerritoryDescription != value))
+			{
+				this.OnTerritoryDescriptionChanging(value);
+				this.SendPropertyChanging();
+				this._TerritoryDescription = value;
+				this.SendPropertyChanged("TerritoryDescription");
+				this.OnTerritoryDescriptionChanged();
+			}
+		}
+	}
+	
+	[Column(Storage="_RegionID", DbType="Int NOT NULL")]
+	public int RegionID
+	{
+		get
+		{
+			return this._RegionID;
+		}
+		set
+		{
+			if ((this._RegionID != value))
+			{
+				if (this._Region.HasLoadedOrAssignedValue)
+				{
+					throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+				}
+				this.OnRegionIDChanging(value);
+				this.SendPropertyChanging();
+				this._RegionID = value;
+				this.SendPropertyChanged("RegionID");
+				this.OnRegionIDChanged();
+			}
+		}
+	}
+	
+	[Association(Name="FK_EmployeeTerritories_Territories", Storage="_EmployeeTerritories", OtherKey="TerritoryID", DeleteRule="NO ACTION")]
+	public EntitySet<EmployeeTerritories> EmployeeTerritories
+	{
+		get
+		{
+			return this._EmployeeTerritories;
+		}
+		set
+		{
+			this._EmployeeTerritories.Assign(value);
+		}
+	}
+	
+	[Association(Name="FK_Territories_Region", Storage="_Region", ThisKey="RegionID", IsForeignKey=true)]
+	public Region Region
+	{
+		get
+		{
+			return this._Region.Entity;
+		}
+		set
+		{
+			Region previousValue = this._Region.Entity;
+			if (((previousValue != value) 
+						|| (this._Region.HasLoadedOrAssignedValue == false)))
+			{
+				this.SendPropertyChanging();
+				if ((previousValue != null))
+				{
+					this._Region.Entity = null;
+					previousValue.Territories.Remove(this);
+				}
+				this._Region.Entity = value;
+				if ((value != null))
+				{
+					value.Territories.Add(this);
+					this._RegionID = value.RegionID;
+				}
+				else
+				{
+					this._RegionID = default(int);
+				}
+				this.SendPropertyChanged("Region");
+			}
+		}
+	}
+	
+	public event PropertyChangingEventHandler PropertyChanging;
+	
+	public event PropertyChangedEventHandler PropertyChanged;
+	
+	protected virtual void SendPropertyChanging()
+	{
+		if ((this.PropertyChanging != null))
+		{
+			this.PropertyChanging(this, emptyChangingEventArgs);
+		}
+	}
+	
+	protected virtual void SendPropertyChanged(String propertyName)
+	{
+		if ((this.PropertyChanged != null))
+		{
+			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+	}
+	
+	private void attach_EmployeeTerritories(EmployeeTerritories entity)
+	{
+		this.SendPropertyChanging();
+		entity.Territories = this;
+	}
+	
+	private void detach_EmployeeTerritories(EmployeeTerritories entity)
+	{
+		this.SendPropertyChanging();
+		entity.Territories = null;
+	}
+}
+#pragma warning restore 1591
diff --git a/src/FSharp.PowerPack/Arg.fs b/src/FSharp.PowerPack/Arg.fs
new file mode 100755
index 0000000..a5fbb6c
--- /dev/null
+++ b/src/FSharp.PowerPack/Arg.fs
@@ -0,0 +1,133 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+#if INTERNALIZED_POWER_PACK
+namespace Internal.Utilities
+#else
+namespace Microsoft.FSharp.Text
+#endif
+
+
+type ArgType = 
+  | ClearArg of bool ref
+  | FloatArg of (float -> unit)
+  | IntArg of (int -> unit)
+  | RestArg of (string -> unit)
+  | SetArg of bool ref
+  | StringArg of (string -> unit)
+  | UnitArg of (unit -> unit)
+  static member Clear  r = ClearArg r
+  static member Float  r = FloatArg r
+  static member Int    r = IntArg r
+  static member Rest   r = RestArg r
+  static member Set    r = SetArg r
+  static member String r = StringArg r
+  static member Unit   r = UnitArg r
+
+
+type ArgInfo (name,action,help) = 
+  member x.Name = name
+  member x.ArgType = action
+  member x.HelpText = help
+  
+exception Bad of string
+exception HelpText of string
+
+[<Sealed>]
+type ArgParser() = 
+    static let getUsage specs u =  
+      let sbuf = new System.Text.StringBuilder 100  
+      let pstring (s:string) = sbuf.Append s |> ignore 
+      let pendline s = pstring s; pstring "\n" 
+      pendline u;
+      List.iter (fun (arg:ArgInfo) -> 
+        match arg.Name, arg.ArgType, arg.HelpText with
+        | (s, (UnitArg _ | SetArg _ | ClearArg _), helpText) -> pstring "\t"; pstring s; pstring ": "; pendline helpText
+        | (s, StringArg _, helpText) -> pstring "\t"; pstring s; pstring " <string>: "; pendline helpText
+        | (s, IntArg _, helpText) -> pstring "\t"; pstring s; pstring " <int>: "; pendline helpText
+        | (s, FloatArg _, helpText) ->  pstring "\t"; pstring s; pstring " <float>: "; pendline helpText
+        | (s, RestArg _, helpText) -> pstring "\t"; pstring s; pstring " ...: "; pendline helpText)
+        specs;
+      pstring "\t"; pstring "--help"; pstring ": "; pendline "display this list of options";
+      pstring "\t"; pstring "-help"; pstring ": "; pendline "display this list of options";
+      sbuf.ToString()
+
+
+    static member ParsePartial(cursor,argv,argSpecs:seq<ArgInfo>,?other,?usageText) =
+        let other = defaultArg other (fun _ -> ())
+        let usageText = defaultArg usageText ""
+        let nargs = Array.length argv 
+        incr cursor;
+        let argSpecs = argSpecs |> Seq.toList
+        let specs = argSpecs |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType)
+        while !cursor < nargs do
+          let arg = argv.[!cursor] 
+          let rec findMatchingArg args = 
+            match args with
+            | ((s, action) :: _) when s = arg -> 
+               let getSecondArg () = 
+                   if !cursor + 1 >= nargs then 
+                     raise(Bad("option "+s+" needs an argument.\n"+getUsage argSpecs usageText));
+                   argv.[!cursor+1] 
+                 
+               match action with 
+               | UnitArg f -> 
+                 f (); 
+                 incr cursor
+               | SetArg f ->
+                 f := true; 
+                 incr cursor
+               | ClearArg f -> 
+                 f := false; 
+                 incr cursor
+               | StringArg f-> 
+                 let arg2 = getSecondArg() 
+                 f arg2; 
+                 cursor := !cursor + 2
+               | IntArg f -> 
+                 let arg2 = getSecondArg () 
+                 let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in  
+                 f arg2;
+                 cursor := !cursor + 2;
+               | FloatArg f -> 
+                 let arg2 = getSecondArg() 
+                 let arg2 = try float arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in 
+                 f arg2; 
+                 cursor := !cursor + 2;
+               | RestArg f -> 
+                 incr cursor;
+                 while !cursor < nargs do
+                     f (argv.[!cursor]);
+                     incr cursor;
+
+            | (_ :: more)  -> findMatchingArg more 
+            | [] -> 
+                if arg = "-help" || arg = "--help" || arg = "/help" || arg = "/help" || arg = "/?" then
+                    raise (HelpText (getUsage argSpecs usageText))
+                // Note: for '/abc/def' does not count as an argument
+                // Note: '/abc' does
+                elif arg.Length>0 && (arg.[0] = '-' || (arg.[0] = '/' && not (arg.Length > 1 && arg.[1..].Contains ("/")))) then
+                    raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage argSpecs usageText))
+                else 
+                   other arg;
+                   incr cursor
+          findMatchingArg specs 
+
+    static member Usage (specs,?usage) = 
+        let usage = defaultArg usage ""
+        System.Console.Error.WriteLine (getUsage (Seq.toList specs) usage)
+
+    #if FX_NO_COMMAND_LINE_ARGS
+    #else
+    static member Parse (specs,?other,?usageText) = 
+        let current = ref 0
+        let argv = System.Environment.GetCommandLineArgs() 
+        try ArgParser.ParsePartial (current, argv, specs, ?other=other, ?usageText=usageText)
+        with 
+          | Bad h 
+          | HelpText h -> 
+              System.Console.Error.WriteLine h; 
+              System.Console.Error.Flush();  
+              System.Environment.Exit(1); 
+          | e -> 
+              reraise()
+    #endif
diff --git a/src/FSharp.PowerPack/Arg.fsi b/src/FSharp.PowerPack/Arg.fsi
new file mode 100755
index 0000000..3a9c941
--- /dev/null
+++ b/src/FSharp.PowerPack/Arg.fsi
@@ -0,0 +1,50 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+/// A simple command-line argument processor.
+#if INTERNALIZED_POWER_PACK
+namespace Internal.Utilities
+#else
+namespace Microsoft.FSharp.Text
+#endif
+
+/// The spec value describes the action of the argument,
+/// and whether it expects a following parameter.
+[<Sealed>]
+type ArgType = 
+    static member Clear  : bool ref         -> ArgType
+    static member Float  : (float -> unit)  -> ArgType
+    static member Int    : (int -> unit)    -> ArgType
+    static member Rest   : (string -> unit) -> ArgType
+    static member Set    : bool ref         -> ArgType
+    static member String : (string -> unit) -> ArgType
+    static member Unit   : (unit -> unit)   -> ArgType
+
+type ArgInfo = 
+  new : name:string * action:ArgType * help:string -> ArgInfo
+  /// Return the name of the argument
+  member Name : string
+  /// Return the argument type and action of the argument
+  member ArgType : ArgType
+  /// Return the usage help associated with the argument
+  member HelpText : string
+
+[<Sealed>]
+type ArgParser = 
+    #if FX_NO_COMMAND_LINE_ARGS
+    #else
+
+    /// Parse some of the arguments given by 'argv', starting at the given position
+    [<System.Obsolete("This method should not be used directly as it will be removed in a future revision of this library")>]
+    static member ParsePartial: cursor: int ref * argv: string[] * arguments:seq<ArgInfo> * ?otherArgs: (string -> unit) * ?usageText:string -> unit
+
+    /// Parse the arguments given by System.Environment.GetEnvironmentVariables()
+    /// according to the argument processing specifications "specs".
+    /// Args begin with "-". Non-arguments are passed to "f" in
+    /// order.  "use" is printed as part of the usage line if an error occurs.
+
+    static member Parse: arguments:seq<ArgInfo> * ?otherArgs: (string -> unit) * ?usageText:string -> unit
+    #endif
+
+    /// Prints the help for each argument.
+    static member Usage : arguments:seq<ArgInfo> * ?usage:string -> unit
+
diff --git a/src/FSharp.PowerPack/AssemblyInfo.fs b/src/FSharp.PowerPack/AssemblyInfo.fs
new file mode 100755
index 0000000..68b52de
--- /dev/null
+++ b/src/FSharp.PowerPack/AssemblyInfo.fs
@@ -0,0 +1,25 @@
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("FSharp.PowerPack.dll")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("FSharp.PowerPack.dll")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Text")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Control")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Collections")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Core")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Math")>]
+[<assembly: AutoOpen("Microsoft.FSharp")>]
+[<assembly: System.Runtime.InteropServices.ComVisible(false)>]
+[<assembly: System.CLSCompliant(true)>]
+//[<assembly: System.Security.SecurityTransparent>]
+#if FX_NO_SECURITY_PERMISSIONS
+#else
+#if FX_SIMPLE_SECURITY_PERMISSIONS
+[<assembly: System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.RequestMinimum)>]
+#else
+#endif
+#endif
+do()
+
+
diff --git a/src/FSharp.PowerPack/AsyncOperations.fs b/src/FSharp.PowerPack/AsyncOperations.fs
new file mode 100755
index 0000000..c3698a5
--- /dev/null
+++ b/src/FSharp.PowerPack/AsyncOperations.fs
@@ -0,0 +1,167 @@
+// (c) Microsoft Corporation 2005-2009. 
+namespace Microsoft.FSharp.Control
+
+    open System
+    open System.Threading
+    open Microsoft.FSharp.Control
+
+    /// Represents the reified result of an asynchronous computation
+    [<NoEquality; NoComparison>]
+    type AsyncResult<'T>  =
+        |   AsyncOk of 'T
+        |   AsyncException of exn
+        |   AsyncCanceled of OperationCanceledException
+
+        static member Commit(res:AsyncResult<'T>) = 
+            Async.FromContinuations (fun (cont,econt,ccont) -> 
+                   match res with 
+                   | AsyncOk v -> cont v 
+                   | AsyncException exn -> econt exn 
+                   | AsyncCanceled exn -> ccont exn)
+
+    /// When using .NET 4.0 you can replace this type by Task<'T>
+    [<Sealed>]
+    type AsyncResultCell<'T>() =
+        let mutable result = None
+        // The continuation for the result, if any
+        let mutable savedConts = []
+        
+        let syncRoot = new obj()
+                
+
+        // Record the result in the AsyncResultCell.
+        // Ignore subsequent sets of the result. This can happen, e.g. for a race between 
+        // a cancellation and a success.
+        member x.RegisterResult (res:AsyncResult<'T>,?reuseThread) =
+            let grabbedConts = 
+                lock syncRoot (fun () ->
+                    if result.IsSome then  
+                        []
+                    else
+                        result <- Some res;
+                        // Invoke continuations in FIFO order 
+                        // Continuations that Async.FromContinuations provide do QUWI/SynchContext.Post, 
+                        // so the order is not overly relevant but still.                        
+                        List.rev savedConts)
+            // Run continuations outside the lock
+            let reuseThread = defaultArg reuseThread false
+            match grabbedConts with
+            |   [] -> ()
+            |   [cont] when reuseThread -> cont res
+            |   otherwise ->
+#if FX_NO_SYNC_CONTEXT
+                    let postOrQueue cont = ThreadPool.QueueUserWorkItem(fun _ -> cont res) |> ignore
+#else
+                    let synchContext = System.Threading.SynchronizationContext.Current
+                    let postOrQueue =
+                        match synchContext with
+                        |   null -> fun cont -> ThreadPool.QueueUserWorkItem(fun _ -> cont res) |> ignore
+                        |   sc -> fun cont -> sc.Post((fun _ -> cont res), state=null)
+#endif                        
+                    grabbedConts |> List.iter postOrQueue
+
+        /// Get the reified result 
+        member private x.AsyncPrimitiveResult =
+            Async.FromContinuations(fun (cont,_,_) -> 
+                let grabbedResult = 
+                    lock syncRoot (fun () ->
+                        match result with
+                        | Some res -> 
+                            result
+                        | None ->
+                            // Otherwise save the continuation and call it in RegisterResult
+                            savedConts <- cont::savedConts
+                            None)
+                // Run the action outside the lock
+                match grabbedResult with 
+                | None -> ()
+                | Some res -> cont res) 
+                           
+
+        /// Get the result and commit it
+        member x.AsyncResult =
+            async { let! res = x.AsyncPrimitiveResult
+                    return! AsyncResult.Commit(res) }
+
+
+    [<AutoOpen>]
+    module FileExtensions =
+
+        let UnblockViaNewThread f =
+            async { do! Async.SwitchToNewThread ()
+                    let res = f()
+                    do! Async.SwitchToThreadPool ()
+                    return res }
+
+
+        type System.IO.File with
+            static member AsyncOpenText(path)   = UnblockViaNewThread (fun () -> System.IO.File.OpenText(path))
+            static member AsyncAppendText(path) = UnblockViaNewThread (fun () -> System.IO.File.AppendText(path))
+            static member AsyncOpenRead(path)   = UnblockViaNewThread (fun () -> System.IO.File.OpenRead(path))
+            static member AsyncOpenWrite(path)  = UnblockViaNewThread (fun () -> System.IO.File.OpenWrite(path))
+#if FX_NO_FILE_OPTIONS
+            static member AsyncOpen(path,mode,?access,?share,?bufferSize) =
+#else
+            static member AsyncOpen(path,mode,?access,?share,?bufferSize,?options) =
+#endif
+                let access = match access with Some v -> v | None -> System.IO.FileAccess.ReadWrite
+                let share = match share with Some v -> v | None -> System.IO.FileShare.None
+#if FX_NO_FILE_OPTIONS
+#else
+                let options = match options with Some v -> v | None -> System.IO.FileOptions.None
+#endif
+                let bufferSize = match bufferSize with Some v -> v | None -> 0x1000
+                UnblockViaNewThread (fun () -> 
+#if FX_NO_FILE_OPTIONS
+                    new System.IO.FileStream(path,mode,access,share,bufferSize))
+#else
+                    new System.IO.FileStream(path,mode,access,share,bufferSize, options))
+#endif
+
+            static member OpenTextAsync(path)   = System.IO.File.AsyncOpenText(path)
+            static member AppendTextAsync(path) = System.IO.File.AsyncAppendText(path)
+            static member OpenReadAsync(path)   = System.IO.File.AsyncOpenRead(path)
+            static member OpenWriteAsync(path)  = System.IO.File.AsyncOpenWrite(path)
+#if FX_NO_FILE_OPTIONS
+            static member OpenAsync(path,mode,?access,?share,?bufferSize) = 
+                System.IO.File.AsyncOpen(path, mode, ?access=access, ?share=share,?bufferSize=bufferSize)
+#else
+            static member OpenAsync(path,mode,?access,?share,?bufferSize,?options) = 
+                System.IO.File.AsyncOpen(path, mode, ?access=access, ?share=share,?bufferSize=bufferSize,?options=options)
+#endif
+
+    [<AutoOpen>]
+    module StreamReaderExtensions =
+        type System.IO.StreamReader with
+
+            member s.AsyncReadToEnd () = FileExtensions.UnblockViaNewThread (fun () -> s.ReadToEnd())
+            member s.ReadToEndAsync () = s.AsyncReadToEnd ()
+
+#if FX_NO_WEB_REQUESTS
+#else
+    [<AutoOpen>]
+    module WebRequestExtensions =
+        open System
+        open System.Net
+        open Microsoft.FSharp.Control.WebExtensions
+
+        let callFSharpCoreAsyncGetResponse (req: System.Net.WebRequest) = req.AsyncGetResponse()
+        
+        type System.Net.WebRequest with
+            member req.AsyncGetResponse() = callFSharpCoreAsyncGetResponse req // this calls the FSharp.Core method
+            member req.GetResponseAsync() = callFSharpCoreAsyncGetResponse req // this calls the FSharp.Core method
+#endif
+     
+#if FX_NO_WEB_CLIENT
+#else
+    [<AutoOpen>]
+    module WebClientExtensions =
+        open System.Net
+        open Microsoft.FSharp.Control.WebExtensions
+        
+        let callFSharpCoreAsyncDownloadString (req: System.Net.WebClient) address = req.AsyncDownloadString address
+
+        type WebClient with
+            member this.AsyncDownloadString address = callFSharpCoreAsyncDownloadString this address
+#endif
+
diff --git a/src/FSharp.PowerPack/AsyncOperations.fsi b/src/FSharp.PowerPack/AsyncOperations.fsi
new file mode 100755
index 0000000..400eb12
--- /dev/null
+++ b/src/FSharp.PowerPack/AsyncOperations.fsi
@@ -0,0 +1,81 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Control
+
+    open System
+    open Microsoft.FSharp.Control
+    
+    /// Represents the reified result of an asynchronous computation
+    [<NoEquality; NoComparison>]
+    type AsyncResult<'T>  =
+        | AsyncOk of 'T
+        | AsyncException of exn
+        | AsyncCanceled of OperationCanceledException
+
+        /// Create an async whose result depends on the value of an AsyncResult.
+        static member Commit : AsyncResult<'T> -> Async<'T>
+
+    [<Sealed>]
+    /// A helper type to store a single result from an asynchronous computation and asynchronously
+    /// access its result.
+    type AsyncResultCell<'T> =
+        /// Record the result in the AsyncResultCell. Subsequent sets of the result are ignored. 
+        ///
+        /// This may result in the scheduled resumption of a waiting asynchronous operation  
+        member RegisterResult:AsyncResult<'T> * ?reuseThread:bool -> unit
+
+        /// Wait for the result and commit it
+        member AsyncResult : Async<'T>
+        /// Create a new result cell
+        new : unit -> AsyncResultCell<'T>
+        
+    [<AutoOpen>]
+    module StreamReaderExtensions =
+        open System.IO
+
+        type System.IO.StreamReader with 
+            /// Return an asynchronous computation that will read to the end of a stream via a fresh I/O thread.
+            member AsyncReadToEnd: unit -> Async<string>
+
+    [<AutoOpen>]
+    module FileExtensions =
+        open System.IO
+        type System.IO.File with 
+            /// Create an async that opens an existing file for reading, via a fresh I/O thread.
+            static member AsyncOpenText: path:string -> Async<StreamReader>
+
+            /// Create an async that opens a <c>System.IO.FileStream</c> on the specified path for read/write access, via a fresh I/O thread.
+            static member AsyncOpenRead: path:string -> Async<FileStream>
+
+            /// Create an async that opens an existing file writing, via a fresh I/O thread.
+            static member AsyncOpenWrite: path:string -> Async<FileStream>
+
+            /// Create an async that returns a <c>System.IO.StreamWriter</c> that appends UTF-8 text to an existing file, via a fresh I/O thread.
+            static member AsyncAppendText: path:string -> Async<StreamWriter>
+
+            /// Create an async that opens a <c>System.IO.FileStream</c> on the specified path, via a fresh I/O thread.
+            /// Pass <c>options=FileOptions.Asynchronous</c> to enable further asynchronous read/write operations
+            /// on the FileStream.
+#if FX_NO_FILE_OPTIONS
+            static member AsyncOpen: path:string * mode:FileMode * ?access: FileAccess * ?share: FileShare * ?bufferSize: int -> Async<FileStream>
+#else
+            static member AsyncOpen: path:string * mode:FileMode * ?access: FileAccess * ?share: FileShare * ?bufferSize: int * ?options: FileOptions -> Async<FileStream>
+#endif
+
+#if FX_NO_WEB_REQUESTS
+#else
+    [<AutoOpen>]
+    module WebRequestExtensions =
+        type System.Net.WebRequest with 
+            /// Return an asynchronous computation that, when run, will wait for a response to the given WebRequest.
+            [<System.Obsolete("The extension method now resides in the 'WebExtensions' module in the F# core library. Please add 'open Microsoft.FSharp.Control.WebExtensions' to access this method")>]
+            member AsyncGetResponse : unit -> Async<System.Net.WebResponse>
+#endif
+    
+#if FX_NO_WEB_CLIENT
+#else
+    [<AutoOpen>]
+    module WebClientExtensions =
+        type System.Net.WebClient with
+            [<System.Obsolete("The extension method now resides in the 'WebExtensions' module in the F# core library. Please add 'open Microsoft.FSharp.Control.WebExtensions' to access this method")>]
+            member AsyncDownloadString : address:System.Uri -> Async<string>
+#endif
diff --git a/src/FSharp.PowerPack/AsyncStreamReader.fs b/src/FSharp.PowerPack/AsyncStreamReader.fs
new file mode 100755
index 0000000..93be139
--- /dev/null
+++ b/src/FSharp.PowerPack/AsyncStreamReader.fs
@@ -0,0 +1,429 @@
+namespace Microsoft.FSharp.Control
+
+open System
+open System.Diagnostics
+open System.IO
+open System.Text
+
+/// <summary>
+/// Implements a TextReader-like API that asynchronously reads characters from 
+/// a byte stream in a particular encoding.
+/// </summary>
+[<Sealed>]
+type AsyncStreamReader(stream:Stream, encoding:Encoding, detectEncodingFromByteOrderMarks:bool, bufferSize:int) =
+    static let defaultBufferSize = 1024;  // Byte buffer size
+    static let defaultFileStreamBufferSize = 4096;
+    static let minBufferSize = 128; 
+
+    // Creates a new StreamReader for the given stream.  The 
+    // character encoding is set by encoding and the buffer size,
+    // in number of 16-bit characters, is set by bufferSize. 
+    // 
+    // Note that detectEncodingFromByteOrderMarks is a very
+    // loose attempt at detecting the encoding by looking at the first 
+    // 3 bytes of the stream.  It will recognize UTF-8, little endian
+    // unicode, and big endian unicode text, but that's it.  If neither
+    // of those three match, it will use the Encoding you provided.
+    // 
+
+    do  if (stream=null || encoding=null) then 
+            raise <| new ArgumentNullException(if (stream=null) then "stream" else "encoding");
+
+        if not stream.CanRead then
+            invalidArg "stream" "stream not readable";
+#if FX_NO_FILESTREAM_ISASYNC
+#else
+        match stream with 
+        | :? System.IO.FileStream as fs when not fs.IsAsync -> 
+            invalidArg "stream" "FileStream not asynchronous. AsyncStreamReader should only be used on FileStream if the IsAsync property returns true. Consider passing 'true' for the async flag in the FileStream constructor"
+        | _ -> 
+            ()
+#endif
+        if (bufferSize <= 0) then
+            raise <| new ArgumentOutOfRangeException("bufferSize");
+
+    let mutable stream = stream
+    let mutable decoder = encoding.GetDecoder();
+    let mutable encoding = encoding
+    let bufferSize = max bufferSize  minBufferSize; 
+
+    // This is the maximum number of chars we can get from one call to
+    // readBuffer.  Used so readBuffer can tell when to copy data into 
+    // a user's char[] directly, instead of our internal char[].
+    let mutable _maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize) 
+    let mutable byteBuffer = Array.zeroCreate<byte> bufferSize;
+    let mutable charBuffer = Array.zeroCreate<char> _maxCharsPerBuffer;
+    let preamble = encoding.GetPreamble();   // Encoding's preamble, which identifies this encoding. 
+    let mutable charPos = 0
+    let mutable charLen = 0
+    // Record the number of valid bytes in the byteBuffer, for a few checks. 
+    let mutable byteLen = 0
+    // This is used only for preamble detection 
+    let mutable bytePos = 0
+
+    // We will support looking for byte order marks in the stream and trying
+    // to decide what the encoding might be from the byte order marks, IF they 
+    // exist.  But that's all we'll do.
+    let mutable _detectEncoding = detectEncodingFromByteOrderMarks;
+
+    // Whether we must still check for the encoding's given preamble at the 
+    // beginning of this file.
+    let mutable _checkPreamble = (preamble.Length > 0); 
+
+    let readerClosed() = invalidOp "reader closed"
+    // Trims n bytes from the front of the buffer.
+    let compressBuffer(n) =
+        Debug.Assert(byteLen >= n, "compressBuffer was called with a number of bytes greater than the current buffer length.  Are two threads using this StreamReader at the same time?");
+        Buffer.BlockCopy(byteBuffer, n, byteBuffer, 0, byteLen - n);
+        byteLen <- byteLen - n; 
+
+    // Trims the preamble bytes from the byteBuffer. This routine can be called multiple times
+    // and we will buffer the bytes read until the preamble is matched or we determine that
+    // there is no match. If there is no match, every byte read previously will be available 
+    // for further consumption. If there is a match, we will compress the buffer for the
+    // leading preamble bytes 
+    let isPreamble() = 
+        if not _checkPreamble then _checkPreamble else
+
+        Debug.Assert(bytePos <= preamble.Length, "_compressPreamble was called with the current bytePos greater than the preamble buffer length.  Are two threads using this StreamReader at the same time?");
+        let len = if (byteLen >= (preamble.Length)) then (preamble.Length - bytePos) else (byteLen  - bytePos); 
+
+        let mutable fin = false
+        let mutable i = 0
+        while i < len && not fin do
+            if (byteBuffer.[bytePos] <> preamble.[bytePos]) then
+                bytePos <- 0;
+                _checkPreamble <- false; 
+                fin <- true
+            if not fin then 
+                i <- i + 1
+                bytePos <- bytePos + 1
+
+        Debug.Assert(bytePos <= preamble.Length, "possible bug in _compressPreamble.  Are two threads using this StreamReader at the same time?");
+
+        if (_checkPreamble) then
+            if (bytePos = preamble.Length) then
+                // We have a match 
+                compressBuffer(preamble.Length);
+                bytePos <- 0;
+                _checkPreamble <- false;
+                _detectEncoding <- false; 
+
+        _checkPreamble;
+
+
+    let detectEncoding() =
+        if (byteLen >= 2) then 
+            _detectEncoding <- false;
+            let mutable changedEncoding = false;
+            if (byteBuffer.[0]=0xFEuy && byteBuffer.[1]=0xFFuy) then
+                // Big Endian Unicode
+
+                encoding <- new UnicodeEncoding(true, true); 
+                compressBuffer(2);
+                changedEncoding <- true; 
+#if FX_NO_UTF32ENCODING
+#else
+            elif (byteBuffer.[0]=0xFFuy && byteBuffer.[1]=0xFEuy) then
+                // Little Endian Unicode, or possibly little endian UTF32
+                if (byteLen >= 4 && byteBuffer.[2] = 0uy && byteBuffer.[3] = 0uy) then
+                    encoding <- new UTF32Encoding(false, true);
+                    compressBuffer(4); 
+                else 
+                    encoding <- new UnicodeEncoding(false, true); 
+                    compressBuffer(2);
+                changedEncoding <- true;
+#endif
+            elif (byteLen >= 3 && byteBuffer.[0]=0xEFuy && byteBuffer.[1]=0xBBuy && byteBuffer.[2]=0xBFuy) then
+                // UTF-8 
+                encoding <- Encoding.UTF8; 
+                compressBuffer(3);
+                changedEncoding <- true; 
+#if FX_NO_UTF32ENCODING
+#else
+            elif (byteLen >= 4 && byteBuffer.[0] = 0uy && byteBuffer.[1] = 0uy && byteBuffer.[2] = 0xFEuy && byteBuffer.[3] = 0xFFuy) then
+                // Big Endian UTF32 
+                encoding <- new UTF32Encoding(true, true);
+                changedEncoding <- true; 
+#endif
+            elif (byteLen = 2) then
+                _detectEncoding <- true; 
+            // Note: in the future, if we change this algorithm significantly,
+            // we can support checking for the preamble of the given encoding.
+
+            if (changedEncoding) then 
+                decoder <- encoding.GetDecoder();
+                _maxCharsPerBuffer <- encoding.GetMaxCharCount(byteBuffer.Length); 
+                charBuffer <- Array.zeroCreate<char> _maxCharsPerBuffer; 
+
+    let readBuffer() = async {
+        charLen <- 0;
+        charPos <- 0; 
+
+        if not _checkPreamble then
+            byteLen <- 0; 
+
+        let fin = ref false
+        while (charLen = 0 && not !fin) do
+            if (_checkPreamble) then 
+                Debug.Assert(bytePos <= preamble.Length, "possible bug in _compressPreamble.  Are two threads using this StreamReader at the same time?");
+                let! len = stream.AsyncRead(byteBuffer, bytePos, byteBuffer.Length - bytePos);
+                Debug.Assert(len >= 0, "Stream.Read returned a negative number!  This is a bug in your stream class.");
+
+                if (len = 0) then
+                    // EOF but we might have buffered bytes from previous 
+                    // attempts to detecting preamble that needs to decoded now 
+                    if (byteLen > 0) then
+                        charLen <-  charLen + decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, charLen); 
+
+                    fin := true
+                
+                byteLen <- byteLen + len;
+            else 
+                Debug.Assert((bytePos = 0), "bytePos can be non zero only when we are trying to _checkPreamble.  Are two threads using this StreamReader at the same time?");
+                let! len = stream.AsyncRead(byteBuffer, 0, byteBuffer.Length); 
+                byteLen <- len
+                Debug.Assert(byteLen >= 0, "Stream.Read returned a negative number!  This is a bug in your stream class.");
+
+                if (byteLen = 0)  then // We're at EOF
+                    fin := true
+
+            // Check for preamble before detect encoding. This is not to override the
+            // user suppplied Encoding for the one we implicitly detect. The user could 
+            // customize the encoding which we will loose, such as ThrowOnError on UTF8
+            if not !fin then 
+                if not (isPreamble()) then
+                    // If we're supposed to detect the encoding and haven't done so yet, 
+                    // do it.  Note this may need to be called more than once.
+                    if (_detectEncoding && byteLen >= 2) then
+                        detectEncoding();
+
+                    charLen <- charLen + decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, charLen);
+
+            if (charLen <> 0) then 
+                fin := true
+
+        return charLen
+
+    } 
+
+
+    let cleanup() = 
+            // Dispose of our resources if this StreamReader is closable.
+            // Note that Console.In should not be closable. 
+            try 
+                // Note that Stream.Close() can potentially throw here. So we need to
+                // ensure cleaning up internal resources, inside the finally block.
+                if (stream <> null) then
+                    stream.Close();
+            
+            finally 
+                if (stream <> null) then
+                    stream <- null; 
+                    encoding <- null;
+                    decoder <- null;
+                    byteBuffer <- null;
+                    charBuffer <- null; 
+                    charPos <- 0;
+                    charLen <- 0; 
+                    //REMOVED: base.Dispose(disposing); 
+
+    // StreamReader by default will ignore illegal UTF8 characters. We don't want to 
+    // throw here because we want to be able to read ill-formed data without choking.
+    // The high level goal is to be tolerant of encoding errors when we read and very strict 
+    // when we write. Hence, default StreamWriter encoding will throw on error.
+
+    new (stream) = new AsyncStreamReader(stream, true) 
+
+    new (stream, detectEncodingFromByteOrderMarks:bool) = new AsyncStreamReader(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, defaultBufferSize)
+
+    new (stream, encoding:Encoding) = new AsyncStreamReader(stream, encoding, true, defaultBufferSize) 
+
+    new (stream, encoding, detectEncodingFromByteOrderMarks) = new AsyncStreamReader(stream, encoding, detectEncodingFromByteOrderMarks, defaultBufferSize) 
+
+(*
+    new (path:string) = new AsyncStreamReader(path, true)
+
+    new (path: string, detectEncodingFromByteOrderMarks: bool) = new AsyncStreamReader (path, Encoding.UTF8, detectEncodingFromByteOrderMarks, defaultBufferSize) 
+
+    new (path:string, encoding:Encoding) = new AsyncStreamReader(path, encoding, true, defaultBufferSize) 
+
+    new (path: string, encoding:Encoding, detectEncodingFromByteOrderMarks: bool)  = new AsyncStreamReader(path, encoding, detectEncodingFromByteOrderMarks, defaultBufferSize) 
+
+    new (path: string, encoding: Encoding, detectEncodingFromByteOrderMarks: bool, bufferSize: int)  =
+        // Don't open a Stream before checking for invalid arguments, 
+        // or we'll create a FileStream on disk and we won't close it until 
+        // the finalizer runs, causing problems for applications.
+        if (path=null || encoding=null) then
+            raise <| new ArgumentNullException((path=null ? "path" : "encoding"));
+        if (path.Length=0) then
+            raise <| new ArgumentException((* Environment.GetResourceString *)("Argument_EmptyPath"));
+        if (bufferSize <= 0)  then
+            raise <| new ArgumentOutOfRangeException("bufferSize", (* Environment.GetResourceString *)("ArgumentOutOfRange_NeedPosNum"));
+
+        Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, defaultFileStreamBufferSize, FileOptions.SequentialScan); 
+        Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize);
+
+*)
+
+    member x.Close() = cleanup()
+
+    interface System.IDisposable with 
+        member x.Dispose() = cleanup()
+
+    member x.CurrentEncoding  = encoding
+    member x.BaseStream = stream
+
+    // DiscardBufferedData tells StreamReader to throw away its internal 
+    // buffer contents.  This is useful if the user needs to seek on the
+    // underlying stream to a known location then wants the StreamReader 
+    // to start reading from this new point.  This method should be called
+    // very sparingly, if ever, since it can lead to very poor performance.
+    // However, it may be the only way of handling some scenarios where
+    // users need to re-read the contents of a StreamReader a second time. 
+    member x.DiscardBufferedData() =
+        byteLen <- 0; 
+        charLen <- 0; 
+        charPos <- 0;
+        decoder <- encoding.GetDecoder(); 
+
+    member x.EndOfStream = async {
+        if (stream = null) then
+            readerClosed(); 
+
+        if (charPos < charLen) then
+            return false
+        else
+            let! numRead = readBuffer(); 
+            return numRead = 0;
+    }
+
+    member x.Peek() = 
+        async {
+            let! emp = x.EndOfStream 
+            return (if emp then -1 else int charBuffer.[charPos])
+        }
+
+    member x.Read() = async {
+        if (stream = null) then
+            readerClosed();
+
+        if (charPos = charLen) then 
+            let! n = readBuffer() 
+            if n = 0 then 
+                return char -1; 
+            else
+                let result = charBuffer.[charPos];
+                charPos <- charPos + 1; 
+                return result;
+        else
+            let result = charBuffer.[charPos];
+            charPos <- charPos + 1; 
+            return result;
+    }
+    
+    // Returns only when count characters have been read or the end of the file was reached. 
+    member x.ReadExactly(buffer:char[], index, count) = async {
+        let i = ref 0
+        let n = ref 0 
+        let count = ref count
+        let first = ref true
+        while !first || (!i > 0 && !n < !count) do 
+            let! j = x.Read(buffer, index + !n, !count - !n)
+            i := j 
+            n := !n + j
+            first := false
+        return !n;
+    } 
+
+    member x.Read(buffer:char[], index, count) = async {
+        if (stream = null) then
+            readerClosed(); 
+        if (buffer=null) then
+            raise <| new ArgumentNullException("buffer");
+        if (index < 0 || count < 0) then
+            raise <| new ArgumentOutOfRangeException((if (index < 0) then "index" else "count"), (* Environment.GetResourceString *)("ArgumentOutOfRange_NeedNonNegNum"));
+        if (buffer.Length - index < count) then
+            raise <| new ArgumentException("index")
+
+        let charsRead = ref 0;
+        let charsReqd = ref count;
+        let fin = ref false
+        while (!charsReqd > 0) && not !fin do
+            let! charsAvail = if (charLen = charPos) then readBuffer() else async { return charLen - charPos }
+            if (charsAvail = 0) then 
+                // We're at EOF
+                fin := true 
+            else  
+                let charsConsumed = min charsAvail !charsReqd
+                Buffer.BlockCopy(charBuffer, charPos * 2, buffer, (index + !charsRead) * 2, charsConsumed*2); 
+                charPos <- charPos + charsConsumed; 
+                charsRead := !charsRead + charsConsumed; 
+                charsReqd := !charsReqd - charsConsumed;
+
+        return !charsRead;
+    } 
+
+    member x.ReadToEnd() = async {
+        if (stream = null) then
+            readerClosed();
+
+        // Call readBuffer, then pull data out of charBuffer. 
+        let sb = new StringBuilder(charLen - charPos);
+        let readNextChunk = 
+            async {
+                sb.Append(charBuffer, charPos, charLen - charPos) |> ignore;
+                charPos <- charLen;  // Note we consumed these characters
+                let! _ = readBuffer() 
+                return ()
+            }
+        do! readNextChunk
+        while charLen > 0 do 
+            do! readNextChunk
+        return sb.ToString();
+    } 
+
+
+    // Reads a line. A line is defined as a sequence of characters followed by 
+    // a carriage return ('\r'), a line feed ('\n'), or a carriage return
+    // immediately followed by a line feed. The resulting string does not 
+    // contain the terminating carriage return and/or line feed. The returned 
+    // value is null if the end of the input stream has been reached.
+    // 
+    member x.ReadLine() = async {
+
+        let! emp = x.EndOfStream
+        if emp then return null else
+        let sb = new StringBuilder()
+        let fin1 = ref false
+        while not !fin1 do 
+            let i = ref charPos;
+            let fin2 = ref false
+            while (!i < charLen) && not !fin2 do 
+                let ch = charBuffer.[!i];
+                // Note the following common line feed chars: 
+                // \n - UNIX   \r\n - DOS   \r - Mac
+                if (ch = '\r' || ch = '\n') then
+                    sb.Append(charBuffer, charPos, !i - charPos) |> ignore; 
+                    charPos <- !i + 1; 
+                    if ch = '\r' then 
+                        let! emp = x.EndOfStream
+                        if not emp && (charBuffer.[charPos] = '\n') then 
+                            charPos <- charPos + 1;
+                    // Found end of line, done
+                    fin2 := true
+                    fin1 := true
+                else
+                    i := !i + 1;
+
+            if not !fin1 then 
+                i := charLen - charPos;
+                sb.Append(charBuffer, charPos, !i) |> ignore; 
+
+                let! n = readBuffer() 
+                fin1 := (n <= 0)
+
+        return sb.ToString(); 
+
+    }
+
diff --git a/src/FSharp.PowerPack/AsyncStreamReader.fsi b/src/FSharp.PowerPack/AsyncStreamReader.fsi
new file mode 100755
index 0000000..a61a160
--- /dev/null
+++ b/src/FSharp.PowerPack/AsyncStreamReader.fsi
@@ -0,0 +1,89 @@
+namespace Microsoft.FSharp.Control
+
+open System
+open System.IO
+open System.Text
+
+/// <summary>
+/// Implements a TextReader-like API that asynchronously reads characters from 
+/// a byte stream in a particular encoding.
+/// </summary>
+[<Sealed>]
+type AsyncStreamReader =
+
+    /// Creates a new AsyncStreamReader for the given stream.  The 
+    /// character encoding is set by encoding and the buffer size,
+    /// in number of 16-bit characters, is set by bufferSize. 
+    /// 
+    /// Note that detectEncodingFromByteOrderMarks is a very
+    /// loose attempt at detecting the encoding by looking at the first 
+    /// 3 bytes of the stream.  It will recognize UTF-8, little endian
+    /// unicode, and big endian unicode text, but that's it.  If neither
+    /// of those three match, it will use the Encoding you provided.
+    new : stream:Stream * encoding:Encoding * detectEncodingFromByteOrderMarks:bool * bufferSize:int -> AsyncStreamReader
+    new : stream:Stream -> AsyncStreamReader
+    new : stream:Stream * detectEncodingFromByteOrderMarks:bool -> AsyncStreamReader
+    new : stream:Stream * encoding:System.Text.Encoding -> AsyncStreamReader
+    new : stream:Stream * encoding:System.Text.Encoding * detectEncodingFromByteOrderMarks:bool -> AsyncStreamReader
+    
+    member Close : unit -> unit
+    member CurrentEncoding : Encoding
+    member BaseStream : Stream
+    
+    ///. DiscardBufferedData tells StreamReader to throw away its internal 
+    ///. buffer contents.  This is useful if the user needs to seek on the
+    /// underlying stream to a known location then wants the StreamReader 
+    /// to start reading from this new point.  This method should be called
+    /// very sparingly, if ever, since it can lead to very poor performance.
+    /// However, it may be the only way of handling some scenarios where
+    /// users need to re-read the contents of a StreamReader a second time. 
+    member DiscardBufferedData : unit -> unit
+    
+    /// An async that produces true if the reader is at the end of stream and false otherwise
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member EndOfStream : Async<bool>
+    
+    /// Creates an async that produces next character from the stream without advancing the stream
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    
+    member Peek : unit -> Async<int> 
+    
+    /// Creates an async that reads next character from the stream
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member Read : unit -> Async<char>
+    
+    /// Creates an async that reads all the charactes that are avilable in the stream up to <c>count</c characters and puts them 
+    /// into <c>buffer</c> starting at <c>index</c>. The async returns the number of characters that are read.
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member Read : buffer:char[] * index:int * count:int -> Async<int>
+    
+    /// Creates an async that reads exactly <c>count</c> characters from the stream unless end of stream is reached and puts them 
+    /// into <c>buffer</c> starting at <c>index</c>. The async returns the number of characters that are read (if end-of-stream is not reached
+    /// that will be <c>count</c>
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member ReadExactly : buffer:char[] * index:int * count:int -> Async<int>
+    
+    /// Creates an async that read all characters in the stream up to the end.
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member ReadToEnd : unit -> Async<string>
+    
+    /// Creates an async that reads next line from the stream
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member ReadLine : unit -> Async<string>
+    
+    interface IDisposable
+    
\ No newline at end of file
diff --git a/src/FSharp.PowerPack/AsyncWorker.fs b/src/FSharp.PowerPack/AsyncWorker.fs
new file mode 100755
index 0000000..96f820e
--- /dev/null
+++ b/src/FSharp.PowerPack/AsyncWorker.fs
@@ -0,0 +1,65 @@
+// (c) Microsoft Corporation 2005-2009. 
+namespace Microsoft.FSharp.Control
+
+    open System
+    open System.Threading
+    open System.IO
+    open Microsoft.FSharp.Control
+    open Microsoft.FSharp.Collections
+
+#if FX_NO_SYNC_CONTEXT
+#else
+    type AsyncWorker<'T>(p : Async<'T>,?cancellationToken) = 
+
+        let cts =
+            match cancellationToken with
+            | None -> new CancellationTokenSource()
+            | Some token ->
+                  let cts = new CancellationTokenSource()
+                  CancellationTokenSource.CreateLinkedTokenSource(token,cts.Token)
+
+        let mutable syncContext : SynchronizationContext = null
+
+        // A standard helper to raise an event on the GUI thread
+
+        let raiseEventOnGuiThread (event:Event<_>) args =
+            syncContext.Post((fun _ -> event.Trigger args),state=null)
+
+        // Trigger one of the following events when the iteration completes.
+        let completed = new Event<'T>()
+        let error     = new Event<_>()
+        let canceled   = new Event<_>()
+        let progress  = new Event<int>()
+
+        let doWork() = 
+            Async.StartWithContinuations
+                ( p, 
+                  (fun res -> raiseEventOnGuiThread completed res),
+                  (fun exn -> raiseEventOnGuiThread error exn),
+                  (fun exn -> raiseEventOnGuiThread canceled exn ),cts.Token)
+                                
+        member x.ReportProgress(progressPercentage) = 
+            raiseEventOnGuiThread progress progressPercentage
+        
+        member x.RunAsync()    = 
+            match syncContext with 
+            | null -> ()
+            | _ -> invalidOp "The operation is already in progress. RunAsync can't be called twice"
+
+            syncContext <- 
+                match SynchronizationContext.Current with 
+                | null -> new SynchronizationContext()
+                | ctxt -> ctxt
+
+            ThreadPool.QueueUserWorkItem(fun args -> doWork())
+
+        member x.CancelAsync(?message:string) = 
+            cts.Cancel()
+
+        member x.ProgressChanged     = progress.Publish
+        member x.Completed  = completed.Publish
+        member x.Canceled   = canceled.Publish
+        member x.Error      = error.Publish
+
+
+#endif
diff --git a/src/FSharp.PowerPack/AsyncWorker.fsi b/src/FSharp.PowerPack/AsyncWorker.fsi
new file mode 100755
index 0000000..7541892
--- /dev/null
+++ b/src/FSharp.PowerPack/AsyncWorker.fsi
@@ -0,0 +1,20 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Control
+
+    open System
+    open System.Threading
+    open Microsoft.FSharp.Control
+
+#if FX_NO_SYNC_CONTEXT
+#else
+    type AsyncWorker<'T> =
+        new : Async<'T> * ?asyncGroup: CancellationToken -> AsyncWorker<'T>
+        member ProgressChanged : IEvent<int> 
+        member Error : IEvent<exn> 
+        member Completed : IEvent<'T> 
+        member Canceled : IEvent<OperationCanceledException> 
+        member RunAsync : unit -> bool
+        member ReportProgress : int -> unit
+        member CancelAsync : ?message:string -> unit
+
+#endif
diff --git a/src/FSharp.PowerPack/CompilerLocationUtils.fs b/src/FSharp.PowerPack/CompilerLocationUtils.fs
new file mode 100755
index 0000000..859ca4b
--- /dev/null
+++ b/src/FSharp.PowerPack/CompilerLocationUtils.fs
@@ -0,0 +1,242 @@
+namespace Internal.Utilities
+open System
+open System.IO
+open System.Configuration
+open System.Reflection
+open Microsoft.Win32
+open System.Runtime.InteropServices
+
+#nowarn "44" // ConfigurationSettings is obsolete but the new stuff is horribly complicated. 
+
+module internal FSharpEnvironment =
+
+    let FSharpCoreLibRunningVersion = 
+        try match (typeof<Microsoft.FSharp.Collections.List<int>>).Assembly.GetName().Version.ToString() with
+            | null -> None
+            | "" -> None
+            | s  -> Some(s)
+        with _ -> None
+
+    // Returns:
+    // -- on 2.0:  "v2.0.50727"
+    // -- on 4.0:  "v4.0.30109" (last 5 digits vary by build)
+    let MSCorLibRunningRuntimeVersion = 
+        typeof<int>.Assembly.ImageRuntimeVersion
+
+    // The F# team version number. This version number is used for
+    //     - the F# version number reported by the fsc.exe and fsi.exe banners in the CTP release
+    //     - the F# version number printed in the HTML documentation generator
+    //     - the .NET DLL version number for all VS2008 DLLs
+    //     - the VS2008 registry key, written by the VS2008 installer
+    //         HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber
+    // Also
+    //     - for Beta2, the language revision number indicated on the F# language spec
+    //
+    // It is NOT the version number listed on FSharp.Core.dll
+    let FSharpTeamVersionNumber = "1.9.9.9"
+
+    // The F# binary format revision number. The first three digits of this form the significant part of the 
+    // format revision number for F# binary signature and optimization metadata. The last digit is not significant.
+    //
+    // WARNING: Do not change this revision number unless you absolutely know what you're doing.
+    let FSharpBinaryMetadataFormatRevision = "2.0.0.0"
+
+    [<DllImport("Advapi32.dll", CharSet = CharSet.Unicode, BestFitMapping = false)>]
+    extern uint32 RegOpenKeyExW(UIntPtr _hKey, string _lpSubKey, uint32 _ulOptions, int _samDesired, UIntPtr & _phkResult);
+
+    [<DllImport("Advapi32.dll", CharSet = CharSet.Unicode, BestFitMapping = false)>]
+    extern uint32 RegQueryValueExW(UIntPtr _hKey, string _lpValueName, uint32 _lpReserved, uint32 & _lpType, IntPtr _lpData, int & _lpchData);
+
+    [<DllImport("Advapi32.dll")>]
+    extern uint32 RegCloseKey(UIntPtr _hKey)
+
+    module Option = 
+        /// Convert string into Option string where null and String.Empty result in None
+        let ofString s = 
+            if String.IsNullOrEmpty(s) then None
+            else Some(s)
+
+            
+        
+
+    // MaxPath accounts for the null-terminating character, for example, the maximum path on the D drive is "D:\<256 chars>\0". 
+    // See: ndp\clr\src\BCL\System\IO\Path.cs
+    let maxPath = 260;
+    let maxDataLength = (new System.Text.UTF32Encoding()).GetMaxByteCount(maxPath)
+    let KEY_WOW64_DEFAULT = 0x0000
+    let KEY_WOW64_32KEY = 0x0200
+    let HKEY_LOCAL_MACHINE = UIntPtr(0x80000002u)
+    let KEY_QUERY_VALUE = 0x1
+    let REG_SZ = 1u
+
+    let GetDefaultRegistryStringValueViaDotNet(subKey: string)  =
+        Option.ofString
+            (try
+                downcast Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\"+subKey,null,null)
+             with e->
+                System.Diagnostics.Debug.Assert(false, sprintf "Failed in GetDefaultRegistryStringValueViaDotNet: %s" (e.ToString()))
+                null)
+
+    let Get32BitRegistryStringValueViaPInvoke(subKey:string) = 
+        Option.ofString
+            (try 
+                // 64 bit flag is not available <= Win2k
+                let options = 
+                    match Environment.OSVersion.Version.Major with
+                    | major when major >= 5 -> KEY_WOW64_32KEY
+                    | _ -> KEY_WOW64_DEFAULT
+
+
+                let mutable hkey = UIntPtr.Zero;
+                let pathResult = Marshal.AllocCoTaskMem(maxDataLength);
+
+                try
+                    let res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,subKey, 0u, KEY_QUERY_VALUE ||| options, & hkey)
+                    if res = 0u then
+                        let mutable uType = REG_SZ;
+                        let mutable cbData = maxDataLength;
+
+                        let res = RegQueryValueExW(hkey, null, 0u, &uType, pathResult, &cbData);
+
+                        if (res = 0u && cbData > 0 && cbData <= maxDataLength) then
+                            Marshal.PtrToStringUni(pathResult, (cbData - 2)/2);
+                        else 
+                            null
+                    else
+                        null
+                finally
+                    if hkey <> UIntPtr.Zero then
+                        RegCloseKey(hkey) |> ignore
+                
+                    if pathResult <> IntPtr.Zero then
+                        Marshal.FreeCoTaskMem(pathResult)
+             with e->
+                System.Diagnostics.Debug.Assert(false, sprintf "Failed in Get32BitRegistryStringValueViaPInvoke: %s" (e.ToString()))
+                null)
+
+    let is32Bit = IntPtr.Size = 4
+    
+    let tryRegKey(subKey:string) = 
+
+        if is32Bit then
+            let s = GetDefaultRegistryStringValueViaDotNet(subKey)
+            // If we got here AND we're on a 32-bit OS then we can validate that Get32BitRegistryStringValueViaPInvoke(...) works
+            // by comparing against the result from GetDefaultRegistryStringValueViaDotNet(...)
+#if DEBUG
+            let viaPinvoke = Get32BitRegistryStringValueViaPInvoke(subKey)
+            System.Diagnostics.Debug.Assert((s = viaPinvoke), sprintf "32bit path: pi=%A def=%A" viaPinvoke s)
+#endif
+            s
+        else
+            Get32BitRegistryStringValueViaPInvoke(subKey) 
+               
+
+    let internal tryCurrentDomain() = 
+        let pathFromCurrentDomain = System.AppDomain.CurrentDomain.BaseDirectory
+        if not(String.IsNullOrEmpty(pathFromCurrentDomain)) then 
+            Some pathFromCurrentDomain
+        else
+            None
+    
+    let internal tryAppConfig (appConfigKey:string) = 
+
+        let locationFromAppConfig = ConfigurationSettings.AppSettings.[appConfigKey]
+        System.Diagnostics.Debug.Print(sprintf "Considering appConfigKey %s which has value '%s'" appConfigKey locationFromAppConfig) 
+
+        if String.IsNullOrEmpty(locationFromAppConfig) then 
+            None
+        else
+            let exeAssemblyFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
+            let locationFromAppConfig = locationFromAppConfig.Replace("{exepath}", exeAssemblyFolder)
+            System.Diagnostics.Debug.Print(sprintf "Using path %s" locationFromAppConfig) 
+            Some locationFromAppConfig
+
+    let BinFolderOfDefaultFSharpCoreReferenceAssembly = 
+        try
+            let result = tryAppConfig "fsharp-core-referenceassembly-location"
+            match result with
+            | Some _ -> result
+            | None ->
+                let keyCTP = @"Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber 
+                let keyRedist = @"SOFTWARE\Microsoft\.NETFramework\" + MSCorLibRunningRuntimeVersion + @"\AssemblyFoldersEx\Microsoft Visual F# 4.0"
+                
+                let result = tryRegKey keyRedist
+                match result with 
+                | Some _ ->  result 
+                | None -> 
+                    let result = tryRegKey keyCTP
+                    match result with
+                    | Some _ -> result
+                    | None -> 
+                        tryCurrentDomain ()
+
+        with e -> 
+            System.Diagnostics.Debug.Assert(false, "Error while determining default location of FSharp.Core reference assembly")
+            None
+
+    // The default location of FSharp.Core.dll and fsc.exe based on the version of fsc.exe that is running
+    // Used for
+    //     - location of design-time copies of FSharp.Core.dll and FSharp.Compiler.Interactive.Settings.dll for the default assumed environment for scripts
+    //     - default ToolPath in tasks in FSharp.Build.dll (for Fsc tasks)
+    //     - default F# binaries directory in service.fs (REVIEW: check this)
+    //     - default location of fsi.exe in FSharp.VS.FSI.dll
+    //     - default location of fsc.exe in FSharp.Compiler.CodeDom.dll
+    let BinFolderOfDefaultFSharpCompiler = 
+        // Check for an app.config setting to redirect the default compiler location
+        // Like fsharp-compiler-location
+        try 
+            let result = tryAppConfig "fsharp-compiler-location"
+            match result with 
+            | Some _ ->  result 
+            | None -> 
+
+                // Note: If the keys below change, be sure to update code in:
+                // Property pages (ApplicationPropPage.vb)
+
+                let key20 = @"Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber 
+                let key40 = @"Software\Microsoft\FSharp\2.0\Runtime\v4.0"
+                let key1,key2 = 
+                    match FSharpCoreLibRunningVersion with 
+                    | None -> key20,key40 
+                    | Some v -> if v.Length > 1 && v.[0] <= '3' then key20,key40 else key40,key20
+                
+                let result = tryRegKey key1
+                match result with 
+                | Some _ ->  result 
+                | None -> 
+                    let result =  tryRegKey key2
+                    match result with 
+                    | Some _ ->  result 
+                    | None -> 
+
+            // This was failing on rolling build for staging because the prototype compiler doesn't have the key. Disable there.
+            #if FX_ATLEAST_40_COMPILER_LOCATION
+                        System.Diagnostics.Debug.Assert(result<>None, sprintf "Could not find location of compiler at '%s' or '%s'" key1 key2)
+            #endif                                
+                          
+                            // For the prototype compiler, we can just use the current domain
+                        tryCurrentDomain()
+        with e -> 
+            System.Diagnostics.Debug.Assert(false, "Error while determining default location of F# compiler")
+            None
+
+    let BinFolderOfFSharpPowerPack = 
+        try 
+            // Check for an app.config setting to redirect the default compiler location
+            // Like fsharp-compiler-location
+            let result = tryAppConfig "fsharp-powerpack-location"
+            match result with 
+            | Some _ ->  result 
+            | None -> 
+
+                let key20 = @"Software\Microsoft\.NETFramework\AssemblyFolders\FSharp.PowerPack-" + FSharpTeamVersionNumber 
+                let result = tryRegKey key20
+                match result with 
+                | Some _ ->  result 
+                | None -> 
+                      
+                    tryCurrentDomain()
+
+        with e -> 
+            System.Diagnostics.Debug.Assert(false, "Error while determining default location of F# power pack tools")
+            None
diff --git a/src/FSharp.PowerPack/FSharp.PowerPack.fsproj b/src/FSharp.PowerPack/FSharp.PowerPack.fsproj
new file mode 100755
index 0000000..7ae61c3
--- /dev/null
+++ b/src/FSharp.PowerPack/FSharp.PowerPack.fsproj
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{649FA588-F02E-457C-9FCF-87E46407481F}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>FSharp.PowerPack</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TreatWarningsAsErrors>
+    </TreatWarningsAsErrors>
+    <DocumentationFile>FSharp.PowerPack.xml</DocumentationFile>
+    <NoWarn>$(NoWarn);9;44;60;35;42;62;86;47;40;51</NoWarn>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="AssemblyInfo.fs" />
+    <Compile Include="StructuredFormat.fsi" />
+    <Compile Include="StructuredFormat.fs" />
+    <Compile Include="math\q.fsi">
+      <Link>q.fsi</Link>
+    </Compile>
+    <Compile Include="math\q.fs">
+      <Link>q.fs</Link>
+    </Compile>
+    <Compile Include="ResizeArray.fsi" />
+    <Compile Include="ResizeArray.fs" />
+    <Compile Include="HashMultiMap.fsi" />
+    <Compile Include="HashMultiMap.fs" />
+    <Compile Include="AsyncOperations.fsi" />
+    <Compile Include="AsyncOperations.fs" />
+    <Compile Include="AsyncWorker.fsi" />
+    <Compile Include="AsyncWorker.fs" />
+    <Compile Include="AsyncStreamReader.fsi" />
+    <Compile Include="AsyncStreamReader.fs" />
+    <Compile Include="HashSet.fsi" />
+    <Compile Include="HashSet.fs" />
+    <Compile Include="TaggedCollections.fsi" />
+    <Compile Include="TaggedCollections.fs" />
+    <Compile Include="TaggedHash.fsi" />
+    <Compile Include="TaggedHash.fs" />
+    <Compile Include="Measure.fsi" />
+    <Compile Include="Measure.fs" />
+    <Compile Include="SI.fs" />
+    <Compile Include="PhysicalConstants.fs" />
+    <Compile Include="Lazy.fsi" />
+    <Compile Include="Lazy.fs" />
+    <Compile Include="Permutation.fsi" />
+    <Compile Include="Permutation.fs" />
+    <Compile Include="math\INumeric.fsi">
+      <Link>INumeric.fsi</Link>
+    </Compile>
+    <Compile Include="math\INumeric.fs">
+      <Link>INumeric.fs</Link>
+    </Compile>
+    <Compile Include="math\complex.fsi">
+      <Link>complex.fsi</Link>
+    </Compile>
+    <Compile Include="math\complex.fs">
+      <Link>complex.fs</Link>
+    </Compile>
+    <Compile Include="math\associations.fsi">
+      <Link>associations.fsi</Link>
+    </Compile>
+    <Compile Include="math\associations.fs">
+      <Link>associations.fs</Link>
+    </Compile>
+    <Compile Include="math\matrix.fsi">
+      <Link>matrix.fsi</Link>
+    </Compile>
+    <Compile Include="math\matrix.fs">
+      <Link>matrix.fs</Link>
+    </Compile>
+    <Compile Include="NativeArray.fsi" />
+    <Compile Include="NativeArray.fs" />
+    <Compile Include="math\NativeArrayExtensions.fsi">
+      <Link>NativeArrayExtensions.fsi</Link>
+    </Compile>
+    <Compile Include="math\NativeArrayExtensions.fs">
+      <Link>NativeArrayExtensions.fs</Link>
+    </Compile>
+    <Compile Include="Lexing.fsi" />
+    <Compile Include="Lexing.fs" />
+    <Compile Include="Parsing.fsi" />
+    <Compile Include="Parsing.fs" />
+    <Compile Include="Arg.fsi" />
+    <Compile Include="Arg.fs" />
+    <Compile Include="LazyList.fsi" />
+    <Compile Include="LazyList.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Numerics" Condition="'$(TargetFrameworkVersion)' == 'v4.0'" />
+    <Reference Condition="'$(TargetFramework)' == 'Silverlight'" Include="System.Net" />    
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Condition="'$(TargetFramework)'=='Silverlight'" Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.Common.targets"/>
+</Project>
\ No newline at end of file
diff --git a/src/FSharp.PowerPack/FSharp.PowerPack.fsproj.vspscc b/src/FSharp.PowerPack/FSharp.PowerPack.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FSharp.PowerPack/FSharp.PowerPack.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FSharp.PowerPack/HashMultiMap.fs b/src/FSharp.PowerPack/HashMultiMap.fs
new file mode 100755
index 0000000..96f5d99
--- /dev/null
+++ b/src/FSharp.PowerPack/HashMultiMap.fs
@@ -0,0 +1,166 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Collections.Generic
+open Microsoft.FSharp.Collections
+                                 
+// Each entry in the HashMultiMap dictionary has at least one entry. Under normal usage each entry has _only_
+// one entry. So use two hash tables: one for the main entries and one for the overflow.
+[<Sealed>]
+type HashMultiMap<'Key,'Value>(n: int, hasheq: IEqualityComparer<'Key>) = 
+    let firstEntries = new Dictionary<_,_>(n,hasheq);
+    let rest = new Dictionary<_,_>(3,hasheq);
+ 
+    new (hasheq : IEqualityComparer<'Key>) = new HashMultiMap<'Key,'Value>(11, hasheq)
+    new (seq : seq<'Key * 'Value>, hasheq : IEqualityComparer<'Key>) as x = 
+        new HashMultiMap<'Key,'Value>(11, hasheq)
+        then seq |> Seq.iter (fun (k,v) -> x.Add(k,v))
+
+    new (seq : seq<'Key * 'Value>) =  failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+    new (n:int) = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+    new () = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+
+    static member Create (seq : seq<'Key * 'Value>) =  failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+    static member Create (n:int) = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+    static member Create () = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+
+
+    member x.GetRest(k) = 
+        let mutable res = []
+        let ok = rest.TryGetValue(k,&res)
+        if ok then res else []
+
+    member x.Add(y,z) = 
+        let mutable res = Unchecked.defaultof<'Value>
+        let ok = firstEntries.TryGetValue(y,&res)
+        if ok then 
+            rest.[y] <- res :: x.GetRest(y)
+        firstEntries.[y] <- z
+
+    member x.Clear() = 
+         firstEntries.Clear()
+         rest.Clear()
+
+    member x.FirstEntries = firstEntries
+    member x.Rest = rest
+    member x.Copy() = 
+        let res = new HashMultiMap<'Key,'Value>(firstEntries.Count,firstEntries.Comparer) 
+        for kvp in firstEntries do 
+             res.FirstEntries.Add(kvp.Key,kvp.Value)
+        for kvp in rest do 
+             res.Rest.Add(kvp.Key,kvp.Value)
+        res
+
+    member x.Item 
+        with get(y : 'Key) = 
+            let mutable res = Unchecked.defaultof<'Value>
+            let ok = firstEntries.TryGetValue(y,&res)
+            if ok then res else raise (new System.Collections.Generic.KeyNotFoundException("The item was not found in collection"))
+        and set (y:'Key) (z:'Value) = 
+            x.Replace(y,z)
+
+    member x.FindAll(y) = 
+        let mutable res = Unchecked.defaultof<'Value>
+        let ok = firstEntries.TryGetValue(y,&res)
+        if ok then res :: x.GetRest(y) else []
+
+    member x.Fold f acc = 
+        let mutable res = acc
+        for kvp in firstEntries do
+            res <- f kvp.Key kvp.Value res
+            match x.GetRest(kvp.Key)  with
+            | [] -> ()
+            | rest -> 
+                for z in rest do
+                    res <- f kvp.Key z res
+        res
+
+    member x.Iterate(f) =  
+        for kvp in firstEntries do
+            f kvp.Key kvp.Value
+            match x.GetRest(kvp.Key)  with
+            | [] -> ()
+            | rest -> 
+                for z in rest do
+                    f kvp.Key z
+
+    member x.Contains(y) = firstEntries.ContainsKey(y)
+
+    member x.ContainsKey(y) = firstEntries.ContainsKey(y)
+
+    member x.Remove(y) = 
+        let mutable res = Unchecked.defaultof<'Value>
+        let ok = firstEntries.TryGetValue(y,&res)
+        // Note, if not ok then nothing to remove - nop
+        if ok then 
+            // We drop the FirstEntry. Here we compute the new FirstEntry and residue MoreEntries
+            let mutable res = []
+            let ok = rest.TryGetValue(y,&res)
+            if ok then 
+                match res with 
+                | [h] -> 
+                    firstEntries.[y] <- h; 
+                    rest.Remove(y) |> ignore
+                | (h::t) -> 
+                    firstEntries.[y] <- h
+                    rest.[y] <- t
+                | _ -> 
+                    // note: broken invariant
+                    ()
+            else
+                firstEntries.Remove(y) |> ignore 
+
+    member x.Replace(y,z) = 
+        firstEntries.[y] <- z
+
+    member x.TryFind(y) = 
+        let mutable res = Unchecked.defaultof<'Value>
+        let ok = firstEntries.TryGetValue(y,&res)
+        if ok then Some(res) else None
+
+    member x.Count = firstEntries.Count
+
+    interface IEnumerable<KeyValuePair<'Key, 'Value>> with
+        member s.GetEnumerator() = 
+            let elems = new System.Collections.Generic.List<_>(firstEntries.Count + rest.Count)
+            for kvp in firstEntries do
+                elems.Add(kvp)
+                for z in s.GetRest(kvp.Key) do
+                   elems.Add(KeyValuePair(kvp.Key, z))
+            (elems.GetEnumerator() :> IEnumerator<_>)
+
+    interface System.Collections.IEnumerable with
+        member s.GetEnumerator() = ((s :> seq<_>).GetEnumerator() :> System.Collections.IEnumerator)
+
+    interface IDictionary<'Key, 'Value> with 
+        member s.Item 
+            with get x = s.[x]            
+            and  set x v = s.[x] <- v
+            
+        member s.Keys = ([| for kvp in s -> kvp.Key |] :> ICollection<'Key>)
+        member s.Values = ([| for kvp in s -> kvp.Value |] :> ICollection<'Value>)
+        member s.Add(k,v) = s.[k] <- v
+        member s.ContainsKey(k) = s.ContainsKey(k)
+        member s.TryGetValue(k,r) = if s.ContainsKey(k) then (r <- s.[k]; true) else false
+        member s.Remove(k:'Key) = 
+            let res = s.ContainsKey(k) in 
+            s.Remove(k); res
+
+    interface ICollection<KeyValuePair<'Key, 'Value>> with 
+        member s.Add(x) = s.[x.Key] <- x.Value
+        member s.Clear() = s.Clear()            
+        member s.Remove(x) = 
+            let res = s.ContainsKey(x.Key) 
+            if res && Unchecked.equals s.[x.Key] x.Value then 
+                s.Remove(x.Key); 
+            res
+        member s.Contains(x) = 
+            s.ContainsKey(x.Key) && 
+            Unchecked.equals s.[x.Key] x.Value
+        member s.CopyTo(arr,arrIndex) = s |> Seq.iteri (fun j x -> arr.[arrIndex+j] <- x)
+        member s.IsReadOnly = false
+        member s.Count = s.Count
+
diff --git a/src/FSharp.PowerPack/HashMultiMap.fsi b/src/FSharp.PowerPack/HashMultiMap.fsi
new file mode 100755
index 0000000..34554dc
--- /dev/null
+++ b/src/FSharp.PowerPack/HashMultiMap.fsi
@@ -0,0 +1,84 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+/// This namespace contains FSharp.PowerPack extensions for the F# collection types
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Collections.Generic
+
+
+/// Hash tables, by default based on F# structural "hash" and (=) functions. 
+/// The table may map a single key to multiple bindings.
+[<Sealed>]
+type HashMultiMap<'Key,'Value> =
+    /// Create a new empty mutable HashMultiMap with the given key hash/equality functions
+    new : comparer:IEqualityComparer<'Key> -> HashMultiMap<'Key,'Value>
+    
+    /// Create a new empty mutable HashMultiMap with an internal bucket array of the given approximate size
+    /// and with the given key hash/equality functions
+    new : size:int * comparer:IEqualityComparer<'Key> -> HashMultiMap<'Key,'Value>
+    
+    /// Build a map that contains the bindings of the given IEnumerable
+    new : entries:seq<'Key * 'Value> * comparer:IEqualityComparer<'Key> -> HashMultiMap<'Key,'Value>
+
+    /// Make a shallow copy of the collection
+    member Copy    : unit    -> HashMultiMap<'Key,'Value>
+    
+    /// Add a binding for the element to the table
+    member Add     : 'Key * 'Value -> unit
+    
+    /// Clear all elements from the collection
+    member Clear   : unit    -> unit
+    
+    /// Test if the collection contains any bindings for the given element
+    member ContainsKey: 'Key -> bool
+
+    /// Remove the latest binding (if any) for the given element from the table
+    member Remove : 'Key -> unit
+
+    /// Replace the latest binding (if any) for the given element.
+    member Replace : 'Key * 'Value -> unit
+
+    /// Lookup or set the given element in the table. Set replaces all existing bindings for a value with a single
+    /// bindings. Raise <c>KeyNotFoundException</c> if the element is not found.
+    member Item : 'Key -> 'Value with get,set
+
+    /// Lookup the given element in the table, returning the result as an Option
+    member TryFind : 'Key      -> 'Value option
+    
+    /// Find all bindings for the given element in the table, if any
+    member FindAll : 'Key      -> 'Value list
+
+    /// Apply the given function to each element in the collection threading the accumulating parameter
+    /// through the sequence of function applications
+    member Fold    : ('Key -> 'Value -> 'State -> 'State) -> 'State -> 'State
+
+    /// The total number of keys in the hash table
+    member Count   : int
+
+    ///Apply the given function to each binding in the hash table 
+    member Iterate : ('Key -> 'Value -> unit) -> unit
+
+    interface IDictionary<'Key, 'Value>         
+    interface ICollection<KeyValuePair<'Key, 'Value>> 
+    interface IEnumerable<KeyValuePair<'Key, 'Value>>         
+    interface System.Collections.IEnumerable 
+    
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    new : unit -> HashMultiMap<'Key,'Value>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(size, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    new : size:int -> HashMultiMap<'Key,'Value>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(entries, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    new : entries:seq<'Key * 'Value> -> HashMultiMap<'Key,'Value>
+
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    static member Create : unit -> HashMultiMap<'Key,'Value>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(size, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    static member Create : size:int -> HashMultiMap<'Key,'Value>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(entries, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    static member Create : entries:seq<'Key * 'Value> -> HashMultiMap<'Key,'Value>
diff --git a/src/FSharp.PowerPack/HashSet.fs b/src/FSharp.PowerPack/HashSet.fs
new file mode 100755
index 0000000..410aae2
--- /dev/null
+++ b/src/FSharp.PowerPack/HashSet.fs
@@ -0,0 +1,54 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Collections
+open System.Collections.Generic
+
+// HashSets are currently implemented using the .NET Dictionary type. 
+[<Sealed>]
+type HashSet<'T>(t: Dictionary<'T,int>) = 
+
+    new (hasheq: IEqualityComparer<'T>) = 
+        new HashSet<_>(new Dictionary<_,_>(hasheq))
+
+    new (size:int,hasheq: IEqualityComparer<'T>) = 
+        new HashSet<_>(new Dictionary<_,_>(size,hasheq))
+
+    new (elements:seq<'T>, hasheq: IEqualityComparer<'T>) as t = 
+        new HashSet<_>(new Dictionary<_,_>(hasheq)) 
+        then 
+           for x in elements do t.Add x
+
+    new (size:int) = failwith "unreachable"; new HashSet<'T>(11)
+
+    new () = failwith "unreachable"; new HashSet<'T>(11)
+
+    new (seq:seq<'T>) = failwith "unreachable"; new HashSet<'T>(11)
+        
+    member x.Add(y)    = t.[y] <- 0
+
+    member x.Clear() = t.Clear()
+
+    member x.Copy() : HashSet<'T>  = 
+        let t2 = new Dictionary<'T,int>(t.Count,t.Comparer) in 
+        t |> Seq.iter (fun kvp -> t2.[kvp.Key] <- 0); 
+        new HashSet<'T>(t2)
+
+    member x.Fold f acc = 
+        let mutable res = acc
+        for kvp in t do
+            res <- f kvp.Key res
+        res
+
+    member x.Iterate(f) =  t |> Seq.iter (fun kvp -> f kvp.Key)
+
+    member x.Contains(y) = t.ContainsKey(y)
+    member x.Remove(y) = t.Remove(y) |> ignore
+    member x.Count = t.Count
+    interface IEnumerable<'T> with
+        member x.GetEnumerator() = t.Keys.GetEnumerator() :> IEnumerator<_>
+    interface System.Collections.IEnumerable with
+        member x.GetEnumerator() = t.Keys.GetEnumerator()  :> IEnumerator 
diff --git a/src/FSharp.PowerPack/HashSet.fsi b/src/FSharp.PowerPack/HashSet.fsi
new file mode 100755
index 0000000..2403425
--- /dev/null
+++ b/src/FSharp.PowerPack/HashSet.fsi
@@ -0,0 +1,59 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Collections.Generic
+
+/// Mutable hash sets based by default on F# structural "hash" and (=) functions. Implemented via a hash table and/or Dictionary.
+[<Sealed>]
+[<Obsolete("The HashSet<_> type from the F# Power Pack is now deprecated. Use the System.Collections.Generic.HashSet<_> type from System.Core.dll instead.")>]
+type HashSet<'T>  =
+
+    /// Create a new empty mutable hash set using the given key hash/equality functions 
+    new : comparer:IEqualityComparer<'T> -> HashSet<'T>
+
+    /// Create a new empty mutable hash set with an internal bucket array of the given approximate size
+    /// and with the given key hash/equality functions 
+    new : size:int * comparer:IEqualityComparer<'T> -> HashSet<'T>
+
+    /// Create a new mutable hash set with the given elements and using the given key hash/equality functions 
+    new : elements:seq<'T> * comparer:IEqualityComparer<'T>  -> HashSet<'T>
+    
+    /// Make a shallow copy of the set
+    member Copy    : unit -> HashSet<'T>
+    
+    /// Add an element to the collection
+    member Add     : 'T   -> unit
+    
+    /// Clear all elements from the set
+    member Clear   : unit -> unit
+    
+    /// Test if the set contains the given element
+    member Contains: 'T   -> bool
+    
+    /// Remove the given element from the set
+    member Remove  : 'T   -> unit
+    
+    /// Apply the given function to the set threading the accumulating parameter
+    /// through the sequence of function applications
+    member Fold    : ('T -> 'State -> 'State) -> 'State -> 'State
+
+    /// The total number of elements in the set
+    member Count   : int
+
+    /// Apply the given function to each binding in the hash table 
+    member Iterate : ('T -> unit) -> unit
+
+    interface IEnumerable<'T> 
+    interface System.Collections.IEnumerable 
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashSet<_>(HashIdentity.Structural) to create a HashSet using F# generic hashing and equality", true)>]
+    new : unit -> HashSet<'T>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashSet<_>(size, HashIdentity.Structural) to create a HashSet using F# generic hashing and equality", true)>]
+    new : size:int -> HashSet<'T>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashSet<_>(elements, HashIdentity.Structural) to create a HashSet using F# generic hashing and equality", true)>]
+    new : elements:seq<'T> -> HashSet<'T>
+
diff --git a/src/FSharp.PowerPack/Lazy.fs b/src/FSharp.PowerPack/Lazy.fs
new file mode 100755
index 0000000..3f9273a
--- /dev/null
+++ b/src/FSharp.PowerPack/Lazy.fs
@@ -0,0 +1,6 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Core.Lazy
+
+let force (x: Lazy<'T>) = x.Force()
diff --git a/src/FSharp.PowerPack/Lazy.fsi b/src/FSharp.PowerPack/Lazy.fsi
new file mode 100755
index 0000000..01d7bfe
--- /dev/null
+++ b/src/FSharp.PowerPack/Lazy.fsi
@@ -0,0 +1,7 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Core.Lazy
+
+/// See Lazy.Force
+val force: Lazy<'T> -> 'T
diff --git a/src/FSharp.PowerPack/LazyList.fs b/src/FSharp.PowerPack/LazyList.fs
new file mode 100755
index 0000000..d0ea6f6
--- /dev/null
+++ b/src/FSharp.PowerPack/LazyList.fs
@@ -0,0 +1,262 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Collections.Generic
+
+#nowarn "21" // recursive initialization
+#nowarn "40" // recursive initialization
+
+exception UndefinedException
+
+[<NoEquality; NoComparison>]
+type LazyList<'T> =
+    { mutable status : LazyCellStatus< 'T > }
+    
+    member x.Value = 
+        match x.status with 
+        | LazyCellStatus.Value v -> v
+        | _ -> 
+            lock x (fun () -> 
+                match x.status with 
+                | LazyCellStatus.Delayed f -> 
+                    x.status <- Exception UndefinedException; 
+                    try 
+                        let res = f () 
+                        x.status <- LazyCellStatus.Value res; 
+                        res 
+                    with e -> 
+                        x.status <- LazyCellStatus.Exception(e); 
+                        reraise()
+                | LazyCellStatus.Value v -> v
+                | LazyCellStatus.Exception e -> raise e)
+    
+    member s.GetEnumeratorImpl() = 
+        let getCell (x : LazyList<'T>) = x.Value
+        let toSeq s = Seq.unfold (fun ll -> match getCell ll with CellEmpty -> None | CellCons(a,b) -> Some(a,b)) s 
+        (toSeq s).GetEnumerator()
+            
+    interface IEnumerable<'T> with
+        member s.GetEnumerator() = s.GetEnumeratorImpl()
+
+    interface System.Collections.IEnumerable with
+        override s.GetEnumerator() = (s.GetEnumeratorImpl() :> System.Collections.IEnumerator)
+
+
+and 
+    [<NoEquality; NoComparison>]
+    LazyCellStatus<'T> =
+    | Delayed of (unit -> LazyListCell<'T> )
+    | Value of LazyListCell<'T> 
+    | Exception of System.Exception
+
+
+and 
+    [<NoEquality; NoComparison>]
+    LazyListCell<'T> = 
+    | CellCons of 'T * LazyList<'T> 
+    | CellEmpty
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module LazyList = 
+
+    let lzy f = { status = Delayed f }
+    let force (x: LazyList<'T>) = x.Value
+
+    let notlazy v = { status = Value v }
+    
+    type EmptyValue<'T>() = 
+        static let value : LazyList<'T> = notlazy CellEmpty
+        static member Value : LazyList<'T> = value
+        
+    [<NoEquality; NoComparison>]
+    type LazyItem<'T> = Cons of 'T * LazyList<'T> | Empty
+    type 'T item = 'T LazyItem
+    let get (x : LazyList<'T>) = match force x with CellCons (a,b) -> Some(a,b) | CellEmpty -> None
+    let getCell (x : LazyList<'T>) = force x 
+    let empty<'T> : LazyList<'T> = EmptyValue<'T>.Value
+    let consc x l = CellCons(x,l)
+    let cons x l = lzy(fun () -> (consc x l))
+    let consDelayed x l = lzy(fun () -> (consc x (lzy(fun () ->  (force (l()))))))
+    let consf x l = consDelayed x l
+
+    let rec unfold f z = 
+      lzy(fun () -> 
+          match f z with
+          | None       -> CellEmpty
+          | Some (x,z) -> CellCons (x,unfold f z))
+
+    let rec append l1  l2 = lzy(fun () ->  (appendc l1 l2))
+    and appendc l1 l2 =
+      match getCell l1 with
+      | CellEmpty -> force l2
+      | CellCons(a,b) -> consc a (append b l2)
+
+    let delayed f = lzy(fun () ->  (getCell (f())))
+    let repeat x = 
+      let rec s = cons x (delayed (fun () -> s)) in s
+
+    let rec map f s = 
+      lzy(fun () ->  
+        match getCell s with
+        | CellEmpty -> CellEmpty
+        | CellCons(a,b) -> consc (f a) (map f b))
+
+    let rec map2 f s1 s2 =  
+      lzy(fun () -> 
+        match getCell s1, getCell s2  with
+        | CellCons(a1,b1),CellCons(a2,b2) -> consc (f a1 a2) (map2 f b1 b2)
+        | _ -> CellEmpty)
+
+    let rec zip s1 s2 = 
+      lzy(fun () -> 
+        match getCell s1, getCell s2  with
+        | CellCons(a1,b1),CellCons(a2,b2) -> consc (a1,a2) (zip b1 b2)
+        | _ -> CellEmpty)
+    let combine s1 s2 = zip s1 s2
+
+    let rec concat s1 = 
+      lzy(fun () -> 
+        match getCell s1 with
+        | CellCons(a,b) -> appendc a (concat b)
+        | CellEmpty -> CellEmpty)
+      
+    let rec filter p s1= lzy(fun () ->  filterc p s1)
+    and filterc p s1 =
+        match getCell s1 with
+        | CellCons(a,b) -> if p a then consc a (filter p b) else filterc p b
+        | CellEmpty -> CellEmpty
+      
+    let rec tryFind p s1 =
+        match getCell s1 with
+        | CellCons(a,b) -> if p a then Some a else tryFind p b
+        | CellEmpty -> None
+
+    let first p s1 = tryFind p s1
+
+    let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
+
+    let find p s1 =
+        match tryFind p s1 with
+        | Some a -> a
+        | None   -> indexNotFound()
+
+    let rec scan f acc s1 = 
+      lzy(fun () -> 
+        match getCell s1 with
+        | CellCons(a,b) -> let acc' = f acc a in consc acc (scan f acc' b)
+        | CellEmpty -> consc acc empty)
+
+    let folds f acc s1 = scan f acc s1 // deprecated
+
+    let head s = 
+      match getCell s with
+      | CellCons(a,_) -> a
+      | CellEmpty -> invalidArg "s" "the list is empty"
+
+    let tail s = 
+      match getCell s with
+      | CellCons(_,b) -> b
+      | CellEmpty -> invalidArg "s" "the list is empty"
+
+    let isEmpty s =
+      match getCell s with
+      | CellCons _ -> false
+      | CellEmpty -> true
+
+    let rec take n s = 
+      lzy(fun () -> 
+        if n < 0 then invalidArg "n" "the number must not be negative"
+        elif n = 0 then CellEmpty 
+        else
+          match getCell s with
+          | CellCons(a,s) -> consc a (take (n-1) s)
+          | CellEmpty -> invalidArg "n" "not enough items in the list" )
+
+    let rec skipc n s =
+      if n = 0 then force s 
+      else  
+        match getCell s with
+        | CellCons(_,s) -> skipc (n-1) s
+        | CellEmpty -> invalidArg "n" "not enough items in the list"
+
+    let rec skip n s = 
+      lzy(fun () -> 
+        if n < 0 then invalidArg "n" "the value must not be negative"
+        else skipc n s)
+
+    let rec ofList l = 
+      lzy(fun () -> 
+        match l with [] -> CellEmpty | h :: t -> consc h (ofList t))
+      
+    let toList s = 
+      let rec loop s acc = 
+          match getCell s with
+          | CellEmpty -> List.rev acc
+          | CellCons(h,t) -> loop t (h::acc)
+      loop s []
+      
+    let rec iter f s = 
+      match getCell s with
+      | CellEmpty -> ()
+      | CellCons(h,t) -> f h; iter f t
+      
+    let rec copyFrom i a = 
+      lzy(fun () -> 
+        if i >= Array.length a then CellEmpty 
+        else consc a.[i] (copyFrom (i+1) a))
+      
+    let rec copyTo (arr: _[]) s i = 
+      match getCell s with
+      | CellEmpty -> ()
+      | CellCons(a,b) -> arr.[i] <- a; copyTo arr b (i+1)
+
+    let ofArray a = copyFrom 0 a
+    let toArray s = Array.ofList (toList s)
+      
+    let rec lengthAux n s = 
+      match getCell s with
+      | CellEmpty -> n
+      | CellCons(_,b) -> lengthAux (n+1) b
+
+    let length s = lengthAux 0 s
+
+    let toSeq (s: LazyList<'T>) = (s :> IEnumerable<_>)
+
+    // Note: this doesn't dispose of the IEnumerator if the iteration is not run to the end
+    let rec ofFreshIEnumerator (e : IEnumerator<_>) = 
+      lzy(fun () -> 
+        if e.MoveNext() then 
+          consc e.Current (ofFreshIEnumerator e)
+        else 
+           e.Dispose()
+           CellEmpty)
+      
+    let ofSeq (c : IEnumerable<_>) =
+      ofFreshIEnumerator (c.GetEnumerator()) 
+      
+    let (|Cons|Nil|) l = match getCell l with CellCons(a,b) -> Cons(a,b) | CellEmpty -> Nil
+
+
+    let hd s = head s
+
+    let tl s = tail s
+
+    let drop n s = skip n s
+
+    let nonempty s = not (isEmpty s)
+
+    let of_list l = ofList l
+
+    let of_seq l = ofSeq l
+
+    let of_array l = ofArray l
+
+    let to_seq l = toSeq l
+
+    let to_list l = toList l
+
+    let to_array l = toArray l
+
+
diff --git a/src/FSharp.PowerPack/LazyList.fsi b/src/FSharp.PowerPack/LazyList.fsi
new file mode 100755
index 0000000..725aa9e
--- /dev/null
+++ b/src/FSharp.PowerPack/LazyList.fsi
@@ -0,0 +1,189 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Collections
+
+open System.Collections.Generic
+
+/// LazyLists are possibly-infinite, cached sequences.  See also IEnumerable/Seq for
+/// uncached sequences. LazyLists normally involve delayed computations without 
+/// side-effects.  The results of these computations are cached and evaluations will be 
+/// performed only once for each element of the lazy list.  In contrast, for sequences 
+/// (IEnumerable) recomputation happens each time an enumerator is created and the sequence 
+/// traversed.
+///
+/// LazyLists can represent cached, potentially-infinite computations.  Because they are 
+/// cached they may cause memory leaks if some active code or data structure maintains a 
+/// live reference to the head of an infinite or very large lazy list while iterating it, 
+/// or if a reference is maintained after the list is no longer required.
+///
+/// Lazy lists may be matched using the LazyList.Cons and LazyList.Nil active patterns. 
+/// These may force the computation of elements of the list.
+
+[<Sealed>]
+type LazyList<'T> =
+    interface IEnumerable<'T>
+    interface System.Collections.IEnumerable
+    
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module LazyList =
+
+    /// Test if a list is empty.  Forces the evaluation of
+    /// the first element of the stream if it is not already evaluated.
+    val isEmpty: LazyList<'T> -> bool
+
+    /// Return the first element of the list.  Forces the evaluation of
+    /// the first cell of the list if it is not already evaluated.
+    val head       : LazyList<'T> -> 'T
+
+    /// Return the list corresponding to the remaining items in the sequence.  
+    /// Forces the evaluation of the first cell of the list if it is not already evaluated.
+    val tail       : LazyList<'T> -> LazyList<'T>
+
+    /// Get the first cell of the list.
+    val get      : LazyList<'T> -> ('T * LazyList<'T>) option  
+
+    /// Return the list which on consumption will consist of at most 'n' elements of 
+    /// the input list.  
+    val take     : count:int -> source:LazyList<'T> -> LazyList<'T>
+
+    /// Return the list which on consumption will skip the first 'n' elements of 
+    /// the input list.  
+    val skip     : count:int -> source:LazyList<'T> -> LazyList<'T>
+
+    /// Apply the given function to successive elements of the list, returning the first
+    /// result where function returns <c>Some(x)</c> for some x. If the function never returns
+    /// true, 'None' is returned.
+    val tryFind    : predicate:('T -> bool) -> source:LazyList<'T> -> 'T option
+
+    /// Return the first element for which the given function returns <c>true</c>.
+    /// Raise <c>KeyNotFoundException</c> if no such element exists.
+    val find     : predicate:('T -> bool) -> source:LazyList<'T> -> 'T 
+
+    /// Evaluates to the list that contains no items
+    [<GeneralizableValue>]
+    val empty<'T>    : LazyList<'T>
+
+    /// Return the length of the list
+    val length: list:LazyList<'T> -> int
+
+    /// Return a new list which contains the given item followed by the
+    /// given list.
+    val cons     : 'T -> LazyList<'T>               -> LazyList<'T>
+
+    /// Return a new list which on consumption contains the given item 
+    /// followed by the list returned by the given computation.  The 
+    val consDelayed    : 'T -> (unit -> LazyList<'T>)     -> LazyList<'T>
+
+    /// Return the list which on consumption will consist of an infinite sequence of 
+    /// the given item
+    val repeat   : 'T -> LazyList<'T>
+
+    /// Return a list that is in effect the list returned by the given computation.
+    /// The given computation is not executed until the first element on the list is
+    /// consumed.
+    val delayed  : (unit -> LazyList<'T>)           -> LazyList<'T>
+
+    /// Return a list that contains the elements returned by the given computation.
+    /// The given computation is not executed until the first element on the list is
+    /// consumed.  The given argument is passed to the computation.  Subsequent elements
+    /// in the list are generated by again applying the residual 'b to the computation.
+    val unfold   : ('State -> ('T * 'State) option) -> 'State -> LazyList<'T>
+
+    /// Return the list which contains on demand the elements of the first list followed
+    /// by the elements of the second list
+    val append   : LazyList<'T> -> source:LazyList<'T> -> LazyList<'T>
+
+    /// Return the list which contains on demand the pair of elements of the first and second list
+    val zip  : LazyList<'T1> -> LazyList<'T2> -> LazyList<'T1 * 'T2>
+
+    /// Return the list which contains on demand the list of elements of the list of lazy lists.
+    val concat   : LazyList< LazyList<'T>> -> LazyList<'T>
+
+    /// Return a new collection which on consumption will consist of only the elements of the collection
+    /// for which the given predicate returns "true"
+    val filter   : predicate:('T -> bool) -> source:LazyList<'T> -> LazyList<'T>
+
+    /// Apply the given function to each element of the collection. 
+    val iter: action:('T -> unit) -> list:LazyList<'T>-> unit
+
+    /// Return a new list consisting of the results of applying the given accumulating function
+    /// to successive elements of the list
+    val scan    : folder:('State -> 'T -> 'State) -> 'State -> source:LazyList<'T> -> LazyList<'State>  
+
+    /// Build a new collection whose elements are the results of applying the given function
+    /// to each of the elements of the collection.
+    val map      : mapping:('T -> 'U) -> source:LazyList<'T> -> LazyList<'U>
+
+    /// Build a new collection whose elements are the results of applying the given function
+    /// to the corresponding elements of the two collections pairwise.
+    val map2     : mapping:('T1 -> 'T2 -> 'U) -> LazyList<'T1> -> LazyList<'T2> -> LazyList<'U>
+
+    /// Build a collection from the given array. This function will eagerly evaluate all of the 
+    /// list (and thus may not terminate). 
+    val ofArray : 'T array -> LazyList<'T>
+
+    /// Build an array from the given collection
+    val toArray : LazyList<'T> -> 'T array
+
+    /// Build a collection from the given list. This function will eagerly evaluate all of the 
+    /// list (and thus may not terminate). 
+    val ofList  : list<'T> -> LazyList<'T>
+
+    /// Build a non-lazy list from the given collection. This function will eagerly evaluate all of the 
+    /// list (and thus may not terminate). 
+    val toList  : LazyList<'T> -> list<'T>
+
+    /// Return a view of the collection as an enumerable object
+    val toSeq: LazyList<'T> -> seq<'T>
+
+    /// Build a new collection from the given enumerable object
+    val ofSeq: seq<'T> -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.consDelayed' instead")>]
+    val consf    : 'T -> (unit -> LazyList<'T>)     -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.head' instead")>]
+    val hd: LazyList<'T> -> 'T
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.tail' instead")>]
+    val tl     : LazyList<'T> -> LazyList<'T>
+
+    [<System.Obsolete("This function will be removed. Use 'not (LazyList.isEmpty list)' instead")>]
+    val nonempty : LazyList<'T> -> bool
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.skip' instead")>]
+    val drop     : count:int -> source:LazyList<'T> -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed to 'tryFind'")>]
+    val first    : predicate:('T -> bool) -> source:LazyList<'T> -> 'T option
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.ofArray' instead")>]
+    val of_array : 'T array -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.toArray' instead")>]
+    val to_array : LazyList<'T> -> 'T array
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.ofList' instead")>]
+    val of_list  : list<'T> -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.toList' instead")>]
+    val to_list  : LazyList<'T> -> list<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.toSeq' instead")>]
+    val to_seq: LazyList<'T> -> seq<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.ofSeq' instead")>]
+    val of_seq: seq<'T> -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed to 'scan'")>]
+    val folds    : folder:('State -> 'T -> 'State) -> 'State -> source:LazyList<'T> -> LazyList<'State>  
+
+    [<System.Obsolete("This function has been renamed to 'zip'")>]
+    val combine  : LazyList<'T1> -> LazyList<'T2> -> LazyList<'T1 * 'T2>
+
+    //--------------------------------------------------------------------------
+    // Lazy list active patterns
+
+    val (|Cons|Nil|) : LazyList<'T> -> Choice<('T * LazyList<'T>),unit>
+
diff --git a/src/FSharp.PowerPack/Lexing.fs b/src/FSharp.PowerPack/Lexing.fs
new file mode 100755
index 0000000..ff3fdc9
--- /dev/null
+++ b/src/FSharp.PowerPack/Lexing.fs
@@ -0,0 +1,423 @@
+// (c) Microsoft Corporation 2005-2009.
+
+#nowarn "47" // recursive initialization of LexBuffer
+
+
+#if INTERNALIZED_POWER_PACK
+namespace Internal.Utilities.Text.Lexing
+
+#else
+namespace Microsoft.FSharp.Text.Lexing 
+#endif
+
+    open System.Collections.Generic
+
+    // REVIEW: This type showed up on a parsing-intensive performance measurement. Consider whether it can be a struct-record later when we have this feature. -jomo
+#if INTERNALIZED_POWER_PACK
+    type internal Position = 
+#else
+    type Position = 
+#endif
+        { pos_fname : string;
+          pos_lnum : int;
+#if INTERNALIZED_POWER_PACK
+          pos_orig_lnum : int;
+#endif
+          pos_bol : int;
+          pos_cnum : int; }
+        member x.FileName = x.pos_fname
+        member x.Line = x.pos_lnum
+#if INTERNALIZED_POWER_PACK
+        member x.OriginalLine = x.pos_orig_lnum
+#endif
+        member x.Char = x.pos_cnum
+        member x.AbsoluteOffset = x.pos_cnum
+        member x.StartOfLine = x.pos_bol
+        member x.StartOfLineAbsoluteOffset = x.pos_bol
+        member x.Column = x.pos_cnum - x.pos_bol
+        member pos.NextLine = 
+            { pos with 
+#if INTERNALIZED_POWER_PACK
+                    pos_orig_lnum = pos.OriginalLine + 1;
+#endif
+                    pos_lnum = pos.Line+1; 
+                    pos_bol = pos.AbsoluteOffset }
+        member pos.EndOfToken(n) = {pos with pos_cnum=pos.pos_cnum + n }
+        member pos.AsNewLinePos() = pos.NextLine
+        member pos.ShiftColumnBy(by) = {pos with pos_cnum = pos.pos_cnum + by}
+        static member Empty = 
+            { pos_fname=""; 
+              pos_lnum= 0; 
+#if INTERNALIZED_POWER_PACK
+              pos_orig_lnum = 0;
+#endif
+              pos_bol= 0; 
+              pos_cnum=0 }
+        static member FirstLine(filename) = 
+            { pos_fname=filename; 
+#if INTERNALIZED_POWER_PACK
+              pos_orig_lnum = 1;
+#endif
+              pos_lnum= 1; 
+              pos_bol= 0; 
+              pos_cnum=0 }
+
+#if INTERNALIZED_POWER_PACK
+    type internal LexBufferFiller<'char> = 
+#else
+    type LexBufferFiller<'char> = 
+#endif
+        { fillSync : (LexBuffer<'char> -> unit) option
+          fillAsync : (LexBuffer<'char> -> Async<unit>) option } 
+        
+    and [<Sealed>]
+#if INTERNALIZED_POWER_PACK
+        internal LexBuffer<'char>(filler: LexBufferFiller<'char>) as this = 
+#else
+        LexBuffer<'char>(filler: LexBufferFiller<'char>) as this = 
+#endif
+        let context = new Dictionary<string,obj>(1) in 
+        let extendBufferSync = (fun () -> match filler.fillSync with Some refill -> refill this | None -> invalidOp "attempt to read synchronously from an asynchronous lex buffer")
+        let extendBufferAsync = (fun () -> match filler.fillAsync with Some refill -> refill this | None -> invalidOp "attempt to read asynchronously from a synchronous lex buffer")
+        let mutable buffer=[||];
+        /// number of valid charactes beyond bufferScanStart 
+        let mutable bufferMaxScanLength=0;
+        /// count into the buffer when scanning 
+        let mutable bufferScanStart=0;
+        /// number of characters scanned so far 
+        let mutable bufferScanLength=0;
+        /// length of the scan at the last accepting state 
+        let mutable lexemeLength=0;
+        /// action related to the last accepting state 
+        let mutable bufferAcceptAction=0;
+        let mutable eof = false;
+        let mutable startPos = Position.Empty ;
+        let mutable endPos = Position.Empty
+
+        // Throw away all the input besides the lexeme 
+              
+        let discardInput () = 
+            let keep = Array.sub buffer bufferScanStart bufferScanLength
+            let nkeep = keep.Length 
+            Array.blit keep 0 buffer 0 nkeep;
+            bufferScanStart <- 0;
+            bufferMaxScanLength <- nkeep
+                 
+              
+        member lexbuf.EndOfScan () : int =
+            // Printf.eprintf "endOfScan, lexBuffer.lexemeLength = %d\n" lexBuffer.lexemeLength;
+            if bufferAcceptAction < 0 then 
+                failwith "unrecognized input"
+
+            //  Printf.printf "endOfScan %d state %d on unconsumed input '%c' (%d)\n" a s (Char.chr inp) inp;
+            //   Printf.eprintf "accept, lexeme = %s\n" (lexeme lexBuffer); 
+            lexbuf.StartPos <- endPos;
+            lexbuf.EndPos <- endPos.EndOfToken(lexbuf.LexemeLength);
+            bufferAcceptAction
+
+        member lexbuf.StartPos
+           with get() = startPos
+           and  set(b) =  startPos <- b
+           
+        member lexbuf.EndPos 
+           with get() = endPos
+           and  set(b) =  endPos <- b
+
+        member lexbuf.Lexeme         = Array.sub buffer bufferScanStart lexemeLength
+        member lexbuf.LexemeChar(n)  = buffer.[n+bufferScanStart]
+        
+        member lexbuf.BufferLocalStore = (context :> IDictionary<_,_>)
+        member lexbuf.LexemeLength        with get() : int = lexemeLength    and set v = lexemeLength <- v
+        member internal lexbuf.Buffer              with get() : 'char[] = buffer              and set v = buffer <- v
+        member internal lexbuf.BufferMaxScanLength with get() = bufferMaxScanLength and set v = bufferMaxScanLength <- v
+        member internal lexbuf.BufferScanLength    with get() = bufferScanLength    and set v = bufferScanLength <- v
+        member internal lexbuf.BufferScanStart     with get() : int = bufferScanStart     and set v = bufferScanStart <- v
+        member internal lexbuf.BufferAcceptAction  with get() = bufferAcceptAction  and set v = bufferAcceptAction <- v
+        member internal lexbuf.RefillBuffer = extendBufferSync
+        member internal lexbuf.AsyncRefillBuffer = extendBufferAsync
+
+        static member LexemeString(lexbuf:LexBuffer<char>) = 
+            new System.String(lexbuf.Buffer,lexbuf.BufferScanStart,lexbuf.LexemeLength)
+
+        member lexbuf.IsPastEndOfStream 
+           with get() = eof
+           and  set(b) =  eof <- b
+
+        member lexbuf.DiscardInput() = discardInput ()
+
+        member x.BufferScanPos = bufferScanStart + bufferScanLength
+
+        member lexbuf.EnsureBufferSize n = 
+            if lexbuf.BufferScanPos + n >= buffer.Length then 
+                let repl = Array.zeroCreate (lexbuf.BufferScanPos + n) 
+                Array.blit buffer bufferScanStart repl bufferScanStart bufferScanLength;
+                buffer <- repl
+
+        static member FromReadFunctions (syncRead : ('char[] * int * int -> int) option, asyncRead : ('char[] * int * int -> Async<int>) option) : LexBuffer<'char> = 
+            let extension= Array.zeroCreate 4096
+            let fillers = 
+                { fillSync = 
+                    match syncRead with 
+                    | None -> None
+                    | Some read -> 
+                         Some (fun lexBuffer -> 
+                             let n = read(extension,0,extension.Length)
+                             lexBuffer.EnsureBufferSize n;
+                             Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n;
+                             lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n); 
+                  fillAsync = 
+                    match asyncRead with 
+                    | None -> None
+                    | Some read -> 
+                         Some (fun lexBuffer -> 
+                                  async { 
+                                      let! n = read(extension,0,extension.Length)
+                                      lexBuffer.EnsureBufferSize n;
+                                      Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n;
+                                      lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n }) }
+            new LexBuffer<_>(fillers)
+
+        // A full type signature is required on this method because it is used at more specific types within its own scope
+        static member FromFunction (f : 'char[] * int * int -> int) : LexBuffer<'char> =  LexBuffer<_>.FromReadFunctions(Some(f),None)
+        static member FromAsyncFunction (f : 'char[] * int * int -> Async<int>) : LexBuffer<'char> =  LexBuffer<_>.FromReadFunctions(None,Some(f))
+              
+        static member FromCharFunction f : LexBuffer<char> = 
+            LexBuffer<char>.FromFunction(fun (buff,start,len) -> 
+                let buff2 = Array.zeroCreate len
+                let n = f buff2 len 
+                Array.blit buff2 0 buff start len
+                n)
+        static member FromByteFunction f : LexBuffer<byte> = 
+            LexBuffer<byte>.FromFunction(fun (buff,start,len) -> 
+                let buff2 = Array.zeroCreate len
+                let n = f buff2 len 
+                Array.blit buff2 0 buff start len
+                n)
+
+        // A full type signature is required on this method because it is used at more specific types within its own scope
+        static member FromArray (s: 'char[]) : LexBuffer<'char> = 
+            let lexBuffer = 
+                new LexBuffer<_> 
+                    { fillSync = Some (fun _ -> ()); 
+                      fillAsync = Some (fun _ -> async { return () }) }
+            let buffer = Array.copy s 
+            lexBuffer.Buffer <- buffer;
+            lexBuffer.BufferMaxScanLength <- buffer.Length;
+            lexBuffer
+
+        static member FromBytes    (arr) = LexBuffer<byte>.FromArray(arr)
+        static member FromChars    (arr) = LexBuffer<char>.FromArray(arr) 
+        static member FromString (s:string) = LexBuffer<char>.FromChars (s.ToCharArray())
+
+        static member FromTextReader (tr:System.IO.TextReader)  : LexBuffer<char> = 
+           LexBuffer<char>.FromFunction(tr.Read) 
+
+        static member FromBinaryReader (br:System.IO.BinaryReader)  : LexBuffer<byte> = 
+           LexBuffer<byte>.FromFunction(br.Read) 
+
+        static member FromStream (stream:System.IO.Stream)  : LexBuffer<byte> = 
+           LexBuffer<byte>.FromReadFunctions(Some(stream.Read),Some(fun (buf,offset,len) -> stream.AsyncRead(buf,offset=offset,count=len))) 
+
+    module GenericImplFragments = 
+        let startInterpret(lexBuffer:LexBuffer<_>)= 
+            lexBuffer.BufferScanStart <- lexBuffer.BufferScanStart + lexBuffer.LexemeLength;
+            lexBuffer.BufferMaxScanLength <- lexBuffer.BufferMaxScanLength - lexBuffer.LexemeLength;
+            lexBuffer.BufferScanLength <- 0;
+            lexBuffer.LexemeLength <- 0;
+            lexBuffer.BufferAcceptAction <- -1;
+
+        let afterRefill (trans: uint16[] array,sentinel,lexBuffer:LexBuffer<_>,scanUntilSentinel,endOfScan,state,eofPos) = 
+            // end of file occurs if we couldn't extend the buffer 
+            if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then  
+                let snew = int trans.[state].[eofPos] // == EOF 
+                if snew = sentinel then 
+                    endOfScan()
+                else 
+                    if lexBuffer.IsPastEndOfStream then failwith "End of file on lexing stream";
+                    lexBuffer.IsPastEndOfStream <- true;
+                    // Printf.printf "state %d --> %d on eof\n" state snew;
+                    scanUntilSentinel(lexBuffer,snew)
+            else 
+                scanUntilSentinel(lexBuffer, state)
+
+        let onAccept (lexBuffer:LexBuffer<_>,a) = 
+            lexBuffer.LexemeLength <- lexBuffer.BufferScanLength;
+            lexBuffer.BufferAcceptAction <- a;
+
+    open GenericImplFragments
+
+    [<Sealed>]
+#if INTERNALIZED_POWER_PACK
+    type internal AsciiTables(trans: uint16[] array, accept: uint16[]) =
+#else
+    type AsciiTables(trans: uint16[] array, accept: uint16[]) =
+#endif
+        let rec scanUntilSentinel(lexBuffer, state) =
+            let sentinel = 255 * 256 + 255 
+            // Return an endOfScan after consuming the input 
+            let a = int accept.[state] 
+            if a <> sentinel then 
+                onAccept (lexBuffer,a)
+            
+            if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
+                lexBuffer.DiscardInput();
+                lexBuffer.RefillBuffer ();
+              // end of file occurs if we couldn't extend the buffer 
+                afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,256 (* == EOF *) )
+            else
+                // read a character - end the scan if there are no further transitions 
+                let inp = int(lexBuffer.Buffer.[lexBuffer.BufferScanPos])
+                let snew = int trans.[state].[inp] 
+                if snew = sentinel then 
+                    lexBuffer.EndOfScan()
+                else 
+                    lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
+                    // Printf.printf "state %d --> %d on '%c' (%d)\n" state snew (Char.chr inp) inp;
+                    scanUntilSentinel(lexBuffer, snew)
+            
+        /// Interpret tables for an ascii lexer generated by fslex. 
+        member tables.Interpret(initialState,lexBuffer : LexBuffer<byte>) = 
+            startInterpret(lexBuffer)
+            scanUntilSentinel(lexBuffer, initialState)
+
+        /// Interpret tables for an ascii lexer generated by fslex. 
+        member tables.AsyncInterpret(initialState,lexBuffer : LexBuffer<byte>) = 
+        
+            let rec scanUntilSentinel(lexBuffer,state) : Async<int> = 
+                async {  
+                    let sentinel = 255 * 256 + 255 
+                    // Return an endOfScan after consuming the input 
+                    let a = int accept.[state] 
+                    if a <> sentinel then 
+                        onAccept (lexBuffer,a)
+                    
+                    if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
+                        lexBuffer.DiscardInput();
+                        do! lexBuffer.AsyncRefillBuffer ();
+                       // end of file occurs if we couldn't extend the buffer 
+                        return! afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,endOfScan,state,256 (* == EOF *) )
+                    else
+                        // read a character - end the scan if there are no further transitions 
+                        let inp = int(lexBuffer.Buffer.[lexBuffer.BufferScanPos])
+                        let snew = int trans.[state].[inp] 
+                        if snew = sentinel then 
+                            return! endOfScan()
+                        else 
+                            lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
+                            return! scanUntilSentinel(lexBuffer,snew)
+                }
+            and endOfScan() = 
+                async { return lexBuffer.EndOfScan() }
+            startInterpret(lexBuffer)
+            scanUntilSentinel(lexBuffer, initialState)
+
+
+        static member Create(trans,accept) = new AsciiTables(trans,accept)
+
+    [<Sealed>]
+#if INTERNALIZED_POWER_PACK
+    type internal UnicodeTables(trans: uint16[] array, accept: uint16[]) = 
+#else
+    type UnicodeTables(trans: uint16[] array, accept: uint16[]) = 
+#endif
+        let sentinel = 255 * 256 + 255 
+        let numUnicodeCategories = 30 
+        let numLowUnicodeChars = 128 
+        let numSpecificUnicodeChars = (trans.[0].Length - 1 - numLowUnicodeChars - numUnicodeCategories)/2
+        let lookupUnicodeCharacters (state,inp) = 
+            let inpAsInt = int inp
+            // Is it a fast ASCII character?
+            if inpAsInt < numLowUnicodeChars then 
+                int trans.[state].[inpAsInt]
+            else 
+                // Search for a specific unicode character
+                let baseForSpecificUnicodeChars = numLowUnicodeChars
+                let rec loop i = 
+                    if i >= numSpecificUnicodeChars then 
+                        // OK, if we failed then read the 'others' entry in the alphabet,
+                        // which covers all Unicode characters not covered in other
+                        // ways
+                        let baseForUnicodeCategories = numLowUnicodeChars+numSpecificUnicodeChars*2
+                        let unicodeCategory = System.Char.GetUnicodeCategory(inp)
+                        //System.Console.WriteLine("inp = {0}, unicodeCategory = {1}", [| box inp; box unicodeCategory |]);
+                        int trans.[state].[baseForUnicodeCategories + int32 unicodeCategory]
+                    else 
+                        // This is the specific unicode character
+                        let c = char (int trans.[state].[baseForSpecificUnicodeChars+i*2])
+                        //System.Console.WriteLine("c = {0}, inp = {1}, i = {2}", [| box c; box inp; box i |]);
+                        // OK, have we found the entry for a specific unicode character?
+                        if c = inp
+                        then int trans.[state].[baseForSpecificUnicodeChars+i*2+1]
+                        else loop(i+1)
+                
+                loop 0
+        let eofPos    = numLowUnicodeChars + 2*numSpecificUnicodeChars + numUnicodeCategories 
+        
+        let rec scanUntilSentinel(lexBuffer,state) =
+            // Return an endOfScan after consuming the input 
+            let a = int accept.[state] 
+            if a <> sentinel then 
+                onAccept(lexBuffer,a)
+            
+            if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
+                lexBuffer.DiscardInput();
+                lexBuffer.RefillBuffer ();
+              // end of file occurs if we couldn't extend the buffer 
+                afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,eofPos)
+            else
+                // read a character - end the scan if there are no further transitions 
+                let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos]
+                
+                // Find the new state
+                let snew = lookupUnicodeCharacters (state,inp)
+
+                if snew = sentinel then 
+                    lexBuffer.EndOfScan()
+                else 
+                    lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
+                    // Printf.printf "state %d --> %d on '%c' (%d)\n" s snew (char inp) inp;
+                    scanUntilSentinel(lexBuffer,snew)
+                          
+        // Each row for the Unicode table has format 
+        //      128 entries for ASCII characters
+        //      A variable number of 2*UInt16 entries for SpecificUnicodeChars 
+        //      30 entries, one for each UnicodeCategory
+        //      1 entry for EOF
+
+        member tables.Interpret(initialState,lexBuffer : LexBuffer<char>) = 
+            startInterpret(lexBuffer)
+            scanUntilSentinel(lexBuffer, initialState)
+
+        member tables.AsyncInterpret(initialState,lexBuffer : LexBuffer<char>) = 
+
+            let rec scanUntilSentinel(lexBuffer, state) =
+                async {
+                    // Return an endOfScan after consuming the input 
+                    let a = int accept.[state] 
+                    if a <> sentinel then 
+                        onAccept(lexBuffer,a)
+                    
+                    if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
+                        lexBuffer.DiscardInput();
+                        lexBuffer.RefillBuffer ();
+                        // end of file occurs if we couldn't extend the buffer 
+                        return! afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,endOfScan,state,eofPos)
+                    else
+                        // read a character - end the scan if there are no further transitions 
+                        let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos]
+                        
+                        // Find the new state
+                        let snew = lookupUnicodeCharacters (state,inp)
+
+                        if snew = sentinel then 
+                            return! endOfScan()
+                        else 
+                            lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
+                            return! scanUntilSentinel(lexBuffer, snew)
+                }
+            and endOfScan() = 
+                async { return lexBuffer.EndOfScan() } 
+            startInterpret(lexBuffer)
+            scanUntilSentinel(lexBuffer, initialState)
+
+        static member Create(trans,accept) = new UnicodeTables(trans,accept)
diff --git a/src/FSharp.PowerPack/Lexing.fsi b/src/FSharp.PowerPack/Lexing.fsi
new file mode 100755
index 0000000..3096b8f
--- /dev/null
+++ b/src/FSharp.PowerPack/Lexing.fsi
@@ -0,0 +1,151 @@
+//==========================================================================
+// LexBuffers are for use with automatically generated lexical analyzers,
+// in particular those produced by 'fslex'.
+//
+// (c) Microsoft Corporation 2005-2008.
+//===========================================================================
+
+#if INTERNALIZED_POWER_PACK
+namespace Internal.Utilities.Text.Lexing
+#else
+namespace Microsoft.FSharp.Text.Lexing 
+#endif
+
+open System.Collections.Generic
+
+/// Position information stored for lexing tokens
+//
+// Note: this is an OCaml compat record type. 
+#if INTERNALIZED_POWER_PACK
+type internal Position = 
+#else
+type Position = 
+#endif
+    { /// The file name for the position
+      pos_fname: string;
+      /// The line number for the position
+      pos_lnum: int;
+#if INTERNALIZED_POWER_PACK
+      /// The line number for the position in the original source file
+      pos_orig_lnum : int;
+#endif
+      /// The absolute offset of the beginning of the line
+      pos_bol: int;
+      /// The absolute offset of the column for the position
+      pos_cnum: int; }
+     /// The file name associated with the input stream.
+     member FileName : string
+     /// The line number in the input stream, assuming fresh positions have been updated 
+     /// using AsNewLinePos() and by modifying the EndPos property of the LexBuffer.
+     member Line : int
+#if INTERNALIZED_POWER_PACK
+     /// The line number for the position in the input stream, assuming fresh positions have been updated 
+     /// using AsNewLinePos()
+     member OriginalLine : int
+#endif
+     [<System.ObsoleteAttribute("Use the AbsoluteOffset property instead")>]
+     member Char : int
+     /// The character number in the input stream
+     member AbsoluteOffset : int
+     /// Return absolute offset of the start of the line marked by the position
+     member StartOfLineAbsoluteOffset : int
+     /// Return the column number marked by the position, i.e. the difference between the AbsoluteOffset and the StartOfLineAbsoluteOffset
+     member Column : int
+     // Given a position just beyond the end of a line, return a position at the start of the next line
+     member NextLine : Position     
+     
+     /// Given a position at the start of a token of length n, return a position just beyond the end of the token
+     member EndOfToken: n:int -> Position
+     /// Gives a position shifted by specified number of characters
+     member ShiftColumnBy: by:int -> Position
+     
+     [<System.ObsoleteAttribute("Consider using the NextLine property instead")>]
+     member AsNewLinePos : unit -> Position
+     
+     /// Get an arbitrary position, with the empty string as filename, and  
+     static member Empty : Position
+
+     /// Get a position corresponding to the first line (line number 1) in a given file
+     static member FirstLine : filename:string -> Position
+    
+[<Sealed>]
+#if INTERNALIZED_POWER_PACK
+type internal LexBuffer<'char> =
+#else
+/// Input buffers consumed by lexers generated by <c>fslex.exe </c>
+type LexBuffer<'char> =
+#endif
+    /// The start position for the lexeme
+    member StartPos: Position with get,set
+    /// The end position for the lexeme
+    member EndPos: Position with get,set
+    /// The matched string 
+    member Lexeme: 'char array
+    
+    /// Fast helper to turn the matched characters into a string, avoiding an intermediate array
+    static member LexemeString : LexBuffer<char> -> string
+    
+    /// The length of the matched string 
+    member LexemeLength: int
+    /// Fetch a particular character in the matched string 
+    member LexemeChar: int -> 'char
+
+    /// Dynamically typed, non-lexically scoped parameter table
+    member BufferLocalStore : IDictionary<string,obj>
+    
+    /// True if the refill of the buffer ever failed , or if explicitly set to true.
+    member IsPastEndOfStream: bool with get,set
+    /// Remove all input, though don't discard the current lexeme 
+    member DiscardInput: unit -> unit
+
+    /// Create a lex buffer suitable for byte lexing that reads characters from the given array
+    static member FromBytes: byte[] -> LexBuffer<byte>
+    /// Create a lex buffer suitable for Unicode lexing that reads characters from the given array
+    static member FromChars: char[] -> LexBuffer<char>
+    /// Create a lex buffer suitable for Unicode lexing that reads characters from the given string
+    static member FromString: string -> LexBuffer<char>
+    /// Create a lex buffer that reads character or byte inputs by using the given function
+    static member FromFunction: ('char[] * int * int -> int) -> LexBuffer<'char>
+    /// Create a lex buffer that asynchronously reads character or byte inputs by using the given function
+    static member FromAsyncFunction: ('char[] * int * int -> Async<int>) -> LexBuffer<'char>
+
+
+    [<System.Obsolete("Use LexBuffer<char>.FromFunction instead")>]
+    static member FromCharFunction: (char[] -> int -> int) -> LexBuffer<char>
+    [<System.Obsolete("Use LexBuffer<byte>.FromFunction instead")>]
+    static member FromByteFunction: (byte[] -> int -> int) -> LexBuffer<byte>
+
+    /// Create a lex buffer suitable for use with a Unicode lexer that reads character inputs from the given text reader
+    static member FromTextReader: System.IO.TextReader -> LexBuffer<char>
+    /// Create a lex buffer suitable for use with ASCII byte lexing that reads byte inputs from the given binary reader
+    static member FromBinaryReader: System.IO.BinaryReader -> LexBuffer<byte>
+
+
+/// The type of tables for an ascii lexer generated by fslex. 
+[<Sealed>]
+#if INTERNALIZED_POWER_PACK
+type internal AsciiTables =
+#else
+type AsciiTables =
+#endif
+    static member Create : uint16[] array * uint16[] -> AsciiTables
+    /// Interpret tables for an ascii lexer generated by fslex. 
+    member Interpret:  initialState:int * LexBuffer<byte>  -> int
+    /// Interpret tables for an ascii lexer generated by fslex, processing input asynchronously
+    member AsyncInterpret:  initialState:int * LexBuffer<byte> -> Async<int>
+
+
+/// The type of tables for an unicode lexer generated by fslex. 
+[<Sealed>]
+#if INTERNALIZED_POWER_PACK
+type internal UnicodeTables =
+#else
+type UnicodeTables =
+#endif
+    static member Create : uint16[] array * uint16[] -> UnicodeTables
+    /// Interpret tables for a unicode lexer generated by fslex. 
+    member Interpret:  initialState:int * LexBuffer<char> -> int
+
+    /// Interpret tables for a unicode lexer generated by fslex, processing input asynchronously
+    member AsyncInterpret:  initialState:int * LexBuffer<char> -> Async<int>
+
diff --git a/src/FSharp.PowerPack/Measure.fs b/src/FSharp.PowerPack/Measure.fs
new file mode 100755
index 0000000..402a0be
--- /dev/null
+++ b/src/FSharp.PowerPack/Measure.fs
@@ -0,0 +1,15 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Math
+
+#nowarn "42"
+
+module Measure =
+
+    let infinity<[<Measure>] 'u> : float<'u> = LanguagePrimitives.FloatWithMeasure System.Double.PositiveInfinity
+    let nan<[<Measure>] 'u> : float<'u> = LanguagePrimitives.FloatWithMeasure System.Double.NaN
+
+    let infinityf<[<Measure>] 'u> : float32<'u> = LanguagePrimitives.Float32WithMeasure System.Single.PositiveInfinity
+    let nanf<[<Measure>] 'u> : float32<'u> = LanguagePrimitives.Float32WithMeasure System.Single.NaN
+
diff --git a/src/FSharp.PowerPack/Measure.fsi b/src/FSharp.PowerPack/Measure.fsi
new file mode 100755
index 0000000..7cdaefb
--- /dev/null
+++ b/src/FSharp.PowerPack/Measure.fsi
@@ -0,0 +1,25 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Math
+
+#nowarn "42"
+
+module Measure =
+
+    /// <summary>Version of <c>System.Double.PositiveInfinity</c> that is generic in its units-of-measure</summary>
+    [<GeneralizableValue>]
+    val infinity<[<Measure>] 'u> : float<'u>
+
+    /// <summary>Version of <c>System.Double.NaN</c> that is generic in its units-of-measure</summary>
+    [<GeneralizableValue>]
+    val nan<[<Measure>] 'u> : float<'u> 
+
+    /// <summary>Version of <c>System.Single.PositiveInfinity</c> that is generic in its units-of-measure</summary>
+    [<GeneralizableValue>]
+    val infinityf<[<Measure>] 'u> : float32<'u> 
+
+    /// <summary>Version of <c>System.Single.NaN</c> that is generic in its units-of-measure</summary>
+    [<GeneralizableValue>]
+    val nanf<[<Measure>] 'u> : float32<'u>
+
diff --git a/src/FSharp.PowerPack/NativeArray.fs b/src/FSharp.PowerPack/NativeArray.fs
new file mode 100755
index 0000000..e53c151
--- /dev/null
+++ b/src/FSharp.PowerPack/NativeArray.fs
@@ -0,0 +1,106 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.NativeInterop
+
+#nowarn "44"
+#nowarn "9" // unverifiable constructs
+#nowarn "51" // The address-of operator may result in non-verifiable code. Its use is restricted to passing byrefs to functions that require them
+
+open System
+open System.Runtime.InteropServices
+open Microsoft.FSharp.NativeInterop
+
+module NativeOps = 
+    [<NoDynamicInvocation>]
+    let inline pinObjUnscoped (obj: obj) =  GCHandle.Alloc(obj,GCHandleType.Pinned) 
+    [<NoDynamicInvocation>]
+    let inline pinObj (obj: obj) f = 
+        let gch = pinObjUnscoped obj 
+        try f gch
+        finally
+            gch.Free()
+
+[<Sealed>]
+type NativeArray<'T when 'T : unmanaged>(ptr : nativeptr<'T>, len: int) =
+    member x.Ptr = ptr
+    [<NoDynamicInvocation>]
+    member inline x.Item 
+       with get n = NativePtr.get x.Ptr n
+       and  set n v = NativePtr.set x.Ptr n v
+    member x.Length = len
+
+[<Sealed>]
+type FortranMatrix<'T when 'T : unmanaged>(ptr : nativeptr<'T>, nrows: int, ncols:int) = 
+    member x.NumCols = ncols
+    member x.NumRows = nrows
+    member x.Ptr = ptr
+    [<NoDynamicInvocation>]
+    member inline x.Item 
+       with get (row,col) = NativePtr.get x.Ptr (row + col*x.NumRows)
+       and  set (row,col) v = NativePtr.set x.Ptr (row + col*x.NumRows) v
+    member x.NativeTranspose = new CMatrix<_>(ptr,ncols,nrows)
+  
+and 
+  [<Sealed>]
+  NativeArray2<'T when 'T : unmanaged>(ptr : nativeptr<'T>, nrows:int, ncols: int) = 
+    member x.Ptr = ptr
+    member x.NumRows = nrows
+    member x.NumCols = ncols
+    [<NoDynamicInvocation>]
+    member inline x.Item 
+       with get (row,col) = NativePtr.get x.Ptr (row*x.NumCols + col)
+       and  set (row,col) v = NativePtr.set x.Ptr (row*x.NumCols + col) v
+    member x.NativeTranspose = new FortranMatrix<_>(x.Ptr,ncols,nrows)
+  
+and CMatrix<'T when 'T : unmanaged> = NativeArray2<'T> 
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Ref = 
+    [<NoDynamicInvocation>]
+    let inline pin (ref: 'T ref) (f : nativeptr<'T> -> 'b) = 
+        NativeOps.pinObj (box ref) (fun gch -> 
+            f (gch.AddrOfPinnedObject() |> NativePtr.ofNativeInt))
+
+open Microsoft.FSharp.Math
+
+[<Sealed>]
+type PinnedArray<'T when 'T : unmanaged>(narray: NativeArray<'T>, gch: GCHandle) =
+    [<NoDynamicInvocation>]
+    static member inline of_array(arr: 'T[]) =
+        let gch = NativeOps.pinObjUnscoped (box arr) 
+        let ptr = &&arr.[0]
+        new PinnedArray<'T>(new NativeArray<_>(ptr,Array.length arr),gch)
+
+    member x.Ptr = narray.Ptr
+    member x.Free() = gch.Free()
+    member x.Length = narray.Length
+    member x.NativeArray = narray
+    interface System.IDisposable with 
+        member x.Dispose() = gch.Free()
+        
+
+[<Sealed>]
+type PinnedArray2<'T when 'T : unmanaged>(narray: NativeArray2<'T>, gch: GCHandle) =
+
+    [<NoDynamicInvocation>]
+    static member inline of_array2(arr: 'T[,]) = 
+        let gch = NativeOps.pinObjUnscoped (box arr) 
+        let ptr = &&arr.[0,0]
+        new PinnedArray2<'T>(new NativeArray2<_>(ptr,Array2D.length1 arr,Array2D.length2 arr),gch)
+
+    [<NoDynamicInvocation>]
+    static member inline of_array2D(arr: 'T[,]) = 
+        let gch = NativeOps.pinObjUnscoped (box arr) 
+        let ptr = &&arr.[0,0]
+        new PinnedArray2<'T>(new NativeArray2<_>(ptr,Array2D.length1 arr,Array2D.length2 arr),gch)
+
+
+    member x.Ptr = narray.Ptr
+    member x.Free() = gch.Free()
+    member x.NumRows = narray.NumRows
+    member x.NumCols = narray.NumCols
+    member x.NativeArray = narray
+    interface System.IDisposable with 
+        member x.Dispose() = gch.Free()
+
+
diff --git a/src/FSharp.PowerPack/NativeArray.fsi b/src/FSharp.PowerPack/NativeArray.fsi
new file mode 100755
index 0000000..b209b48
--- /dev/null
+++ b/src/FSharp.PowerPack/NativeArray.fsi
@@ -0,0 +1,159 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.NativeInterop
+
+open System.Runtime.InteropServices
+
+/// This type wraps a pointer to a blob of unmanaged memory assumed to contain
+/// a C-style one-dimensional array of items compatible with the (presumably blittable) 
+/// type 'T.  The blob of memory must be allocated and managed externally, 
+/// e.g. by a computation routine written in C.
+///
+/// All operations on this type are marked inlined
+/// because the code used to implement the operations is not verifiable.  
+///
+/// Any code that uses these operations will be unverifiable and may 
+/// cause memory corruption if not used with extreme care.
+[<Sealed>]
+type NativeArray<'T when 'T : unmanaged> =
+
+    /// Creates a C-style one dimensional array from a native pointer and the length of the array
+    /// Nothing is actually copied.
+    new : startAddress: nativeptr<'T> * length: int -> NativeArray<'T>
+
+    /// Pointer to the C-style one-dimensional array
+    member Ptr: nativeptr<'T>
+
+    /// Get or set an entry in the array
+    [<Unverifiable>]
+    [<NoDynamicInvocation>]
+    member inline Item : int -> 'T with get,set
+
+    /// Length of the C-style one-dimensional array
+    member Length : int
+
+/// This type wraps a pointer to a blob of unmanaged memory assumed to contain
+/// a C-style row major two-dimensional matrix of items compatible with the (presumably blittable) 
+/// type 'T. The blob of memory must be allocated and managed externally, 
+/// e.g. by a computation routine written in C.
+///
+/// All operations on this type are marked inlined
+/// because the code used to implement the operations is not verifiable.  
+///
+/// Any code that uses these operations will be unverifiable and may 
+/// cause memory corruption if not used with extreme care.
+
+[<Sealed>]
+type NativeArray2<'T when 'T : unmanaged> =
+    /// Creates a C-style row major two-dimensional array from a native pointer, the number of rows and the number of columns.  
+    /// Nothing is actually copied.
+    new : nativeptr<'T> * nrows:int * ncols:int -> NativeArray2<'T>
+
+    /// Pointer to the C-style row major two-dimensional array 
+    member Ptr: nativeptr<'T>
+
+    /// Get the number of rows of the native array
+    member NumRows : int
+
+    /// Get the number of columns of the native array
+    member NumCols : int
+
+    /// Get or set an entry in the array
+    [<Unverifiable>]
+    [<NoDynamicInvocation>]
+    member inline Item : int * int -> 'T with get,set
+
+    /// View a CMatrix as a FortranMatrix.  Doesn't actually allocate
+    /// a new matirx - just gives a different label to the same bits, and swaps the
+    /// row/column count information associated with the bits.
+    member NativeTranspose : FortranMatrix<'T>
+
+/// See NativeArray2
+and CMatrix<'T  when 'T : unmanaged> = NativeArray2<'T> 
+
+/// This type wraps a pointer to a blob of unmanaged memory assumed to contain
+/// a Fortran-style column major two-dimensional matrix of items compatible with the (presumably blittable) 
+/// type 'T. The blob of memory must be allocated and managed externally, 
+/// e.g. by a computation routine written in C.
+///
+/// All operations on this type are marked inlined
+/// because the code used to implement the operations is not verifiable.  
+///
+/// Any code that uses these operations will be unverifiable and may 
+/// cause memory corruption if not used with extreme care.
+and 
+   [<Sealed>]
+   FortranMatrix<'T when 'T : unmanaged> =
+    new : nativeptr<'T> * nrows:int * ncols:int -> FortranMatrix<'T>
+
+    member Ptr: nativeptr<'T>
+
+    member NumRows : int
+    member NumCols : int
+
+    /// Get or set an entry in the array
+    [<Unverifiable>]
+    [<NoDynamicInvocation>]
+    member inline Item : int * int -> 'T with get,set
+    
+    /// View a FortranMatrix as a CMatrix.  Doesn't actually allocate
+    /// a new matirx - just gives a different label to the same bits, and swaps the
+    /// row/column count information associated with the bits.
+    member NativeTranspose : CMatrix<'T>
+  
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Ref =
+    /// Pin the given ref for the duration of a single call to the given function.  A native pointer to
+    /// the contents of the ref is passed to the given function.  Cleanup the GCHandle associated with the 
+    /// pin when the function completes, even if an exception is raised.
+    [<Unverifiable>]
+    [<NoDynamicInvocation>]
+    val inline pin : 'T ref -> (nativeptr<'T> -> 'U) -> 'U
+
+/// Represents a pinned handle to a structure with an underlying 1D array, i.e. an underlying NativeArray.
+/// Used when interfacing with native code math libraries such as LAPACK.
+[<Sealed>]
+type PinnedArray<'T  when 'T : unmanaged> =
+
+    new : NativeArray<'T> * GCHandle -> PinnedArray<'T>
+
+    interface System.IDisposable 
+    member Ptr : nativeptr<'T> 
+
+    member Length : int 
+
+    member NativeArray : NativeArray<'T>
+
+    /// For native interop. Pin the given object
+    [<NoDynamicInvocation>]
+    static member inline of_array : 'T[] -> PinnedArray<'T>
+
+    member Free : unit -> unit
+
+/// Represents a pinned handle to a structure with an underlying 2D array, i.e. an underlying NativeArray2.
+/// Used when interfacing with native code math libraries such as LAPACK.
+[<Sealed>]
+type PinnedArray2<'T when 'T : unmanaged> =
+
+    interface System.IDisposable 
+    new : NativeArray2<'T> * GCHandle -> PinnedArray2<'T> 
+
+    member Ptr : nativeptr<'T> 
+
+    member NumRows : int 
+
+    member NumCols : int 
+
+    member NativeArray : NativeArray2<'T>
+
+    /// For native interop. Pin the given object
+    [<NoDynamicInvocation>]
+    [<System.Obsolete("This method has been renamed to of_array2D")>]
+    static member inline of_array2 : 'T[,] -> PinnedArray2<'T>
+
+    /// For native interop. Pin the given object
+    [<NoDynamicInvocation>]
+    static member inline of_array2D : 'T[,] -> PinnedArray2<'T>
+
+    member Free : unit -> unit
+
diff --git a/src/FSharp.PowerPack/Parsing.fs b/src/FSharp.PowerPack/Parsing.fs
new file mode 100755
index 0000000..11337d1
--- /dev/null
+++ b/src/FSharp.PowerPack/Parsing.fs
@@ -0,0 +1,509 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+#if INTERNALIZED_POWER_PACK
+
+namespace  Internal.Utilities.Text.Parsing
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+
+#else
+namespace Microsoft.FSharp.Text.Parsing
+open Microsoft.FSharp.Text.Lexing
+#endif
+
+
+
+open System
+open System.Collections.Generic
+
+#if INTERNALIZED_POWER_PACK
+type internal IParseState = 
+#else
+type IParseState = 
+#endif
+    abstract InputRange: int -> Position * Position
+    abstract InputEndPosition: int -> Position 
+    abstract InputStartPosition: int -> Position 
+    abstract ResultRange: Position * Position
+    abstract GetInput: int -> obj 
+    abstract ParserLocalStore : IDictionary<string,obj>
+    abstract RaiseError<'b> : unit -> 'b 
+
+//-------------------------------------------------------------------------
+// This context is passed to the error reporter when a syntax error occurs
+
+[<Sealed>]
+#if INTERNALIZED_POWER_PACK
+type internal ParseErrorContext<'tok>
+#else
+type ParseErrorContext<'tok>
+#endif
+         (//lexbuf: LexBuffer<_>,
+          stateStack:int list,
+          parseState: IParseState, 
+          reduceTokens: int list, 
+          currentToken: 'tok option, 
+          reducibleProductions: int list list, 
+          shiftableTokens: int list , 
+          message : string) =
+      //member x.LexBuffer = lexbuf
+      member x.StateStack  = stateStack
+      member x.ReduceTokens = reduceTokens
+      member x.CurrentToken = currentToken
+      member x.ParseState = parseState
+      member x.ReducibleProductions = reducibleProductions
+      member x.ShiftTokens = shiftableTokens
+      member x.Message = message
+
+
+//-------------------------------------------------------------------------
+// This is the data structure emitted as code by FSYACC.  
+
+#if INTERNALIZED_POWER_PACK
+type internal Tables<'tok> = 
+#else
+type Tables<'tok> = 
+#endif
+    { reductions: (IParseState -> obj) array;
+      endOfInputTag: int;
+      tagOfToken: 'tok -> int;
+      dataOfToken: 'tok -> obj; 
+      actionTableElements: uint16[];  
+      actionTableRowOffsets: uint16[];
+      reductionSymbolCounts: uint16[];
+      immediateActions: uint16[];
+      gotos: uint16[];
+      sparseGotoTableRowOffsets: uint16[];
+      stateToProdIdxsTableElements: uint16[];  
+      stateToProdIdxsTableRowOffsets: uint16[];  
+      productionToNonTerminalTable: uint16[];
+      /// For fsyacc.exe, this entry is filled in by context from the generated parser file. If no 'parse_error' function
+      /// is defined by the user then ParseHelpers.parse_error is used by default (ParseHelpers is opened
+      /// at the top of the generated parser file)
+      parseError:  ParseErrorContext<'tok> -> unit;
+      numTerminals: int;
+      tagOfErrorTerminal: int }
+
+//-------------------------------------------------------------------------
+// An implementation of stacks.
+
+// This type is in System.dll so for the moment we can't use it in FSharp.Core.dll
+//type Stack<'a> = System.Collections.Generic.Stack<'a>
+
+#if INTERNALIZED_POWER_PACK
+type Stack<'a>(n)  = 
+#else
+type internal Stack<'a>(n)  = 
+#endif
+    let mutable contents = Array.zeroCreate<'a>(n)
+    let mutable count = 0
+
+    member buf.Ensure newSize = 
+        let oldSize = Array.length contents
+        if newSize > oldSize then 
+            let old = contents
+            contents <- Array.zeroCreate (max newSize (oldSize * 2));
+            Array.blit old 0 contents 0 count;
+    
+    member buf.Count = count
+    member buf.Pop() = count <- count - 1
+    member buf.Peep() = contents.[count - 1]
+    member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev
+    member buf.Push(x) =
+        buf.Ensure(count + 1); 
+        contents.[count] <- x; 
+        count <- count + 1
+        
+    member buf.IsEmpty = (count = 0)
+    member buf.PrintStack() = 
+        for i = 0 to (count - 1) do 
+            System.Console.Write("{0}{1}",(contents.[i]),if i=count-1 then ":" else "-") 
+          
+exception RecoverableParseError
+exception Accept of obj
+
+#if DEBUG
+module Flags = 
+    let mutable debug = false
+#endif
+
+#if INTERNALIZED_POWER_PACK
+module internal Implementation = 
+#else
+module Implementation = 
+#endif
+    
+    // Definitions shared with fsyacc 
+    let anyMarker = 0xffff
+    let shiftFlag = 0x0000
+    let reduceFlag = 0x4000
+    let errorFlag = 0x8000
+    let acceptFlag = 0xc000
+    let actionMask = 0xc000
+
+    let actionValue action = action &&& (~~~ actionMask)                                    
+    let actionKind action = action &&& actionMask
+    
+    //-------------------------------------------------------------------------
+    // Read the tables written by FSYACC.  
+
+    type AssocTable(elemTab:uint16[], offsetTab:uint16[]) =
+        let cache = new Dictionary<_,_>(2000)
+
+        member t.readAssoc (minElemNum,maxElemNum,defaultValueOfAssoc,keyToFind) =     
+            // do a binary chop on the table 
+            let elemNumber : int = (minElemNum+maxElemNum)/2
+            if elemNumber = maxElemNum 
+            then defaultValueOfAssoc
+            else 
+                let x = int elemTab.[elemNumber*2]
+                if keyToFind = x then 
+                    int elemTab.[elemNumber*2+1]
+                elif keyToFind < x then t.readAssoc (minElemNum ,elemNumber,defaultValueOfAssoc,keyToFind)
+                else                    t.readAssoc (elemNumber+1,maxElemNum,defaultValueOfAssoc,keyToFind)
+
+        member t.Read(rowNumber ,keyToFind) =
+        
+            // First check the sparse lookaside table
+            // Performance note: without this lookaside table the binary chop in readAssoc
+            // takes up around 10% of of parsing time 
+            // for parsing intensive samples such as the bootstrapped F# compiler.
+            //
+            // Note: using a .NET Dictionary for this int -> int table looks like it could be sub-optimal.
+            // Some other better sparse lookup table may be better.
+            let mutable res = 0 
+            let cacheKey = (rowNumber <<< 16) ||| keyToFind
+            let ok = cache.TryGetValue(cacheKey, &res) 
+            if ok then res 
+            else
+                let headOfTable = int offsetTab.[rowNumber]
+                let firstElemNumber = headOfTable + 1           
+                let numberOfElementsInAssoc = int elemTab.[headOfTable*2]
+                let defaultValueOfAssoc = int elemTab.[headOfTable*2+1]          
+                let res = t.readAssoc (firstElemNumber,(firstElemNumber+numberOfElementsInAssoc),defaultValueOfAssoc,keyToFind)
+                cache.[cacheKey] <- res
+                res
+
+        // Read all entries in the association table
+        // Used during error recovery to find all valid entries in the table
+        member x.ReadAll(n) =       
+            let headOfTable = int offsetTab.[n]
+            let firstElemNumber = headOfTable + 1           
+            let numberOfElementsInAssoc = int32 elemTab.[headOfTable*2]           
+            let defaultValueOfAssoc = int elemTab.[headOfTable*2+1]          
+            [ for i in firstElemNumber .. (firstElemNumber+numberOfElementsInAssoc-1) -> 
+                (int elemTab.[i*2], int elemTab.[i*2+1]) ], defaultValueOfAssoc
+
+    type IdxToIdxListTable(elemTab:uint16[], offsetTab:uint16[]) =
+
+        // Read all entries in a row of the table
+        member x.ReadAll(n) =       
+            let headOfTable = int offsetTab.[n]
+            let firstElemNumber = headOfTable + 1           
+            let numberOfElements = int32 elemTab.[headOfTable]           
+            [ for i in firstElemNumber .. (firstElemNumber+numberOfElements-1) -> int elemTab.[i] ]
+
+    //-------------------------------------------------------------------------
+    // interpret the tables emitted by FSYACC.  
+
+    [<NoEquality; NoComparison>]
+    [<Struct>]
+    type ValueInfo = 
+        val value: obj
+        val startPos: Position
+        val endPos: Position
+        new(value,startPos,endPos) = { value=value; startPos=startPos;endPos=endPos }
+
+    let interpret (tables: Tables<'tok>) lexer (lexbuf : LexBuffer<_>) initialState =                                                                      
+        let localStore = new Dictionary<string,obj>() in
+        localStore.["LexBuffer"] <- lexbuf;
+#if DEBUG
+        if Flags.debug then System.Console.WriteLine("\nParser: interpret tables");
+#endif
+        let stateStack : Stack<int> = new Stack<_>(100)
+        stateStack.Push(initialState);
+        let valueStack = new Stack<ValueInfo>(100)
+        let mutable haveLookahead = false                                                                              
+        let mutable lookaheadToken = Unchecked.defaultof<'tok>
+        let mutable lookaheadEndPos = Unchecked.defaultof<Position>
+        let mutable lookaheadStartPos = Unchecked.defaultof<Position>
+        let mutable finished = false
+        // After an error occurs, we suppress errors until we've shifted three tokens in a row.
+        let mutable errorSuppressionCountDown = 0
+        
+        // When we hit the end-of-file we don't fail straight away but rather keep permitting shift
+        // and reduce against the last token in the token stream 20 times or until we've accepted
+        // or exhausted the stack. This allows error recovery rules of the form
+        //      input : realInput EOF | realInput error EOF | error EOF
+        // where consuming one EOF to trigger an error doesn't result in overall parse failure 
+        // catastrophe and the loss of intermediate results.
+        //
+        let mutable inEofCountDown = false
+        let mutable eofCountDown = 20 // Number of EOFs to supply at the end for error recovery
+        // The 100 here means a maximum of 100 elements for each rule
+        let ruleStartPoss = (Array.zeroCreate 100 : Position array)              
+        let ruleEndPoss   = (Array.zeroCreate 100 : Position array)              
+        let ruleValues    = (Array.zeroCreate 100 : obj array)              
+        let lhsPos        = (Array.zeroCreate 2 : Position array)                                            
+        let reductions = tables.reductions
+        let actionTable = new AssocTable(tables.actionTableElements, tables.actionTableRowOffsets)
+        let gotoTable = new AssocTable(tables.gotos, tables.sparseGotoTableRowOffsets)
+        let stateToProdIdxsTable = new IdxToIdxListTable(tables.stateToProdIdxsTableElements, tables.stateToProdIdxsTableRowOffsets)
+
+        let parseState =                                                                                            
+            { new IParseState with 
+                member p.InputRange(n) = ruleStartPoss.[n-1], ruleEndPoss.[n-1]; 
+                member p.InputStartPosition(n) = ruleStartPoss.[n-1]
+                member p.InputEndPosition(n) = ruleEndPoss.[n-1]; 
+                member p.GetInput(n)    = ruleValues.[n-1];        
+                member p.ResultRange    = (lhsPos.[0], lhsPos.[1]);  
+                member p.ParserLocalStore = (localStore :> IDictionary<_,_>); 
+                member p.RaiseError()  = raise RecoverableParseError  (* NOTE: this binding tests the fairly complex logic associated with an object expression implementing a generic abstract method *)
+            }       
+
+#if DEBUG
+        let report haveLookahead lookaheadToken = 
+            if haveLookahead then sprintf "%A" lookaheadToken 
+            else "[TBC]"
+#endif
+
+        // Pop the stack until we can shift the 'error' token. If 'tokenOpt' is given
+        // then keep popping until we can shift both the 'error' token and the token in 'tokenOpt'.
+        // This is used at end-of-file to make sure we can shift both the 'error' token and the 'EOF' token.
+        let rec popStackUntilErrorShifted(tokenOpt) =
+            // Keep popping the stack until the "error" terminal is shifted
+#if DEBUG
+            if Flags.debug then System.Console.WriteLine("popStackUntilErrorShifted");
+#endif
+            if stateStack.IsEmpty then 
+#if DEBUG
+                if Flags.debug then 
+                    System.Console.WriteLine("state stack empty during error recovery - generating parse error");
+#endif
+                failwith "parse error";
+            
+            let currState = stateStack.Peep()
+#if DEBUG
+            if Flags.debug then 
+                System.Console.WriteLine("In state {0} during error recovery", currState);
+#endif
+            
+            let action = actionTable.Read(currState, tables.tagOfErrorTerminal)
+            
+            if actionKind action = shiftFlag &&  
+                (match tokenOpt with 
+                 | None -> true
+                 | Some(token) -> 
+                    let nextState = actionValue action 
+                    actionKind (actionTable.Read(nextState, tables.tagOfToken(token))) = shiftFlag) then
+
+#if DEBUG
+                if Flags.debug then System.Console.WriteLine("shifting error, continuing with error recovery");
+#endif
+                let nextState = actionValue action 
+                // The "error" non terminal needs position information, though it tends to be unreliable.
+                // Use the StartPos/EndPos from the lex buffer
+                valueStack.Push(ValueInfo(box (), lexbuf.StartPos, lexbuf.EndPos));
+                stateStack.Push(nextState)
+            else
+                if valueStack.IsEmpty then 
+                    failwith "parse error";
+#if DEBUG
+                if Flags.debug then 
+                    System.Console.WriteLine("popping stack during error recovery");
+#endif
+                valueStack.Pop();
+                stateStack.Pop();
+                popStackUntilErrorShifted(tokenOpt)
+
+        while not finished do                                                                                    
+            if stateStack.IsEmpty then 
+                finished <- true
+            else
+                let state = stateStack.Peep()
+#if DEBUG
+                if Flags.debug then (Console.Write("{0} value(state), state ",valueStack.Count); stateStack.PrintStack())
+#endif
+                let action = 
+                    let immediateAction = int tables.immediateActions.[state]
+                    if not (immediateAction = anyMarker) then
+                        // Action has been pre-determined, no need to lookahead 
+                        // Expecting it to be a Reduce action on a non-fakeStartNonTerminal ? 
+                        immediateAction
+                    else
+                        // Lookahead required to determine action 
+                        if not haveLookahead then 
+                            if lexbuf.IsPastEndOfStream then 
+                                // When the input runs out, keep supplying the last token for eofCountDown times
+                                if eofCountDown>0 then
+                                    haveLookahead <- true
+                                    eofCountDown <- eofCountDown - 1
+                                    inEofCountDown <- true
+                                else 
+                                    haveLookahead <- false
+                            else 
+                                lookaheadToken <- lexer lexbuf
+                                lookaheadStartPos <- lexbuf.StartPos
+                                lookaheadEndPos <- lexbuf.EndPos
+                                haveLookahead <- true;
+
+                        let tag = 
+                            if haveLookahead then tables.tagOfToken lookaheadToken 
+                            else tables.endOfInputTag   
+                                    
+                        // Printf.printf "state %d\n" state  
+                        actionTable.Read(state,tag)
+                        
+                let kind = actionKind action 
+                if kind = shiftFlag then (
+                    if errorSuppressionCountDown > 0 then 
+                        errorSuppressionCountDown <- errorSuppressionCountDown - 1;
+#if DEBUG
+                        if Flags.debug then Console.WriteLine("shifting, reduced errorRecoverylevel to {0}\n", errorSuppressionCountDown);
+#endif
+                    let nextState = actionValue action                                     
+                    if not haveLookahead then failwith "shift on end of input!";
+                    let data = tables.dataOfToken lookaheadToken
+                    valueStack.Push(ValueInfo(data, lookaheadStartPos, lookaheadEndPos));
+                    stateStack.Push(nextState);                                                                
+#if DEBUG
+                    if Flags.debug then Console.WriteLine("shift/consume input {0}, shift to state {1}", report haveLookahead lookaheadToken, nextState);
+#endif
+                    haveLookahead <- false
+
+                ) elif kind = reduceFlag then
+                    let prod = actionValue action                                     
+                    let reduction = reductions.[prod]                                                             
+                    let n = int tables.reductionSymbolCounts.[prod]
+                       // pop the symbols, populate the values and populate the locations                              
+#if DEBUG
+                    if Flags.debug then Console.Write("reduce popping {0} values/states, lookahead {1}", n, report haveLookahead lookaheadToken);
+#endif
+                    
+                    lhsPos.[0] <- Position.Empty;                                                                     
+                    lhsPos.[1] <- Position.Empty;  
+                    for i = 0 to n - 1 do                                                                             
+                        if valueStack.IsEmpty then failwith "empty symbol stack";
+                        let topVal = valueStack.Peep()
+                        valueStack.Pop();
+                        stateStack.Pop();
+                        ruleValues.[(n-i)-1] <- topVal.value;  
+                        ruleStartPoss.[(n-i)-1] <- topVal.startPos;  
+                        ruleEndPoss.[(n-i)-1] <- topVal.endPos;  
+                        if lhsPos.[1] = Position.Empty then lhsPos.[1] <- topVal.endPos;
+                        if not (topVal.startPos = Position.Empty) then lhsPos.[0] <- topVal.startPos
+                    done;                                                                                           
+                    
+                    try                                                                                               
+                          // Printf.printf "reduce %d\n" prod;                                                       
+                        let redResult = reduction parseState                                                          
+                        valueStack.Push(ValueInfo(redResult, lhsPos.[0], lhsPos.[1]));
+                        let currState = stateStack.Peep()
+                        let newGotoState = gotoTable.Read(int tables.productionToNonTerminalTable.[prod], currState)
+                        stateStack.Push(newGotoState)
+#if DEBUG
+                        if Flags.debug then Console.WriteLine(" goto state {0}", newGotoState)
+#endif
+                    with                                                                                              
+                    | Accept res ->                                                                            
+                          finished <- true;                                                                             
+                          valueStack.Push(ValueInfo(res, lhsPos.[0], lhsPos.[1])) 
+                    | RecoverableParseError ->
+#if DEBUG
+                          if Flags.debug then Console.WriteLine("RecoverableParseErrorException...\n");
+#endif
+                          popStackUntilErrorShifted(None);
+                          // User code raised a Parse_error. Don't report errors again until three tokens have been shifted 
+                          errorSuppressionCountDown <- 3
+                elif kind = errorFlag then (
+#if DEBUG
+                    if Flags.debug then Console.Write("ErrorFlag... ");
+#endif
+                    // Silently discard inputs and don't report errors 
+                    // until three tokens in a row have been shifted 
+#if DEBUG
+                    if Flags.debug then printfn "error on token '%A' " (if haveLookahead then Some(lookaheadToken) else None);
+#endif
+                    if errorSuppressionCountDown > 0 then 
+                        // If we're in the end-of-file count down then we're very keen to 'Accept'.
+                        // We can only do this by repeatedly popping the stack until we can shift both an 'error' token
+                        // and an EOF token. 
+                        if inEofCountDown && eofCountDown < 10 then 
+#if DEBUG
+                            if Flags.debug then printfn "poppin stack, lokking to shift both 'error' and that token, during end-of-file error recovery" ;
+#endif
+                            popStackUntilErrorShifted(if haveLookahead then Some(lookaheadToken) else None);
+
+                        // If we don't haveLookahead then the end-of-file count down is over and we have no further options.
+                        if not haveLookahead then 
+                            failwith "parse error: unexpected end of file"
+                            
+#if DEBUG
+                        if Flags.debug then printfn "discarding token '%A' during error suppression" (if haveLookahead then Some(lookaheadToken) else None);
+#endif
+                        // Discard the token
+                        haveLookahead <- false
+                        // Try again to shift three tokens
+                        errorSuppressionCountDown <- 3
+                    else (
+
+                        let currentToken = if haveLookahead then Some(lookaheadToken) else None
+                        let actions,defaultAction = actionTable.ReadAll(state) 
+                        let explicit = Set.ofList [ for (tag,_action) in actions -> tag ]
+                        
+                        let shiftableTokens = 
+                           [ for (tag,action) in actions do
+                                 if (actionKind action) = shiftFlag then 
+                                     yield tag
+                             if actionKind defaultAction = shiftFlag  then
+                                 for tag in 0 .. tables.numTerminals-1 do  
+                                    if not (explicit.Contains(tag)) then 
+                                         yield tag ] in
+
+                        let stateStack = stateStack.Top(12) in
+                        let reducibleProductions = 
+                            [ for state in stateStack do 
+                               yield stateToProdIdxsTable.ReadAll(state)  ]
+
+                        let reduceTokens = 
+                           [ for (tag,action) in actions do
+                                if actionKind(action) = reduceFlag then
+                                    yield tag
+                             if actionKind(defaultAction) = reduceFlag  then
+                                 for tag in 0 .. tables.numTerminals-1 do  
+                                    if not (explicit.Contains(tag)) then 
+                                         yield tag ] in
+                        //let activeRules = stateStack |> List.iter (fun state -> 
+                        let errorContext = new ParseErrorContext<'tok>(stateStack,parseState, reduceTokens,currentToken,reducibleProductions, shiftableTokens, "syntax error")
+                        tables.parseError(errorContext);
+                        popStackUntilErrorShifted(None);
+                        errorSuppressionCountDown <- 3;
+#if DEBUG
+                        if Flags.debug then System.Console.WriteLine("generated syntax error and shifted error token, haveLookahead = {0}\n", haveLookahead);
+#endif
+                    )
+                ) elif kind = acceptFlag then 
+                    finished <- true
+#if DEBUG
+                else
+                  if Flags.debug then System.Console.WriteLine("ALARM!!! drop through case in parser");  
+#endif
+        done;                                                                                                     
+        // OK, we're done - read off the overall generated value
+        valueStack.Peep().value
+
+#if INTERNALIZED_POWER_PACK
+type internal Tables<'tok> with
+#else
+type Tables<'tok> with
+#endif
+    member tables.Interpret (lexer,lexbuf,initialState) = 
+        Implementation.interpret tables lexer lexbuf initialState
+    
+#if INTERNALIZED_POWER_PACK
+module internal ParseHelpers = 
+#else
+module ParseHelpers = 
+#endif
+    let parse_error (_s:string) = ()
+    let parse_error_rich = (None : (ParseErrorContext<_> -> unit) option)
diff --git a/src/FSharp.PowerPack/Parsing.fsi b/src/FSharp.PowerPack/Parsing.fsi
new file mode 100755
index 0000000..7b86284
--- /dev/null
+++ b/src/FSharp.PowerPack/Parsing.fsi
@@ -0,0 +1,130 @@
+//==========================================================================
+// (c) Microsoft Corporation 2005-2009.
+//=========================================================================
+
+#if INTERNALIZED_POWER_PACK
+namespace Internal.Utilities.Text.Parsing
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+#else
+namespace Microsoft.FSharp.Text.Parsing
+open Microsoft.FSharp.Text.Lexing
+#endif
+
+open System.Collections.Generic
+
+#if INTERNALIZED_POWER_PACK
+type internal IParseState = 
+#else
+/// The information accessible via the <c>parseState</c> value within parser actions.
+type IParseState = 
+#endif
+    /// Get the start and end position for the terminal or non-terminal at a given index matched by the production
+    abstract InputRange: index:int -> Position * Position
+    /// Get the end position for the terminal or non-terminal at a given index matched by the production
+    abstract InputEndPosition: int -> Position 
+    /// Get the start position for the terminal or non-terminal at a given index matched by the production
+    abstract InputStartPosition: int -> Position 
+    /// Get the full range of positions matched by the production
+    abstract ResultRange: Position * Position
+    /// Get the value produced by the terminal or non-terminal at the given position
+    abstract GetInput   : int -> obj 
+    /// Get the store of local values associated with this parser
+    // Dynamically typed, non-lexically scoped local store
+    abstract ParserLocalStore : IDictionary<string,obj>
+    /// Raise an error in this parse context
+    abstract RaiseError<'b> : unit -> 'b 
+
+
+[<Sealed>]
+#if INTERNALIZED_POWER_PACK
+type internal ParseErrorContext<'tok> =
+#else
+/// The context provided when a parse error occurs
+type ParseErrorContext<'tok> =
+#endif
+      /// The stack of state indexes active at the parse error 
+      member StateStack  : int list
+      /// The state active at the parse error 
+      member ParseState : IParseState
+      /// The tokens that would cause a reduction at the parse error 
+      member ReduceTokens: int list
+      /// The stack of productions that would be reduced at the parse error 
+      member ReducibleProductions : int list list
+      /// The token that caused the parse error
+      member CurrentToken : 'tok option
+      /// The token that would cause a shift at the parse error
+      member ShiftTokens : int list
+      /// The message associated with the parse error
+      member Message : string
+
+/// Tables generated by fsyacc
+#if INTERNALIZED_POWER_PACK
+type internal Tables<'tok> = 
+#else
+/// The type of the tables contained in a file produced by the fsyacc.exe parser generator.
+type Tables<'tok> = 
+#endif
+    { /// The reduction table
+      reductions: (IParseState -> obj) array ;
+      /// The token number indicating the end of input
+      endOfInputTag: int;
+      /// A function to compute the tag of a token
+      tagOfToken: 'tok -> int;
+      /// A function to compute the data carried by a token
+      dataOfToken: 'tok -> obj; 
+      /// The sparse action table elements
+      actionTableElements: uint16[];
+      /// The sparse action table row offsets
+      actionTableRowOffsets: uint16[];
+      /// The number of symbols for each reduction
+      reductionSymbolCounts: uint16[];
+      /// The immediate action table
+      immediateActions: uint16[];      
+      /// The sparse goto table
+      gotos: uint16[];
+      /// The sparse goto table row offsets
+      sparseGotoTableRowOffsets: uint16[];
+      /// The sparse table for the productions active for each state
+      stateToProdIdxsTableElements: uint16[];  
+      /// The sparse table offsets for the productions active for each state
+      stateToProdIdxsTableRowOffsets: uint16[];  
+      /// This table is logically part of the Goto table
+      productionToNonTerminalTable: uint16[];
+      /// This function is used to hold the user specified "parse_error" or "parse_error_rich" functions
+      parseError:  ParseErrorContext<'tok> -> unit;
+      /// The total number of terminals 
+      numTerminals: int;
+      /// The tag of the error terminal
+      tagOfErrorTerminal: int }
+
+    /// Interpret the parser table taking input from the given lexer, using the given lex buffer, and the given start state.
+    /// Returns an object indicating the final synthesized value for the parse.
+    member Interpret :  lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * startState:int -> obj 
+
+#if INTERNALIZED_POWER_PACK
+exception internal Accept of obj
+exception internal RecoverableParseError
+#else
+/// Indicates an accept action has occured
+exception Accept of obj
+/// Indicates a parse error has occured and parse recovery is in progress
+exception RecoverableParseError
+#endif
+
+#if DEBUG
+module internal Flags =
+  val mutable debug : bool
+#endif
+
+#if INTERNALIZED_POWER_PACK
+module internal ParseHelpers = 
+#else
+/// Helpers used by generated parsers.
+module ParseHelpers = 
+#endif
+   /// The default implementation of the parse_error_rich function
+   val parse_error_rich: (ParseErrorContext<'tok> -> unit) option
+   /// The default implementation of the parse_error function
+   val parse_error: string -> unit
+
diff --git a/src/FSharp.PowerPack/Permutation.fs b/src/FSharp.PowerPack/Permutation.fs
new file mode 100755
index 0000000..f988514
--- /dev/null
+++ b/src/FSharp.PowerPack/Permutation.fs
@@ -0,0 +1,56 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+type Permutation = int -> int
+
+type permutation = int -> int
+
+[<RequireQualifiedAccess>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Permutation =
+
+    let invalidArg arg msg = raise (new System.ArgumentException((msg:string),(arg:string)))        
+
+    let ofFreshArray (arr:_[]) = 
+        let arr2 = Array.zeroCreate arr.Length
+        for i = 0 to arr.Length - 1 do 
+            let x = arr.[i] 
+            if x < 0 || x >= arr.Length then invalidArg "arr" "invalid permutation" 
+            arr2.[x] <- 1
+        for i = 0 to arr.Length - 1 do 
+            if arr2.[i] <> 1 then invalidArg "arr" "invalid permutation"
+        (fun k -> arr.[k])
+
+    let ofArray (arr:_[]) = arr |> Array.copy |> ofFreshArray
+
+    let of_array (arr:_[]) = ofArray arr
+
+    let ofPairs  (mappings: seq<int * int>) = 
+      let p = dict mappings 
+      (fun k -> if p.ContainsKey k then p.[k] else k)
+
+    let of_pairs  (mappings: seq<int * int>) =  ofPairs mappings
+
+    let swap (n:int) (m:int) = 
+      (fun k -> if k = n then m elif k = m then n else k)
+
+    let reversal size = 
+      if size <= 0 then invalidArg "size" "a permutation size must be positive";
+      (fun k -> (size - 1 - k))
+
+    let rotation size distance = 
+      if size <= 0 then invalidArg "size" "a permutation size must be positive";
+      if abs distance >= size then invalidArg "distance" "the absolute value of the distance must be less than the size of the permutation";
+      (fun k -> (k + size + distance) % size)
+
+    let identity (k:int) = k
+    
+    let inverse size p =
+        if size <= 0 then invalidArg "size" "a permutation size must be positive";
+        let arr2 = Array.zeroCreate size
+        for i = 0 to size - 1 do
+             arr2.[p i] <- i
+        ofFreshArray arr2
+
+    
\ No newline at end of file
diff --git a/src/FSharp.PowerPack/Permutation.fsi b/src/FSharp.PowerPack/Permutation.fsi
new file mode 100755
index 0000000..18e27c3
--- /dev/null
+++ b/src/FSharp.PowerPack/Permutation.fsi
@@ -0,0 +1,43 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Math
+
+/// A permutation of a finite range of integers 0 .. N-1, represented by a mapping of index positions
+type Permutation = int -> int
+
+[<System.Obsolete("This type abbreviation is now capitalized, please use 'Permutation'")>]
+type permutation = int -> int
+
+[<RequireQualifiedAccess>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Permutation =
+    /// Create a permutation by specifying the result of permuting [| 0 .. n-1 |]. For example, 
+    /// Permutation.ofArray [| 1;2;0 |]  specifies a permutation that rotates all elements right one place.
+    val ofArray : destinations:int array -> Permutation
+    [<System.Obsolete("This function has been renamed. Use 'Permutation.ofArray' instead")>]
+    val of_array : destinations:int array -> Permutation
+
+    /// Create a permutation by specifying (source,destination) index pairs. For example,
+    /// Permutation(3,[ (0,2);(1,0); (2,1) ]) specifies a permutation that rotates 
+    /// all elements left one place. Not all elements need be given, e.g. 
+    /// Permutation(5,[ (1,2);(2,1) |]) specifies a permutation that swaps elements at indexes
+    /// 1 and 2.
+    val ofPairs : mappings: seq<int * int> -> Permutation
+
+    [<System.Obsolete("This function has been renamed. Use 'Permutation.ofPairs' instead")>]
+    val of_pairs : mappings: seq<int * int> -> Permutation
+    
+    /// Return a swaps the given two elements over any size
+    val swap: n:int -> m:int -> Permutation
+
+    /// Return a permutation that, when applied, maps index 0 to size-1, size-1 to 0 etc.
+    val reversal: size:int -> Permutation
+
+    /// Return a permutation that rotates right by the given distance. If the distance
+    /// is negative then a left rotation results.
+    val rotation: size:int -> distance:int -> Permutation
+    
+    /// The identity permutation over any size
+    val identity : Permutation
+    
+    val inverse : size: int -> p:Permutation -> Permutation
+    
\ No newline at end of file
diff --git a/src/FSharp.PowerPack/PhysicalConstants.fs b/src/FSharp.PowerPack/PhysicalConstants.fs
new file mode 100755
index 0000000..64881cb
--- /dev/null
+++ b/src/FSharp.PowerPack/PhysicalConstants.fs
@@ -0,0 +1,91 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+open Microsoft.FSharp.Math.SI
+
+/// Fundamental physical constants, with units-of-measure
+// Selected from frequently used constants at http://physics.nist.gov/cuu/Constants/index.html
+module PhysicalConstants =
+
+  /// speed of light in vacuum
+  [<Literal>]
+  let c = 299792458.0<m/s>
+
+  /// magnetic constant
+  [<Literal>]
+  let mu0 = 12.566370614e-7<N A^-2>
+
+  /// electric constant = 1/(mu0 c^2)
+  [<Literal>]
+  let epsilon0 = 8.854187817e-12<F m^-1>
+
+  /// Newtonian constant of gravitation
+  [<Literal>]
+  let G = 6.6742867e-11<m^3 kg^-1 s^-2>
+  
+  /// Planck constant
+  [<Literal>]
+  let h = 6.6260689633e-34<J s>
+
+  /// Dirac constant, also known as the reduced Planck constant = h/2pi
+  [<Literal>]
+  let hbar = 1.05457162853e-34<J s>
+
+  /// Elementary charge
+  [<Literal>]
+  let e = 1.60217648740e-19<C>
+
+  /// Magnetic flux quantum h/2e
+  [<Literal>]
+  let Phi0 = 2.06783366752e-15<Wb>
+
+  /// Conductance quantum 2e^2/h
+  [<Literal>]
+  let G0 = 7.748091700453e-5<S>
+
+  /// Electron mass
+  [<Literal>]
+  let m_e = 9.1093821545e-31<kg>
+
+  /// Proton mass
+  [<Literal>]
+  let m_p = 1.67262163783e-27<kg>
+
+  /// Fine-structure constant
+  [<Literal>]
+  let alpha = 7.297352537650e-3
+
+  /// Rydberg constant
+  [<Literal>]
+  let R_inf = 10973731.56852773<m^-1>
+
+  /// Avogadro constant
+  [<Literal>]
+  let N_A = 6.0221417930e23<mol^-1>
+
+  /// Faraday constant
+  [<Literal>]
+  let F = 96485.339924<C/mol>
+
+  /// Molar gas constant
+  [<Literal>]
+  let R = 8.31447215<J mol^-1 K^-1> 
+ 
+  /// Boltzmann constant R/N_A
+  [<Literal>]
+  let k = 1.380650424e-23<J/K>
+
+  /// Stefan-Boltzmann constant
+  [<Literal>]
+  let sigma = 5.67040040e-8<W m^-2 K^-4>
+ 
+  /// Electron volt
+  [<Literal>]
+  let eV = 1.60217648740e-19<J>
+
+  /// Unified atomic mass unit
+  [<Literal>]
+  let u = 1.66053878283e-27<kg>
+
+
diff --git a/src/FSharp.PowerPack/PowerPack.fs b/src/FSharp.PowerPack/PowerPack.fs
new file mode 100755
index 0000000..b6947b2
--- /dev/null
+++ b/src/FSharp.PowerPack/PowerPack.fs
@@ -0,0 +1,35 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+module internal Microsoft.FSharp.AssemblyAttributes
+
+//[<assembly: System.Security.SecurityTransparent>]
+[<assembly: AutoOpen("Microsoft.FSharp.Compatibility")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Compatibility.OCaml.Pervasives")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Compatibility.OCaml")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Text")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Control")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Collections")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Core")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Math")>]
+[<assembly: AutoOpen("Microsoft.FSharp")>]
+do()
+
+#if FX_NO_SECURITY_PERMISSIONS
+#else
+#if FX_SIMPLE_SECURITY_PERMISSIONS
+[<assembly: System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.RequestMinimum)>]
+#else
+#endif
+#endif
+
+[<assembly: System.Runtime.InteropServices.ComVisible(false)>]
+
+[<assembly: System.CLSCompliant(true)>]
+
+
+#if FX_NO_DEFAULT_DEPENDENCY_TYPE
+#else
+[<assembly: System.Runtime.CompilerServices.Dependency("FSharp.Core",System.Runtime.CompilerServices.LoadHint.Always)>] 
+#endif
+
+do ()
diff --git a/src/FSharp.PowerPack/ResizeArray.fs b/src/FSharp.PowerPack/ResizeArray.fs
new file mode 100755
index 0000000..27902dc
--- /dev/null
+++ b/src/FSharp.PowerPack/ResizeArray.fs
@@ -0,0 +1,321 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Collections
+
+open Microsoft.FSharp.Core.OptimizedClosures
+
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module ResizeArray =
+
+    let length (arr: ResizeArray<'T>) =  arr.Count
+    let get (arr: ResizeArray<'T>) (n: int) =  arr.[n]
+    let set (arr: ResizeArray<'T>) (n: int) (x:'T) =  arr.[n] <- x
+    let create  (n: int) x = new ResizeArray<_> (seq { for _ in 1 .. n -> x })
+    let init (n: int) (f: int -> 'T) =  new ResizeArray<_> (seq { for i in 0 .. n-1 -> f i })
+
+    let blit (arr1: ResizeArray<'T>) start1 (arr2: ResizeArray<'T>) start2 len =
+        if start1 < 0 then invalidArg "start1" "index must be positive"
+        if start2 < 0 then invalidArg "start2" "index must be positive"
+        if len < 0 then invalidArg "len" "length must be positive"
+        if start1 + len > length arr1 then invalidArg "start1" "(start1+len) out of range"
+        if start2 + len > length arr2 then invalidArg "start2" "(start2+len) out of range"
+        for i = 0 to len - 1 do 
+            arr2.[start2+i] <- arr1.[start1 + i]
+
+    let concat (arrs: ResizeArray<'T> list) = new ResizeArray<_> (seq { for arr in arrs do for x in arr do yield x })
+    let append (arr1: ResizeArray<'T>) (arr2: ResizeArray<'T>) = concat [arr1; arr2]
+
+    let sub (arr: ResizeArray<'T>) start len =
+        if start < 0 then invalidArg "start" "index must be positive"
+        if len < 0 then invalidArg "len" "length must be positive"
+        if start + len > length arr then invalidArg "len" "length must be positive"
+        new ResizeArray<_> (seq { for i in start .. start+len-1 -> arr.[i] })
+
+    let fill (arr: ResizeArray<'T>) (start: int) (len: int) (x:'T) =
+        if start < 0 then invalidArg "start" "index must be positive"
+        if len < 0 then invalidArg "len" "length must be positive"
+        if start + len > length arr then invalidArg "len" "length must be positive"
+        for i = start to start + len - 1 do 
+            arr.[i] <- x
+
+    let copy      (arr: ResizeArray<'T>) = new ResizeArray<_>(arr)
+
+    let toList (arr: ResizeArray<_>) =
+        let mutable res = []
+        for i = length arr - 1 downto 0 do
+            res <- arr.[i] :: res
+        res
+
+    let ofList (l: _ list) =
+        let len = l.Length
+        let res = new ResizeArray<_>(len)
+        let rec add = function
+          | [] -> ()
+          | e::l -> res.Add(e); add l
+        add l
+        res
+
+    let ofSeq (s:seq<_>) = new ResizeArray<_>(s)
+        
+    let iter f (arr: ResizeArray<_>) = 
+        for i = 0 to arr.Count - 1 do
+            f arr.[i]
+
+    let map f (arr: ResizeArray<_>) =
+        let len = length arr
+        let res = new ResizeArray<_>(len)
+        for i = 0 to len - 1 do
+            res.Add(f arr.[i])
+        res
+
+    let mapi f (arr: ResizeArray<_>) =
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        let len = length arr
+        let res = new ResizeArray<_>(len)
+        for i = 0 to len - 1 do
+            res.Add(f.Invoke(i, arr.[i]))
+        res
+        
+    let iteri f (arr: ResizeArray<_>) =
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        for i = 0 to arr.Count - 1 do
+            f.Invoke(i, arr.[i])
+
+    let exists (f: 'T -> bool) (arr: ResizeArray<'T>) =
+        let len = length arr 
+        let rec loop i = i < len && (f arr.[i] || loop (i+1))
+        loop 0
+
+    let forall f (arr: ResizeArray<_>) =
+        let len = length arr
+        let rec loop i = i >= len || (f arr.[i] && loop (i+1))
+        loop 0
+
+    let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
+
+    let find f (arr: ResizeArray<_>) = 
+        let rec loop i = 
+            if i >= length arr then indexNotFound()
+            elif f arr.[i] then arr.[i]
+            else loop (i+1)
+        loop 0
+
+    let tryPick f (arr: ResizeArray<_>) =
+        let rec loop i = 
+            if i >= length arr then None else
+            match f arr.[i] with 
+            | None -> loop(i+1)
+            | res -> res
+        loop 0
+
+    let tryFind f (arr: ResizeArray<_>) = 
+        let rec loop i = 
+            if i >= length arr then None
+            elif f arr.[i] then Some arr.[i]
+            else loop (i+1)
+        loop 0
+
+    let iter2 f (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = 
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        for i = 0 to len1 - 1 do 
+            f.Invoke(arr1.[i], arr2.[i])
+
+    let map2 f (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = 
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        let res = new ResizeArray<_>(len1)
+        for i = 0 to len1 - 1 do
+            res.Add(f.Invoke(arr1.[i], arr2.[i]))
+        res
+
+    let choose f (arr: ResizeArray<_>) = 
+        let res = new ResizeArray<_>() 
+        for i = 0 to length arr - 1 do
+            match f arr.[i] with 
+            | None -> ()
+            | Some b -> res.Add(b)
+        res
+
+    let filter f (arr: ResizeArray<_>) = 
+        let res = new ResizeArray<_>() 
+        for i = 0 to length arr - 1 do 
+            let x = arr.[i] 
+            if f x then res.Add(x)
+        res
+
+    let partition f (arr: ResizeArray<_>) = 
+      let res1 = new ResizeArray<_>()
+      let res2 = new ResizeArray<_>()
+      for i = 0 to length arr - 1 do 
+          let x = arr.[i] 
+          if f x then res1.Add(x) else res2.Add(x)
+      res1, res2
+
+    let rev (arr: ResizeArray<_>) = 
+      let len = length arr 
+      let res = new ResizeArray<_>(len)
+      for i = len - 1 downto 0 do 
+          res.Add(arr.[i])
+      res
+
+    let foldBack (f : 'T -> 'State -> 'State) (arr: ResizeArray<'T>) (acc: 'State) =
+        let mutable res = acc 
+        let len = length arr 
+        for i = len - 1 downto 0 do 
+            res <- f (get arr i) res
+        res
+
+    let fold (f : 'State -> 'T -> 'State) (acc: 'State) (arr: ResizeArray<'T>) =
+        let mutable res = acc 
+        let len = length arr 
+        for i = 0 to len - 1 do 
+            res <- f res (get arr i)
+        res
+
+    let toArray (arr: ResizeArray<'T>) = arr.ToArray()
+    let ofArray (arr: 'T[]) = new ResizeArray<_>(arr)
+    let toSeq (arr: ResizeArray<'T>) = Seq.readonly arr
+
+    let sort f (arr: ResizeArray<'T>) = arr.Sort (System.Comparison(f))
+    let sortBy f (arr: ResizeArray<'T>) = arr.Sort (System.Comparison(fun x y -> compare (f x) (f y)))
+
+
+    let exists2 f (arr1: ResizeArray<_>) (arr2: ResizeArray<_>) =
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        let rec loop i = i < len1 && (f arr1.[i] arr2.[i] || loop (i+1))
+        loop 0
+
+    let findIndex f (arr: ResizeArray<_>) =
+        let rec go n = if n >= length arr then indexNotFound() elif f arr.[n] then n else go (n+1)
+        go 0
+
+    let findIndexi f (arr: ResizeArray<_>) =
+        let rec go n = if n >= length arr then indexNotFound() elif f n arr.[n] then n else go (n+1)
+        go 0
+
+    let foldSub f acc (arr: ResizeArray<_>) start fin = 
+        let mutable res = acc
+        for i = start to fin do
+            res <- f res arr.[i] 
+        res
+
+    let foldBackSub f (arr: ResizeArray<_>) start fin acc = 
+        let mutable res = acc 
+        for i = fin downto start do
+            res <- f arr.[i] res
+        res
+
+    let reduce f (arr : ResizeArray<_>) =
+        let arrn = length arr
+        if arrn = 0 then invalidArg "arr" "the input array may not be empty"
+        else foldSub f arr.[0] arr 1 (arrn - 1)
+        
+    let reduceBack f (arr: ResizeArray<_>) = 
+        let arrn = length arr
+        if arrn = 0 then invalidArg "arr" "the input array may not be empty"
+        else foldBackSub f arr 0 (arrn - 2) arr.[arrn - 1]
+
+    let fold2 f (acc: 'T) (arr1: ResizeArray<'T1>) (arr2: ResizeArray<'T2>) =
+        let f = FSharpFunc<_,_,_,_>.Adapt(f)
+        let mutable res = acc 
+        let len = length arr1
+        if len <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        for i = 0 to len - 1 do
+            res <- f.Invoke(res,arr1.[i],arr2.[i])
+        res
+
+    let foldBack2 f (arr1: ResizeArray<'T1>) (arr2: ResizeArray<'T2>) (acc: 'b) =
+        let f = FSharpFunc<_,_,_,_>.Adapt(f)
+        let mutable res = acc 
+        let len = length arr1
+        if len <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        for i = len - 1 downto 0 do 
+            res <- f.Invoke(arr1.[i],arr2.[i],res)
+        res
+
+    let forall2 f (arr1: ResizeArray<_>) (arr2: ResizeArray<_>) = 
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        let rec loop i = i >= len1 || (f arr1.[i] arr2.[i] && loop (i+1))
+        loop 0
+        
+    let isEmpty (arr: ResizeArray<_>) = length (arr: ResizeArray<_>) = 0
+    
+    let iteri2 f (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) =
+        let f = FSharpFunc<_,_,_,_>.Adapt(f)
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        for i = 0 to len1 - 1 do 
+            f.Invoke(i,arr1.[i], arr2.[i])
+
+    let mapi2 (f: int -> 'T -> 'b -> 'c) (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = 
+        let f = FSharpFunc<_,_,_,_>.Adapt(f)
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        init len1 (fun i -> f.Invoke(i, arr1.[i], arr2.[i]))
+
+    let scanBackSub f (arr: ResizeArray<'T>) start fin acc = 
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        let mutable state = acc
+        let res = create (2+fin-start) acc
+        for i = fin downto start do
+            state <- f.Invoke(arr.[i], state)
+            res.[i - start] <- state
+        res
+
+    let scanSub f  acc (arr : ResizeArray<'T>) start fin = 
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        let mutable state = acc
+        let res = create (fin-start+2) acc
+        for i = start to fin do
+            state <- f.Invoke(state, arr.[i])
+            res.[i - start+1] <- state
+        res
+
+    let scan f acc (arr : ResizeArray<'T>) = 
+        let arrn = length arr
+        scanSub f acc arr 0 (arrn - 1)
+
+    let scanBack f (arr : ResizeArray<'T>) acc = 
+        let arrn = length arr
+        scanBackSub f arr 0 (arrn - 1) acc
+
+    let singleton x =
+        let res = new ResizeArray<_>(1)
+        res.Add(x)
+        res
+
+    let tryFindIndex f (arr: ResizeArray<'T>) = 
+        let rec go n = if n >= length arr then None elif f arr.[n] then Some n else go (n+1)
+        go 0
+        
+    let tryFindIndexi f (arr: ResizeArray<'T>) = 
+        let rec go n = if n >= length arr then None elif f n arr.[n] then Some n else go (n+1)
+        go 0
+    
+    let zip (arr1: ResizeArray<_>) (arr2: ResizeArray<_>) = 
+        let len1 = length arr1 
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        init len1 (fun i -> arr1.[i], arr2.[i])
+
+    let unzip (arr: ResizeArray<_>) = 
+        let len = length arr
+        let res1 = new ResizeArray<_>(len)
+        let res2 = new ResizeArray<_>(len)
+        for i = 0 to len - 1 do 
+            let x,y = arr.[i] 
+            res1.Add(x)
+            res2.Add(y)
+        res1,res2
+
+    let combine (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = zip arr1 arr2
+    let split (arr: ResizeArray<_>) = unzip arr
+
+    let to_list arr = toList arr
+    let of_list l = ofList l
+    let to_seq arr = toSeq arr
diff --git a/src/FSharp.PowerPack/ResizeArray.fsi b/src/FSharp.PowerPack/ResizeArray.fsi
new file mode 100755
index 0000000..3e86f87
--- /dev/null
+++ b/src/FSharp.PowerPack/ResizeArray.fsi
@@ -0,0 +1,240 @@
+//==========================================================================
+// ResizeArray
+// 
+// (c) Microsoft Corporation 2005-2008.  
+//===========================================================================
+
+namespace Microsoft.FSharp.Collections
+
+
+open System
+open System.Collections.Generic
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+/// Generic operations on the type System.Collections.Generic.List, which is called ResizeArray in the F# libraries.
+module ResizeArray =
+
+    /// Return the length of the collection.  You can also use property <c>arr.Length</c>.
+    val length: ResizeArray<'T> -> int
+
+    /// Fetch an element from the collection.  You can also use the syntax <c>arr.[idx]</c>.
+    val get: ResizeArray<'T> -> int -> 'T
+
+
+    /// Set the value of an element in the collection. You can also use the syntax <c>arr.[idx] <- e</c>.
+    val set: ResizeArray<'T> -> int -> 'T -> unit
+
+    /// Create an array whose elements are all initially the given value.
+    val create: int -> 'T -> ResizeArray<'T>
+     
+    /// Create an array by calling the given generator on each index.
+    val init: int -> (int -> 'T) -> ResizeArray<'T>
+
+    ///Build a new array that contains the elements of the first array followed by the elements of the second array
+    val append: ResizeArray<'T> -> ResizeArray<'T> -> ResizeArray<'T>
+
+    ///Build a new array that contains the elements of each of the given list of arrays
+    val concat: ResizeArray<'T> list -> ResizeArray<'T>
+
+    ///Build a new array that contains the given subrange specified by
+    ///starting index and length.
+    val sub: ResizeArray<'T> -> int -> int -> ResizeArray<'T>
+
+    ///Build a new array that contains the elements of the given array
+    val copy: ResizeArray<'T> -> ResizeArray<'T>
+
+    ///Fill a range of the collection with the given element
+    val fill: ResizeArray<'T> -> int -> int -> 'T -> unit
+
+    ///Read a range of elements from the first array and write them into the second.
+    val blit: ResizeArray<'T> -> int -> ResizeArray<'T> -> int -> int -> unit
+
+    ///Build a list from the given array
+    val toList: ResizeArray<'T> -> 'T list
+    [<System.Obsolete("This function has been renamed. Use 'ResizeArray.toList' instead")>]
+    val to_list: ResizeArray<'T> -> 'T list
+
+    ///Build an array from the given list
+    val ofList: 'T list -> ResizeArray<'T>
+    [<System.Obsolete("This function has been renamed. Use 'ResizeArray.ofList' instead")>]
+    val of_list: 'T list -> ResizeArray<'T>
+
+    ///Build and array from the given seq
+    val ofSeq : 'T seq -> ResizeArray<'T>
+
+    /// Apply a function to each element of the collection, threading an accumulator argument
+    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
+    /// then computes <c>f (... (f s i0)...) iN</c>
+    val fold: ('T -> 'U -> 'T) -> 'T -> ResizeArray<'U> -> 'T
+
+    /// Apply a function to each element of the array, threading an accumulator argument
+    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then 
+    /// computes <c>f i0 (...(f iN s))</c>.
+    val foldBack: ('T -> 'U -> 'U) -> ResizeArray<'T> -> 'U -> 'U
+
+    ///Apply the given function to each element of the array. 
+    val iter: ('T -> unit) -> ResizeArray<'T> -> unit
+
+    ///Build a new array whose elements are the results of applying the given function
+    ///to each of the elements of the array.
+    val map: ('T -> 'U) -> ResizeArray<'T> -> ResizeArray<'U>
+
+    ///Apply the given function to two arrays simultaneously. The
+    ///two arrays must have the same lengths, otherwise an Invalid_argument exception is
+    ///raised.
+    val iter2: ('T -> 'U -> unit) -> ResizeArray<'T> -> ResizeArray<'U> -> unit
+
+    ///Build a new collection whose elements are the results of applying the given function
+    ///to the corresponding elements of the two collections pairwise.  The two input
+    ///arrays must have the same lengths.
+    val map2: ('T -> 'U -> 'c) -> ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<'c>
+
+    ///Apply the given function to each element of the array.  The integer passed to the
+    ///function indicates the index of element.
+    val iteri: (int -> 'T -> unit) -> ResizeArray<'T> -> unit
+
+    ///Build a new array whose elements are the results of applying the given function
+    ///to each of the elements of the array. The integer index passed to the
+    ///function indicates the index of element being transformed.
+    val mapi: (int -> 'T -> 'U) -> ResizeArray<'T> -> ResizeArray<'U>
+
+    /// Test if any element of the array satisfies the given predicate.
+    /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
+    /// then computes <c>p i0 or ... or p iN</c>.
+    val exists: ('T -> bool) -> ResizeArray<'T> -> bool
+
+    /// Test if all elements of the array satisfy the given predicate.
+    /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> and "j0...jN"
+    /// then computes <c>p i0 && ... && p iN</c>.
+    val forall: ('T -> bool) -> ResizeArray<'T> -> bool
+
+    ///Return a new collection containing only the elements of the collection
+    ///for which the given predicate returns <c>true</c>
+    val filter: ('T -> bool) -> ResizeArray<'T> -> ResizeArray<'T>
+
+    ///Split the collection into two collections, containing the 
+    ///elements for which the given predicate returns <c>true</c> and <c>false</c>
+    ///respectively 
+    val partition: ('T -> bool) -> ResizeArray<'T> -> ResizeArray<'T> * ResizeArray<'T>
+
+    ///Apply the given function to each element of the array. Return
+    ///the array comprised of the results "x" for each element where
+    ///the function returns Some(x)
+    val choose: ('T -> 'U option) -> ResizeArray<'T> -> ResizeArray<'U>
+
+    ///Return the first element for which the given function returns <c>true</c>.
+    ///Raise <c>KeyNotFoundException</c> if no such element exists.
+    val find: ('T -> bool) -> ResizeArray<'T> -> 'T
+
+    ///Return the first element for which the given function returns <c>true</c>.
+    ///Return None if no such element exists.
+    val tryFind: ('T -> bool) -> ResizeArray<'T> -> 'T option
+
+    ///Apply the given function to successive elements, returning the first
+    ///result where function returns "Some(x)" for some x.
+    val tryPick: ('T -> 'U option) -> ResizeArray<'T> -> 'U option
+
+    ///Combine the two arrays into an array of pairs. The two arrays must have equal lengths.
+    [<Obsolete("Use unzip instead")>]
+    val combine: ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<('T * 'U)>
+
+    ///Split a list of pairs into two lists
+    [<Obsolete("Use unzip instead")>]
+    val split: ResizeArray<('T * 'U)> -> (ResizeArray<'T> * ResizeArray<'U>)
+
+    ///Return a new array with the elements in reverse order
+    val rev: ResizeArray<'T> -> ResizeArray<'T>
+
+    /// Sort the elements using the given comparison function
+    val sort: ('T -> 'T -> int) -> ResizeArray<'T> -> unit
+
+    /// Sort the elements using the key extractor and generic comparison on the keys
+    val sortBy: ('T -> 'Key) -> ResizeArray<'T> -> unit when 'Key : comparison
+
+    /// Return a fixed-length array containing the elements of the input ResizeArray
+    val toArray : ResizeArray<'T> -> 'T[]
+    /// Build a ResizeArray from the given elements
+    val ofArray : 'T[] -> ResizeArray<'T>
+    /// Return a view of the array as an enumerable object
+    val toSeq : ResizeArray<'T> -> seq<'T>
+    [<System.Obsolete("This function has been renamed. Use 'ResizeArray.toSeq' instead")>]
+    val to_seq : ResizeArray<'T> -> seq<'T>
+
+    /// Test elements of the two arrays pairwise to see if any pair of element satisfies the given predicate.
+    /// Raise ArgumentException if the arrays have different lengths.
+    val exists2 : ('T -> 'U -> bool) -> ResizeArray<'T> -> ResizeArray<'U> -> bool
+
+    /// Return the index of the first element in the array
+    /// that satisfies the given predicate. Raise <c>KeyNotFoundException</c> if 
+    /// none of the elements satisfy the predicate.
+    val findIndex : ('T -> bool) -> ResizeArray<'T> -> int
+
+    /// Return the index of the first element in the array
+    /// that satisfies the given predicate. Raise <c>KeyNotFoundException</c> if 
+    /// none of the elements satisfy the predicate.
+    val findIndexi : (int -> 'T -> bool) -> ResizeArray<'T> -> int
+
+    /// Apply a function to each element of the array, threading an accumulator argument
+    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
+    /// then computes <c>f (... (f i0 i1)...) iN</c>. Raises ArgumentException if the array has size zero.
+    val reduce : ('T -> 'T -> 'T) -> ResizeArray<'T> -> 'T
+
+    /// Apply a function to each element of the array, threading an accumulator argument
+    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then 
+    /// computes <c>f i0 (...(f iN-1 iN))</c>. Raises ArgumentException if the array has size zero.
+    val reduceBack : ('T -> 'T -> 'T) -> ResizeArray<'T> -> 'T
+
+    /// Apply a function to pairs of elements drawn from the two collections, 
+    /// left-to-right, threading an accumulator argument
+    /// through the computation.  The two input
+    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
+    /// raised.
+    val fold2: ('state -> 'b1 -> 'b2 -> 'state) -> 'state -> ResizeArray<'b1> -> ResizeArray<'b2> -> 'state
+
+    /// Apply a function to pairs of elements drawn from the two collections, right-to-left, 
+    /// threading an accumulator argument through the computation.  The two input
+    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
+    /// raised.
+    val foldBack2 : ('a1 -> 'a2 -> 'U -> 'U) -> ResizeArray<'a1> -> ResizeArray<'a2> -> 'U -> 'U
+
+    /// Test elements of the two arrays pairwise to see if all pairs of elements satisfy the given predicate.
+    /// Raise ArgumentException if the arrays have different lengths.
+    val forall2 : ('T -> 'U -> bool) -> ResizeArray<'T> -> ResizeArray<'U> -> bool
+
+    /// Return true if the given array is empty, otherwise false
+    val isEmpty : ResizeArray<'T> -> bool
+
+    /// Apply the given function to pair of elements drawn from matching indices in two arrays,
+    /// also passing the index of the elements. The two arrays must have the same lengths, 
+    /// otherwise an <c>ArgumentException</c> is raised.
+    val iteri2 : (int -> 'T -> 'U -> unit) -> ResizeArray<'T> -> ResizeArray<'U> -> unit
+
+    /// Build a new collection whose elements are the results of applying the given function
+    /// to the corresponding elements of the two collections pairwise.  The two input
+    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
+    /// raised.
+    val mapi2 : (int -> 'T -> 'U -> 'c) -> ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<'c>
+
+    /// Like <c>fold</c>, but return the intermediary and final results
+    val scan : ('U -> 'T -> 'U) -> 'U -> ResizeArray<'T> -> ResizeArray<'U>
+
+    /// Like <c>foldBack</c>, but return both the intermediary and final results
+    val scanBack : ('T -> 'c -> 'c) -> ResizeArray<'T> -> 'c -> ResizeArray<'c>
+
+    /// Return an array containing the given element
+    val singleton : 'T -> ResizeArray<'T>
+    
+    /// Return the index of the first element in the array
+    /// that satisfies the given predicate.
+    val tryFindIndex : ('T -> bool) -> ResizeArray<'T> -> int option
+
+    /// Return the index of the first element in the array
+    /// that satisfies the given predicate.
+    val tryFindIndexi : (int -> 'T -> bool) -> ResizeArray<'T> -> int option
+
+    /// Combine the two arrays into an array of pairs. The two arrays must have equal lengths, otherwise an <c>ArgumentException</c> is
+    /// raised..
+    val zip : ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<'T * 'U>
+
+    /// Split an array of pairs into two arrays
+    val unzip : ResizeArray<'T * 'U> -> ResizeArray<'T> * ResizeArray<'U>
diff --git a/src/FSharp.PowerPack/SI.fs b/src/FSharp.PowerPack/SI.fs
new file mode 100755
index 0000000..60f682d
--- /dev/null
+++ b/src/FSharp.PowerPack/SI.fs
@@ -0,0 +1,113 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+
+// System Internationale. See http://www.bipm.org/en/si/si_brochure/general.html
+/// The International System of Units (SI)
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module SI =
+
+  [<Measure>] 
+  /// metre (or meter), SI unit of length
+  type m               
+
+  [<Measure>] 
+  /// kilogram, SI unit of mass
+  type kg
+
+  [<Measure>] 
+  /// second, SI unit of time
+  type s
+
+  [<Measure>] 
+  /// ampere, SI unit of electric current
+  type A             
+
+  [<Measure>] 
+  /// kelvin, SI unit of thermodynamic temperature
+  type K              
+
+  [<Measure>] 
+  /// mole, SI unit of amount of substance
+  type mol             
+
+  [<Measure>] 
+  /// candela, SI unit of luminous intensity
+  type cd              
+
+  [<Measure>] 
+  /// hertz, SI unit of frequency
+  type Hz = s^-1
+
+  [<Measure>] 
+  /// newton, SI unit of force
+  type N = kg m / s^2 
+
+  [<Measure>] 
+  /// pascal, SI unit of pressure, stress
+  type Pa = N / m^2
+
+  [<Measure>] 
+  /// joule, SI unit of energy, work, amount of heat
+  type J = N m
+
+  [<Measure>] 
+  /// watt, SI unit of power, radiant flux
+  type W = J / s       
+
+  [<Measure>] 
+  /// coulomb, SI unit of electric charge, amount of electricity
+  type C = s A 
+
+  [<Measure>] 
+  /// volt, SI unit of electric potential difference, electromotive force
+  type V = W/A        
+
+  [<Measure>] 
+  /// farad, SI unit of capacitance
+  type F = C/V
+
+  [<Measure>] 
+  /// ohm, SI unit of electric resistance
+  type ohm = V/A       
+
+  [<Measure>] 
+  /// siemens, SI unit of electric conductance
+  type S = A/V         
+
+  [<Measure>] 
+  /// weber, SI unit of magnetic flux
+  type Wb = V s        
+
+  [<Measure>] 
+  /// tesla, SI unit of magnetic flux density
+  type T = Wb/m^2      
+
+  [<Measure>] 
+  /// henry, SI unit of inductance
+  type H = Wb/A        
+
+  [<Measure>] 
+  /// lumen, SI unit of luminous flux
+  type lm = cd        
+
+  [<Measure>] 
+  /// lux, SI unit of illuminance
+  type lx = lm/m^2 
+
+  [<Measure>] 
+  /// becquerel, SI unit of activity referred to a radionuclide
+  type Bq = s^-1       
+
+  [<Measure>] 
+  /// gray, SI unit of absorbed dose
+  type Gy = J/kg       
+
+  [<Measure>] 
+  /// sievert, SI unit of does equivalent
+  type Sv = J/kg       
+
+  [<Measure>] 
+  /// katal, SI unit of catalytic activity
+  type kat = mol/s 
diff --git a/src/FSharp.PowerPack/StructuredFormat.fs b/src/FSharp.PowerPack/StructuredFormat.fs
new file mode 100755
index 0000000..295e1e0
--- /dev/null
+++ b/src/FSharp.PowerPack/StructuredFormat.fs
@@ -0,0 +1,1020 @@
+//=========================================================================
+// (c) Microsoft Corporation 2005-2009. 
+//=========================================================================
+
+#nowarn "52" // The value has been copied to ensure the original is not mutated by this operation
+
+namespace Microsoft.FSharp.Text.StructuredFormat
+
+    // Breakable block layout implementation.
+    // This is a fresh implementation of pre-existing ideas.
+
+    open System
+    open System.Diagnostics
+    open System.Text
+    open System.IO
+    open System.Reflection
+    open System.Globalization
+    open System.Collections.Generic
+    open Microsoft.FSharp.Reflection
+
+    /// A joint, between 2 layouts, is either:
+    ///  - unbreakable, or
+    ///  - breakable, and if broken the second block has a given indentation.
+    [<StructuralEquality; NoComparison>]
+    type Joint =
+     | Unbreakable
+     | Breakable of int
+     | Broken of int
+
+    /// Leaf juxt,data,juxt
+    /// Node juxt,left,juxt,right,juxt and joint
+    ///
+    /// If either juxt flag is true, then no space between words.
+    [<NoEquality; NoComparison>]
+    type Layout =
+     | Leaf of bool * obj * bool
+     | Node of bool * layout * bool * layout * bool * joint
+     | Attr of string * (string * string) list * layout
+
+    and layout = Layout
+
+    and joint = Joint
+
+    [<NoEquality; NoComparison>]
+    type IEnvironment = 
+        abstract GetLayout : obj -> layout
+        abstract MaxColumns : int
+        abstract MaxRows : int
+     
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module LayoutOps = 
+        let rec juxtLeft = function
+          | Leaf (jl,_,_)         -> jl
+          | Node (jl,_,_,_,_,_) -> jl
+          | Attr (_,_,l)        -> juxtLeft l
+
+        let rec juxtRight = function
+          | Leaf (_,_,jr)         -> jr
+          | Node (_,_,_,_,jr,_) -> jr
+          | Attr (_,_,l)        -> juxtRight l
+
+        let mkNode l r joint =
+           let jl = juxtLeft  l 
+           let jm = juxtRight l || juxtLeft r 
+           let jr = juxtRight r 
+           Node(jl,l,jm,r,jr,joint)
+
+
+        // constructors
+
+
+        let objL   (obj:obj) = Leaf (false,obj,false)
+        let sLeaf  (l,(str:string),r) = Leaf (l,(str:>obj),r)
+        let wordL  str = sLeaf (false,str,false)
+        let sepL   str = sLeaf (true ,str,true)   
+        let rightL str = sLeaf (true ,str,false)   
+        let leftL  str = sLeaf (false,str,true)
+        let emptyL = sLeaf (true,"",true)
+        let isEmptyL = function 
+         | Leaf(true,s,true) -> 
+            match s with 
+            | :? string as s -> s = "" 
+            | _ -> false
+         | _ -> false
+         
+
+        let aboveL  l r = mkNode l r (Broken 0)
+
+        let joinN i l r = mkNode l r (Breakable i)                                      
+        let join  = joinN 0
+        let join1 = joinN 1
+        let join2 = joinN 2
+        let join3 = joinN 3
+
+        let tagAttrL tag attrs l = Attr(tag,attrs,l)
+
+        let apply2 f l r = if isEmptyL l then r else
+                           if isEmptyL r then l else f l r
+
+        let (^^)  l r  = mkNode l r (Unbreakable)
+        let (++)  l r  = mkNode l r (Breakable 0)
+        let (--)  l r  = mkNode l r (Breakable 1)
+        let (---) l r  = mkNode l r (Breakable 2)
+        let (@@)   l r = apply2 (fun l r -> mkNode l r (Broken 0)) l r
+        let (@@-)  l r = apply2 (fun l r -> mkNode l r (Broken 1)) l r
+        let (@@--) l r = apply2 (fun l r -> mkNode l r (Broken 2)) l r
+        let tagListL tagger = function
+            | []    -> emptyL
+            | [x]   -> x
+            | x::xs ->
+                let rec process' prefixL = function
+                    []    -> prefixL
+                  | y::ys -> process' ((tagger prefixL) ++ y) ys
+                in  process' x xs
+            
+        let commaListL x = tagListL (fun prefixL -> prefixL ^^ rightL ",") x
+        let semiListL x  = tagListL (fun prefixL -> prefixL ^^ rightL ";") x
+        let spaceListL x = tagListL (fun prefixL -> prefixL) x
+        let sepListL x y = tagListL (fun prefixL -> prefixL ^^ x) y
+        let bracketL l = leftL "(" ^^ l ^^ rightL ")"
+        let tupleL xs = bracketL (sepListL (sepL ",") xs)
+        let aboveListL = function
+          | []    -> emptyL
+          | [x]   -> x
+          | x::ys -> List.fold (fun pre y -> pre @@ y) x ys
+
+        let optionL xL = function
+            None   -> wordL "None"
+          | Some x -> wordL "Some" -- (xL x)
+
+        let listL xL xs = leftL "[" ^^ sepListL (sepL ";") (List.map xL xs) ^^ rightL "]"
+
+        let squareBracketL x = leftL "[" ^^ x ^^ rightL "]"    
+
+        let braceL         x = leftL "{" ^^ x ^^ rightL "}"
+
+        let boundedUnfoldL
+                    (itemL     : 'a -> layout)
+                    (project   : 'z -> ('a * 'z) option)
+                    (stopShort : 'z -> bool)
+                    (z : 'z)
+                    maxLength =
+          let rec consume n z =
+            if stopShort z then [wordL "..."] else
+            match project z with
+              | None       -> []  (* exhaused input *)
+              | Some (x,z) -> if n<=0 then [wordL "..."]               (* hit print_length limit *)
+                                      else itemL x :: consume (n-1) z  (* cons recursive... *)
+          consume maxLength z  
+
+        let unfoldL itemL project z maxLength = boundedUnfoldL  itemL project (fun _ -> false) z maxLength
+          
+    /// These are a typical set of options used to control structured formatting.
+    [<NoEquality; NoComparison>]
+    type FormatOptions = 
+        { FloatingPointFormat: string;
+          AttributeProcessor: (string -> (string * string) list -> bool -> unit);
+          FormatProvider: System.IFormatProvider;
+          BindingFlags: System.Reflection.BindingFlags
+          PrintWidth : int; 
+          PrintDepth : int; 
+          PrintLength : int;
+          PrintSize : int;        
+          ShowProperties : bool;
+          ShowIEnumerable: bool; }
+        static member Default =
+            { FormatProvider = (System.Globalization.CultureInfo.InvariantCulture :> System.IFormatProvider);
+              AttributeProcessor= (fun _ _ _ -> ());
+              BindingFlags = System.Reflection.BindingFlags.Public;
+              FloatingPointFormat = "g10";
+              PrintWidth = 80 ; 
+              PrintDepth = 100 ; 
+              PrintLength = 100;
+              PrintSize = 10000;
+              ShowProperties = false;
+              ShowIEnumerable = true; }
+
+
+
+    module ReflectUtils = 
+        open System
+        open System.Reflection
+
+        [<NoEquality; NoComparison>]
+        type TypeInfo =
+          | TupleType of Type list
+          | FunctionType of Type * Type
+          | RecordType of (string * Type) list
+          | SumType of (string * (string * Type) list) list
+          | UnitType
+          | ObjectType of Type
+
+             
+        let isNamedType(typ:Type) = not (typ.IsArray || typ.IsByRef || typ.IsPointer)
+        let equivHeadTypes (ty1:Type) (ty2:Type) = 
+            isNamedType(ty1) &&
+            if ty1.IsGenericType then 
+              ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition())
+            else 
+              ty1.Equals(ty2)
+
+        let option = typedefof<obj option>
+        let func = typedefof<(obj -> obj)>
+
+        let isOptionType typ = equivHeadTypes typ (typeof<int option>)
+        let isUnitType typ = equivHeadTypes typ (typeof<unit>)
+        let isListType typ = 
+            FSharpType.IsUnion typ && 
+            (let cases = FSharpType.GetUnionCases typ 
+             cases.Length > 0 && equivHeadTypes (typedefof<list<_>>) cases.[0].DeclaringType)
+
+        module Type =
+
+            let recdDescOfProps props = 
+               props |> Array.toList |> List.map (fun (p:PropertyInfo) -> p.Name, p.PropertyType) 
+
+            let getTypeInfoOfType (bindingFlags:BindingFlags) (typ:Type) = 
+                if FSharpType.IsTuple(typ)  then TypeInfo.TupleType (FSharpType.GetTupleElements(typ) |> Array.toList)
+                elif FSharpType.IsFunction(typ) then let ty1,ty2 = FSharpType.GetFunctionElements typ in  TypeInfo.FunctionType( ty1,ty2)
+                elif FSharpType.IsUnion(typ,bindingFlags) then 
+                    let cases = FSharpType.GetUnionCases(typ,bindingFlags) 
+                    match cases with 
+                    | [| |] -> TypeInfo.ObjectType(typ) 
+                    | _ -> 
+                        TypeInfo.SumType(cases |> Array.toList |> List.map (fun case -> 
+                            let flds = case.GetFields()
+                            case.Name,recdDescOfProps(flds)))
+                elif FSharpType.IsRecord(typ,bindingFlags) then 
+                    let flds = FSharpType.GetRecordFields(typ,bindingFlags) 
+                    TypeInfo.RecordType(recdDescOfProps(flds))
+                else
+                    TypeInfo.ObjectType(typ)
+
+            let IsOptionType (typ:Type) = isOptionType typ
+            let IsListType (typ:Type) = isListType typ
+            let IsUnitType (typ:Type) = isUnitType typ
+
+        [<NoEquality; NoComparison>]
+        type ValueInfo =
+          | TupleValue of obj list
+          | FunctionClosureValue of System.Type 
+          | RecordValue of (string * obj) list
+          | ConstructorValue of string * (string * obj) list
+          | ExceptionValue of System.Type * (string * obj) list
+          | UnitValue
+          | ObjectValue of obj
+
+        module Value = 
+       
+            // Analyze an object to see if it the representation
+            // of an F# value.
+            let GetValueInfoOfObject (bindingFlags:BindingFlags) (obj : obj) = 
+              match obj with 
+              | null -> ObjectValue(obj)
+              | _ -> 
+                let reprty = obj.GetType() 
+
+                // First a bunch of special rules for tuples
+                // Because of the way F# currently compiles tuple values 
+                // of size > 7 we can only reliably reflect on sizes up
+                // to 7.
+
+                if FSharpType.IsTuple reprty then 
+                    TupleValue (FSharpValue.GetTupleFields obj |> Array.toList)
+                elif FSharpType.IsFunction reprty then 
+                    FunctionClosureValue reprty
+                    
+                // It must be exception, abstract, record or union.
+                // Either way we assume the only properties defined on
+                // the type are the actual fields of the type.  Again,
+                // we should be reading attributes here that indicate the
+                // true structure of the type, e.g. the order of the fields.   
+                elif FSharpType.IsUnion(reprty,bindingFlags) then 
+                    let tag,vals = FSharpValue.GetUnionFields (obj,reprty,bindingFlags) 
+                    let props = tag.GetFields()
+                    let pvals = (props,vals) ||> Array.map2 (fun prop v -> prop.Name,v)
+                    ConstructorValue(tag.Name, Array.toList pvals)
+
+                elif FSharpType.IsExceptionRepresentation(reprty,bindingFlags) then 
+                    let props = FSharpType.GetExceptionFields(reprty,bindingFlags) 
+                    let vals = FSharpValue.GetExceptionFields(obj,bindingFlags) 
+                    let pvals = (props,vals) ||> Array.map2 (fun prop v -> prop.Name,v)
+                    ExceptionValue(reprty, pvals |> Array.toList)
+
+                elif FSharpType.IsRecord(reprty,bindingFlags) then 
+                    let props = FSharpType.GetRecordFields(reprty,bindingFlags) 
+                    RecordValue(props |> Array.map (fun prop -> prop.Name, prop.GetValue(obj,null)) |> Array.toList)
+                else
+                    ObjectValue(obj)
+
+            // This one is like the above but can make use of additional
+            // statically-known type information to aid in the
+            // analysis of null values. 
+
+            let GetValueInfo bindingFlags (x : 'a)  (* x could be null *) = 
+                let obj = (box x)
+                match obj with 
+                | null -> 
+                   let typ = typeof<'a>
+                   if isOptionType typ then  ConstructorValue("None", [])
+                   elif isUnitType typ then  UnitValue
+                   else ObjectValue(obj)
+                | _ -> 
+                  GetValueInfoOfObject bindingFlags (obj) 
+
+
+            let GetInfo bindingFlags (v:'a) = GetValueInfo bindingFlags (v:'a)
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Display = 
+
+        open ReflectUtils
+        open LayoutOps
+        let string_of_int (i:int) = i.ToString()
+
+        let typeUsesSystemObjectToString (typ:System.Type) =
+            try let methInfo = typ.GetMethod("ToString",BindingFlags.Public ||| BindingFlags.Instance,null,[| |],null)
+                methInfo.DeclaringType = typeof<System.Object>
+            with e -> false
+
+        /// If "str" ends with "ending" then remove it from "str", otherwise no change.
+        let trimEnding (ending:string) (str:string) =
+#if FX_NO_CULTURE_INFO_ARGS
+          if str.EndsWith(ending) then 
+#else
+          if str.EndsWith(ending,StringComparison.Ordinal) then 
+#endif
+              str.Substring(0,str.Length - ending.Length) 
+          else str
+
+        let catchExn f = try Choice1Of2 (f ()) with e -> Choice2Of2 e
+        
+        // An implementation of break stack.
+        // Uses mutable state, relying on linear threading of the state.
+
+        [<NoEquality; NoComparison>]
+        type Breaks = 
+            Breaks of
+                int *     // pos of next free slot 
+                int *     // pos of next possible "outer" break - OR - outer=next if none possible 
+                int array // stack of savings, -ve means it has been broken   
+
+        // next  is next slot to push into - aka size of current occupied stack.  
+        // outer counts up from 0, and is next slot to break if break forced.
+        // - if all breaks forced, then outer=next.
+        // - popping under these conditions needs to reduce outer and next.
+        
+
+        //let dumpBreaks prefix (Breaks(next,outer,stack)) = ()
+        //   printf "%s: next=%d outer=%d stack.Length=%d\n" prefix next outer stack.Length;
+        //   stdout.Flush() 
+             
+        let chunkN = 400      
+        let breaks0 () = Breaks(0,0,Array.create chunkN 0)
+
+        let pushBreak saving (Breaks(next,outer,stack)) =
+            //dumpBreaks "pushBreak" (next,outer,stack);
+            let stack = 
+                if next = stack.Length then
+                  Array.init (next + chunkN) (fun i -> if i < next then stack.[i] else 0) // expand if full 
+                else
+                  stack
+           
+            stack.[next] <- saving;
+            Breaks(next+1,outer,stack)
+
+        let popBreak (Breaks(next,outer,stack)) =
+            //dumpBreaks "popBreak" (next,outer,stack);
+            if next=0 then raise (Failure "popBreak: underflow");
+            let topBroke = stack.[next-1] < 0
+            let outer = if outer=next then outer-1 else outer  // if all broken, unwind 
+            let next  = next - 1
+            Breaks(next,outer,stack),topBroke
+
+        let forceBreak (Breaks(next,outer,stack)) =
+            //dumpBreaks "forceBreak" (next,outer,stack);
+            if outer=next then
+              // all broken 
+                None
+            else
+                let saving = stack.[outer]
+                stack.[outer] <- -stack.[outer];    
+                let outer = outer+1
+                Some (Breaks(next,outer,stack),saving)
+
+        // -------------------------------------------------------------------------
+        // fitting
+        // ------------------------------------------------------------------------
+          
+        let squashTo (maxWidth,leafFormatter) layout =
+            if maxWidth <= 0 then layout else 
+            let rec fit breaks (pos,layout) =
+                // breaks = break context, can force to get indentation savings.
+                // pos    = current position in line
+                // layout = to fit
+                //------
+                // returns:
+                // breaks
+                // layout - with breaks put in to fit it.
+                // pos    - current pos in line = rightmost position of last line of block.
+                // offset - width of last line of block
+                // NOTE: offset <= pos -- depending on tabbing of last block
+               
+                let breaks,layout,pos,offset =
+                    match layout with
+                    | Attr (tag,attrs,l) ->
+                        let breaks,layout,pos,offset = fit breaks (pos,l) 
+                        let layout = Attr (tag,attrs,layout) 
+                        breaks,layout,pos,offset
+                    | Leaf (jl,obj,jr) ->
+                        let text:string = leafFormatter obj 
+                        // save the formatted text from the squash
+                        let layout = Leaf(jl,(text :> obj),jr) 
+                        let textWidth = text.Length
+                        let rec fitLeaf breaks pos =
+                          if pos + textWidth <= maxWidth then
+                              breaks,layout,pos + textWidth,textWidth // great, it fits 
+                          else
+                              match forceBreak breaks with
+                              | None                 -> 
+                                  breaks,layout,pos + textWidth,textWidth // tough, no more breaks 
+                              | Some (breaks,saving) -> 
+                                  let pos = pos - saving 
+                                  fitLeaf breaks pos
+                       
+                        fitLeaf breaks pos
+                    | Node (jl,l,jm,r,jr,joint) ->
+                        let mid = if jm then 0 else 1
+                        match joint with
+                        | Unbreakable    ->
+                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
+                            let pos = pos + mid                              // fit space if juxt says so 
+                            let breaks,r,pos,offsetr = fit breaks (pos,r)    // fit right 
+                            breaks,Node (jl,l,jm,r,jr,Unbreakable),pos,offsetl + mid + offsetr
+                        | Broken indent ->
+                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
+                            let pos = pos - offsetl + indent                 // broken so - offset left + ident 
+                            let breaks,r,pos,offsetr = fit breaks (pos,r)    // fit right 
+                            breaks,Node (jl,l,jm,r,jr,Broken indent),pos,indent + offsetr
+                        | Breakable indent ->
+                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
+                            // have a break possibility, with saving 
+                            let saving = offsetl + mid - indent
+                            let pos = pos + mid
+                            if saving>0 then
+                                let breaks = pushBreak saving breaks
+                                let breaks,r,pos,offsetr = fit breaks (pos,r)
+                                let breaks,broken = popBreak breaks
+                                if broken then
+                                    breaks,Node (jl,l,jm,r,jr,Broken indent)   ,pos,indent + offsetr
+                                else
+                                    breaks,Node (jl,l,jm,r,jr,Breakable indent),pos,offsetl + mid + offsetr
+                            else
+                                // actually no saving so no break 
+                                let breaks,r,pos,offsetr = fit breaks (pos,r)
+                                breaks,Node (jl,l,jm,r,jr,Breakable indent)  ,pos,offsetl + mid + offsetr
+               
+               //Printf.printf "\nDone:     pos=%d offset=%d" pos offset;
+                breaks,layout,pos,offset
+           
+            let breaks = breaks0 ()
+            let pos = 0
+            let _,layout,_,_ = fit breaks (pos,layout)
+            layout
+
+        // -------------------------------------------------------------------------
+        // showL
+        // ------------------------------------------------------------------------
+
+        let combine strs = System.String.Concat(Array.ofList(strs) : string[])
+        let showL opts leafFormatter layout =
+            let push x rstrs = x::rstrs
+            let z0 = [],0
+            let addText (rstrs,i) (text:string) = push text rstrs,i + text.Length
+            let index   (_,i)               = i
+            let extract rstrs = combine(List.rev rstrs) 
+            let newLine (rstrs,_) n     = // \n then spaces... 
+                let indent = new System.String(' ', n)
+                let rstrs = push System.Environment.NewLine rstrs
+                let rstrs = push indent rstrs
+                rstrs,n
+
+            // addL: pos is tab level 
+            let rec addL z pos layout = 
+                match layout with 
+                | Leaf (_,obj,_)                 -> 
+                    let text = leafFormatter obj 
+                    addText z text
+                | Node (_,l,_,r,_,Broken indent) 
+                     // Print width = 0 implies 1D layout, no squash
+                     when not (opts.PrintWidth = 0)  -> 
+                    let z = addL z pos l
+                    let z = newLine z (pos+indent)
+                    let z = addL z (pos+indent) r
+                    z
+                | Node (_,l,jm,r,_,_)             -> 
+                    let z = addL z pos l
+                    let z = if jm then z else addText z " "
+                    let pos = index z
+                    let z = addL z pos r
+                    z
+                | Attr (_,_,l) ->
+                    addL z pos l
+           
+            let rstrs,_ = addL z0 0 layout
+            extract rstrs
+
+
+        // -------------------------------------------------------------------------
+        // outL
+        // ------------------------------------------------------------------------
+
+        let outL outAttribute leafFormatter (chan : TextWriter) layout =
+            // write layout to output chan directly 
+            let write (s:string) = chan.Write(s)
+            // z is just current indent 
+            let z0 = 0
+            let index i = i
+            let addText z text  = write text;  (z + text.Length)
+            let newLine _ n     = // \n then spaces... 
+                let indent = new System.String(' ',n)
+                chan.WriteLine();
+                write indent;
+                n
+                
+            // addL: pos is tab level 
+            let rec addL z pos layout = 
+                match layout with 
+                | Leaf (_,obj,_)                 -> 
+                    let text = leafFormatter obj 
+                    addText z text
+                | Node (_,l,_,r,_,Broken indent) -> 
+                    let z = addL z pos l
+                    let z = newLine z (pos+indent)
+                    let z = addL z (pos+indent) r
+                    z
+                | Node (_,l,jm,r,_,_)             -> 
+                    let z = addL z pos l
+                    let z = if jm then z else addText z " "
+                    let pos = index z
+                    let z = addL z pos r
+                    z 
+                | Attr (tag,attrs,l) ->
+                let _ = outAttribute tag attrs true
+                let z = addL z pos l
+                let _ = outAttribute tag attrs false
+                z
+           
+            let _ = addL z0 0 layout
+            ()
+
+        // --------------------------------------------------------------------
+        // pprinter: using general-purpose reflection...
+        // -------------------------------------------------------------------- 
+          
+        let getValueInfo bindingFlags (x:'a) = Value.GetInfo bindingFlags (x:'a)
+
+        let unpackCons recd =
+            match recd with 
+            | [(_,h);(_,t)] -> (h,t)
+            | _             -> failwith "unpackCons"
+
+        let getListValueInfo bindingFlags (x:obj) =
+            match x with 
+            | null -> None 
+            | _ -> 
+                match getValueInfo bindingFlags x with
+                | ConstructorValue ("Cons",recd) -> Some (unpackCons recd)
+                | ConstructorValue ("Empty",[]) -> None
+                | _ -> failwith "List value had unexpected ValueInfo"
+
+        let compactCommaListL xs = sepListL (sepL ",") xs // compact, no spaces around "," 
+        let nullL = wordL "null"
+        let measureL = wordL "()"
+          
+        // --------------------------------------------------------------------
+        // pprinter: attributes
+        // -------------------------------------------------------------------- 
+
+        let makeRecordVerticalL nameXs =
+            let itemL (name,xL) = let labelL = wordL name in ((labelL ^^ wordL "=")) -- (xL  ^^ (rightL ";"))
+            let braceL xs = (leftL "{") ^^ xs ^^ (rightL "}")
+            braceL (aboveListL (List.map itemL nameXs))
+
+        let makeRecordHorizontalL nameXs = (* This is a more compact rendering of records - and is more like tuples *)
+            let itemL (name,xL) = let labelL = wordL name in ((labelL ^^ wordL "=")) -- xL
+            let braceL xs = (leftL "{") ^^ xs ^^ (rightL "}")
+            braceL (sepListL (rightL ";")  (List.map itemL nameXs))
+
+        let makeRecordL nameXs = makeRecordVerticalL nameXs (* REVIEW: switch to makeRecordHorizontalL ? *)
+
+        let makePropertiesL nameXs =
+            let itemL (name,v) = 
+               let labelL = wordL name 
+               (labelL ^^ wordL "=")
+               ^^ (match v with 
+                   | None -> wordL "?" 
+                   | Some xL -> xL)
+               ^^ (rightL ";")
+            let braceL xs = (leftL "{") ^^ xs ^^ (rightL "}")
+            braceL (aboveListL (List.map itemL nameXs))
+
+        let makeListL itemLs =
+            (leftL "[") 
+            ^^ sepListL (rightL ";") itemLs 
+            ^^ (rightL "]")
+
+        let makeArrayL xs =
+            (leftL "[|") 
+            ^^ sepListL (rightL ";") xs 
+            ^^ (rightL "|]")
+
+        let makeArray2L xs = leftL "[" ^^ aboveListL xs ^^ rightL "]"  
+
+        // --------------------------------------------------------------------
+        // pprinter: anyL - support functions
+        // -------------------------------------------------------------------- 
+
+        let getProperty (obj: obj) name =
+            let ty = obj.GetType()
+#if FX_NO_CULTURE_INFO_ARGS
+            ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |])
+#else
+            ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |],CultureInfo.InvariantCulture)
+#endif
+
+        let formatChar isChar c = 
+            match c with 
+            | '\'' when isChar -> "\\\'"
+            | '\"' when not isChar -> "\\\""
+            //| '\n' -> "\\n"
+            //| '\r' -> "\\r"
+            //| '\t' -> "\\t"
+            | '\\' -> "\\\\"
+            | '\b' -> "\\b"
+            | _ when System.Char.IsControl(c) -> 
+                 let d1 = (int c / 100) % 10 
+                 let d2 = (int c / 10) % 10 
+                 let d3 = int c % 10 
+                 "\\" + d1.ToString() + d2.ToString() + d3.ToString()
+            | _ -> c.ToString()
+            
+        let formatString (s:string) =
+            let rec check i = i < s.Length && not (System.Char.IsControl(s,i)) && s.[i] <> '\"' && check (i+1) 
+            let rec conv i acc = if i = s.Length then combine (List.rev acc) else conv (i+1) (formatChar false s.[i] :: acc)  
+            "\"" + s + "\""
+            // REVIEW: should we check for the common case of no control characters? Reinstate the following?
+            //"\"" + (if check 0 then s else conv 0 []) + "\""
+
+        let formatStringInWidth (width:int) (str:string) =
+            // Return a truncated version of the string, e.g.
+            //   "This is the initial text, which has been truncat"+[12 chars]
+            //
+            // Note: The layout code forces breaks based on leaf size and possible break points.
+            //       It does not force leaf size based on width.
+            //       So long leaf-string width can not depend on their printing context...
+            //
+            // The suffix like "+[dd chars]" is 11 chars.
+            //                  12345678901
+            let suffixLength    = 11 // turning point suffix length
+            let prefixMinLength = 12 // arbitrary. If print width is reduced, want to print a minimum of information on strings...
+            let prefixLength = max (width - 2 (*quotes*) - suffixLength) prefixMinLength
+            "\"" + (str.Substring(0,prefixLength)) + "\"" + "+[" + (str.Length - prefixLength).ToString() + " chars]"
+
+        // --------------------------------------------------------------------
+        // pprinter: anyL
+        // -------------------------------------------------------------------- 
+                           
+        type Precedence = 
+            | BracketIfTupleOrNotAtomic = 2
+            | BracketIfTuple = 3
+            | NeverBracket = 4
+
+        // In fsi.exe, certain objects are not printed for top-level bindings.
+        [<StructuralEquality; NoComparison>]
+        type ShowMode = 
+            | ShowAll 
+            | ShowTopLevelBinding
+
+        // polymorphic and inner recursion limitations prevent us defining polyL in the recursive loop 
+        let polyL bindingFlags (objL: ShowMode -> int -> Precedence -> ValueInfo -> obj -> Layout) showMode i prec  (x:'a) (* x could be null *) =
+            objL showMode i prec (getValueInfo bindingFlags (x:'a))  (box x) 
+
+        let anyL showMode bindingFlags (opts:FormatOptions) (x:'a) =
+            // showMode = ShowTopLevelBinding on the outermost expression when called from fsi.exe,
+            // This allows certain outputs, e.g. objects that would print as <seq> to be suppressed, etc. See 4343.
+            // Calls to layout proper sub-objects should pass showMode = ShowAll.
+
+            // Precedences to ensure we add brackets in the right places
+            
+            // Keep a record of objects encountered along the way
+            let path = Dictionary<obj,int>(10,HashIdentity.Reference)
+
+            // Roughly count the "nodes" printed, e.g. leaf items and inner nodes, but not every bracket and comma.
+            let size = ref opts.PrintSize
+            let exceededPrintSize() = !size<=0
+            let countNodes n = if !size > 0 then size := !size - n else () (* no need to keep decrementing (and avoid wrap around) *)
+            let stopShort _ = exceededPrintSize() // for unfoldL
+
+            // Recursive descent
+            let rec objL depthLim prec (x:obj) = polyL bindingFlags objWithReprL ShowAll  depthLim prec x (* showMode for inner expr *)
+            and sameObjL depthLim prec (x:obj) = polyL bindingFlags objWithReprL showMode depthLim prec x (* showMode preserved *)
+
+            and objWithReprL showMode depthLim prec (info:ValueInfo) (x:obj) (* x could be null *) =
+                try
+                  if depthLim<=0 || exceededPrintSize() then wordL "..." else
+                  match x with 
+                  | null -> 
+                    reprL showMode (depthLim-1) prec info x
+                  | _    ->
+                    if (path.ContainsKey(x)) then 
+                       wordL "..."
+                    else 
+                        path.Add(x,0);
+                        let res = 
+                          // Lazy<T> values. VS2008 used StructuredFormatDisplayAttribute to show via ToString. Dev10 (no attr) needs a special case.
+                          let ty = x.GetType()
+                          if ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<Lazy<_>> then
+                            Some (wordL (x.ToString()))
+                          else
+                            // Try the StructuredFormatDisplayAttribute extensibility attribute
+                            match x.GetType().GetCustomAttributes (typeof<StructuredFormatDisplayAttribute>, true) with
+                            | null | [| |] -> None
+                            | res -> 
+                               let attr = (res.[0] :?> StructuredFormatDisplayAttribute) 
+                               let txt = attr.Value
+                               if txt = null || txt.Length <= 1 then  
+                                   None
+                               else
+                                  let p1 = txt.IndexOf ("{", StringComparison.Ordinal)
+                                  let p2 = txt.LastIndexOf ("}", StringComparison.Ordinal)
+                                  if p1 < 0 || p2 < 0 || p1+1 >= p2 then 
+                                      None 
+                                  else
+                                      let preText = if p1 <= 0 then "" else txt.[0..p1-1]
+                                      let postText = if p2+1 >= txt.Length then "" else txt.[p2+1..]
+                                      let prop = txt.[p1+1..p2-1]
+                                      match catchExn (fun () -> getProperty x prop) with
+                                        | Choice2Of2 e -> Some (wordL ("<StructuredFormatDisplay exception: " + e.Message + ">"))
+                                        | Choice1Of2 alternativeObj ->
+                                            try 
+                                                let alternativeObjL = 
+                                                  match alternativeObj with 
+                                                      // A particular rule is that if the alternative property
+                                                      // returns a string, we turn off auto-quoting and esaping of
+                                                      // the string, i.e. just treat the string as display text.
+                                                      // This allows simple implementations of 
+                                                      // such as
+                                                      //
+                                                      //    [<StructuredFormatDisplay("{StructuredDisplayString}I")>]
+                                                      //    type BigInt(signInt:int, v : BigNat) =
+                                                      //        member x.StructuredDisplayString = x.ToString()
+                                                      //
+                                                      | :? string as s -> sepL s
+                                                      | _ -> sameObjL (depthLim-1) Precedence.BracketIfTuple alternativeObj
+                                                countNodes 0 (* 0 means we do not count the preText and postText *)
+                                                Some (leftL preText ^^ alternativeObjL ^^ rightL postText)
+                                            with _ -> 
+                                              None
+
+                        let res = 
+                            match res with 
+                            | Some res -> res
+                            | None     -> reprL showMode (depthLim-1) prec info x
+                        path .Remove(x) |> ignore;
+                        res
+                with
+                  e ->
+                    countNodes 1
+                    wordL ("Error: " + e.Message)
+
+            and recdAtomicTupleL depthLim recd =
+                // tuples up args to UnionConstruction or ExceptionConstructor. no node count.
+                match recd with 
+                | [(_,x)] -> objL depthLim Precedence.BracketIfTupleOrNotAtomic x 
+                | txs     -> leftL "(" ^^ compactCommaListL (List.map (snd >> objL depthLim Precedence.BracketIfTuple) txs) ^^ rightL ")" 
+
+            and bracketIfL b basicL =
+                if b then (leftL "(") ^^ basicL ^^ (rightL ")") else basicL
+
+            and reprL showMode depthLim prec repr x (* x could be null *) =
+                let showModeFilter lay = match showMode with ShowAll -> lay | ShowTopLevelBinding -> emptyL                                                             
+                match repr with 
+                | TupleValue vals -> 
+                    let basicL = sepListL (rightL ",") (List.map (objL depthLim Precedence.BracketIfTuple ) vals)
+                    bracketIfL (prec <= Precedence.BracketIfTuple) basicL 
+
+                | RecordValue items -> 
+                    let itemL (name,x) =
+                      countNodes 1 // record labels are counted as nodes. [REVIEW: discussion under 4090].
+                      (name,objL depthLim Precedence.BracketIfTuple x)
+                    makeRecordL (List.map itemL items)
+
+                | ConstructorValue (constr,recd) when (* x is List<T>. Note: "null" is never a valid list value. *)
+                                                      x<>null && Type.IsListType (x.GetType()) ->
+                    match constr with 
+                    | "Cons" -> 
+                        let (x,xs) = unpackCons recd
+                        let project xs = getListValueInfo bindingFlags xs
+                        let itemLs = objL depthLim Precedence.BracketIfTuple x :: boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) project stopShort xs (opts.PrintLength - 1)
+                        makeListL itemLs
+                    | _ ->
+                        countNodes 1
+                        wordL "[]" 
+
+                | ConstructorValue(nm,[])   ->
+                    countNodes 1
+                    (wordL nm)
+
+                | ConstructorValue(nm,recd) ->
+                    countNodes 1 (* e.g. Some (Some (Some (Some 2))) should count for 5 *)
+                    (wordL nm --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+
+                | ExceptionValue(ty,recd) ->
+                    countNodes 1
+                    let name = ty.Name 
+                    match recd with
+                      | []   -> (wordL name)
+                      | recd -> (wordL name --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+
+                | FunctionClosureValue ty ->
+                    // Q: should function printing include the ty.Name? It does not convey much useful info to most users, e.g. "clo at 0_123".    
+                    countNodes 1
+                    wordL ("<fun:"+ty.Name+">") |> showModeFilter
+
+                | ObjectValue(obj)  ->
+                    match obj with 
+                    | null -> (countNodes 1; nullL)
+                    | _ -> 
+                    let ty = obj.GetType()
+                    match obj with 
+                    | :? string as s ->
+                        countNodes 1
+                        wordL (formatString s)  
+                    | :? System.Array as arr -> 
+                        match arr.Rank with
+                        | 1 -> 
+                             let n = arr.Length
+                             let b1 = arr.GetLowerBound(0) 
+                             let project depthLim = if depthLim=(b1+n) then None else Some (box (arr.GetValue(depthLim)),depthLim+1)
+                             let itemLs = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) project stopShort b1 opts.PrintLength
+                             makeArrayL (if b1 = 0 then itemLs else wordL("bound1="+string_of_int b1)::itemLs)
+                        | 2 -> 
+                             let n1 = arr.GetLength(0)
+                             let n2 = arr.GetLength(1)
+                             let b1 = arr.GetLowerBound(0) 
+                             let b2 = arr.GetLowerBound(1) 
+                             let project2 x y =
+                               if x>=(b1+n1) || y>=(b2+n2) then None
+                               else Some (box (arr.GetValue(x,y)),y+1)
+                             let rowL x = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) (project2 x) stopShort b2 opts.PrintLength |> makeListL
+                             let project1 x = if x>=(b1+n1) then None else Some (x,x+1)
+                             let rowsL  = boundedUnfoldL rowL project1 stopShort b1 opts.PrintLength
+                             makeArray2L (if b1=0 && b2 = 0 then rowsL else wordL("bound1=" + string_of_int b1)::wordL("bound2=" + string_of_int b2)::rowsL)
+                          | n -> 
+                             makeArrayL [wordL("rank=" + string_of_int n)]
+                        
+                    // Format 'set' and 'map' nicely
+                    | _ when  
+                          (let ty = obj.GetType()
+                           ty.IsGenericType && (ty.GetGenericTypeDefinition() = typedefof<Map<int,int>> 
+                                                || ty.GetGenericTypeDefinition() = typedefof<Set<int>>) ) ->
+                         let ty = obj.GetType()
+                         let word = if ty.GetGenericTypeDefinition() = typedefof<Map<int,int>> then "map" else "set"
+                         let possibleKeyValueL v = 
+                             if word = "map" &&
+                                (match v with null -> false | _ -> true) && 
+                                v.GetType().IsGenericType && 
+                                v.GetType().GetGenericTypeDefinition() = typedefof<KeyValuePair<int,int>> then
+                                  objL depthLim Precedence.BracketIfTuple (v.GetType().GetProperty("Key").GetValue(v, [| |]), 
+                                                                           v.GetType().GetProperty("Value").GetValue(v, [| |]))
+                             else
+                                  objL depthLim Precedence.BracketIfTuple v
+                         let it = (obj :?>  System.Collections.IEnumerable).GetEnumerator() 
+                         try 
+                           let itemLs = boundedUnfoldL possibleKeyValueL (fun () -> if it.MoveNext() then Some(it.Current,()) else None) stopShort () (1+opts.PrintLength/12)
+                           (wordL word --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+                         finally 
+                            match it with 
+                            | :? System.IDisposable as e -> e.Dispose()
+                            | _ -> ()
+
+                    | :? System.Collections.IEnumerable as ie ->
+                         if opts.ShowIEnumerable then
+                           let word = "seq"
+                           let it = ie.GetEnumerator() 
+                           try 
+                             let itemLs = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) (fun () -> if it.MoveNext() then Some(it.Current,()) else None) stopShort () (1+opts.PrintLength/30)
+                             (wordL word --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+                           finally 
+                              match it with 
+                              | :? System.IDisposable as e -> e.Dispose()
+                              | _ -> ()
+                             
+                         else
+                           // Sequence printing is turned off for declared-values, and maybe be disabled to users.
+                           // There is choice here, what to print? <seq> or ... or ?
+                           // Also, in the declared values case, if the sequence is actually a known non-lazy type (list, array etc etc) we could print it.  
+                           wordL "<seq>" |> showModeFilter
+                    | _ ->
+                         if showMode = ShowTopLevelBinding && typeUsesSystemObjectToString (obj.GetType()) then
+                           emptyL
+                         else
+                           countNodes 1
+                           let basicL = LayoutOps.objL obj  // This buries an obj in the layout, rendered at squash time via a leafFormatter.
+                                                            // If the leafFormatter was directly here, then layout leaves could store strings.
+                           match obj with 
+                           | _ when opts.ShowProperties ->
+                              let props = ty.GetProperties(BindingFlags.GetField ||| BindingFlags.Instance ||| BindingFlags.Public)
+                              // massively reign in deep printing of properties 
+                              let nDepth = depthLim/10
+                              System.Array.Sort((props:>System.Array),{ new System.Collections.IComparer with member this.Compare(p1,p2) = compare ((p1 :?> PropertyInfo).Name) ((p2 :?> PropertyInfo).Name) } );
+                              if props.Length = 0 || (nDepth <= 0) then basicL 
+                              else basicL --- 
+                                     (props 
+                                      |> Array.toList 
+                                      |> List.map (fun p -> (p.Name,(try Some (objL nDepth Precedence.BracketIfTuple (getProperty obj p.Name)) 
+                                                                     with _ -> None)))
+                                      |> makePropertiesL)
+                           | _ -> basicL 
+                | UnitValue -> countNodes 1; measureL
+
+            polyL bindingFlags objWithReprL showMode opts.PrintDepth Precedence.BracketIfTuple x
+
+        // --------------------------------------------------------------------
+        // pprinter: leafFormatter
+        // --------------------------------------------------------------------
+
+#if Suggestion4299
+        // See bug 4299. Suppress FSI_dddd+<etc> from fsi printer.
+        let fixupForInteractiveFSharpClassesWithNoToString obj (text:string) =
+              // Given obj:T.
+              // If T is a nested type inside a parent type called FSI_dddd, then it looks like an F# Interactive type.
+              // Further, if the .ToString() text starts with "FSI_dddd+T" then it looks like it's the default ToString.
+              // A better test: it is default ToString if the MethodInfo.DeclaringType is System.Object.
+              // In this case, replace "FSI_dddd+T" by "T".
+              // assert(obj <> null)
+              let fullName = obj.GetType().FullName // e.g. "FSI_0123+Name"
+              let name     = obj.GetType().Name     // e.g. "Name"
+              let T = obj.GetType()      
+              if text.StartsWith(fullName) then
+                  // text could be a default .ToString() since it starts with the FullName of the type. More checks...
+                  if T.IsNested &&
+                     T.DeclaringType.Name.StartsWith("FSI_") &&                             // Name has "FSI_" which is 
+                     T.DeclaringType.Name.Substring(4) |> Seq.forall System.Char.IsDigit    // followed by digits?
+                  then
+                      name ^ text.Substring(fullName.Length)    // replace fullName by name at start of text
+                  else
+                      text
+              else
+                text
+#endif
+
+        let leafFormatter (opts:FormatOptions) (obj :obj) =
+            match obj with 
+            | null -> "null"
+            | :? double as d -> 
+                let s = d.ToString(opts.FloatingPointFormat,opts.FormatProvider)
+                if System.Double.IsNaN(d) then "nan"
+                elif System.Double.IsNegativeInfinity(d) then "-infinity"
+                elif System.Double.IsPositiveInfinity(d) then "infinity"
+                elif opts.FloatingPointFormat.[0] = 'g'  && String.forall(fun c -> System.Char.IsDigit(c) || c = '-')  s
+                then s + ".0" 
+                else s
+            | :? single as d -> 
+                (if System.Single.IsNaN(d) then "nan"
+                 elif System.Single.IsNegativeInfinity(d) then "-infinity"
+                 elif System.Single.IsPositiveInfinity(d) then "infinity"
+                 elif opts.FloatingPointFormat.Length >= 1 && opts.FloatingPointFormat.[0] = 'g' 
+                  && float32(System.Int32.MinValue) < d && d < float32(System.Int32.MaxValue) 
+                  && float32(int32(d)) = d 
+                 then (System.Convert.ToInt32 d).ToString(opts.FormatProvider) + ".0"
+                 else d.ToString(opts.FloatingPointFormat,opts.FormatProvider)) 
+                + "f"
+            | :? System.Decimal as d -> d.ToString("g",opts.FormatProvider) + "M"
+            | :? uint64 as d -> d.ToString(opts.FormatProvider) + "UL"
+            | :? int64  as d -> d.ToString(opts.FormatProvider) + "L"
+            | :? int32  as d -> d.ToString(opts.FormatProvider)
+            | :? uint32 as d -> d.ToString(opts.FormatProvider) + "u"
+            | :? int16  as d -> d.ToString(opts.FormatProvider) + "s"
+            | :? uint16 as d -> d.ToString(opts.FormatProvider) + "us"
+            | :? sbyte  as d -> d.ToString(opts.FormatProvider) + "y"
+            | :? byte   as d -> d.ToString(opts.FormatProvider) + "uy"
+            | :? nativeint as d -> d.ToString() + "n"
+            | :? unativeint  as d -> d.ToString() + "un"
+            | :? bool   as b -> (if b then "true" else "false")
+            | :? char   as c -> "\'" + formatChar true c + "\'"
+            | _ -> try  let text = obj.ToString()
+                        text
+                   with e ->
+                     // If a .ToString() call throws an exception, catch it and use the message as the result.
+                     // This may be informative, e.g. division by zero etc...
+                     "<ToString exception: " + e.Message + ">" 
+
+        let any_to_layout opts x = anyL ShowAll BindingFlags.Public opts x
+
+        let squash_layout opts l = 
+            // Print width = 0 implies 1D layout, no squash
+            if opts.PrintWidth = 0 then 
+                l 
+            else 
+                l |> squashTo (opts.PrintWidth,leafFormatter opts)
+
+        let output_layout opts oc l = 
+            l |> squash_layout opts 
+              |> outL opts.AttributeProcessor (leafFormatter opts) oc
+
+        let layout_to_string opts l = 
+            l |> squash_layout opts 
+              |> showL opts (leafFormatter opts) 
+
+        let output_any_ex opts oc x = x |> any_to_layout opts |> output_layout opts oc
+
+        let output_any oc x = output_any_ex FormatOptions.Default oc x
+
+        let layout_as_string opts x = x |> any_to_layout opts |> layout_to_string opts
+
+        let any_to_string x = layout_as_string FormatOptions.Default x
+
+
diff --git a/src/FSharp.PowerPack/StructuredFormat.fsi b/src/FSharp.PowerPack/StructuredFormat.fsi
new file mode 100755
index 0000000..24b72f6
--- /dev/null
+++ b/src/FSharp.PowerPack/StructuredFormat.fsi
@@ -0,0 +1,188 @@
+//=========================================================================
+// (c) Microsoft Corporation 2005-2009. 
+//=========================================================================
+
+namespace Microsoft.FSharp.Text.StructuredFormat
+
+    open System
+    open System.IO
+
+    /// Data representing joints in structured layouts of terms.  The representation
+    /// of this data type is only for the consumption of formatting engines.
+    [<StructuralEquality; NoComparison>]
+    type Joint =
+        | Unbreakable
+        | Breakable of int
+        | Broken of int
+
+    /// Data representing structured layouts of terms.  The representation
+    /// of this data type is only for the consumption of formatting engines.
+    [<NoEquality; NoComparison>]
+    type Layout =
+     | Leaf of bool * obj * bool
+     | Node of bool * Layout * bool * Layout * bool * Joint
+     | Attr of string * (string * string) list * Layout
+
+
+    type IEnvironment = 
+        /// Return to the layout-generation 
+        /// environment to layout any otherwise uninterpreted object
+        abstract GetLayout : obj -> Layout
+        /// The maximum number of elements for which to generate layout for 
+        /// list-like structures, or columns in table-like 
+        /// structures.  -1 if no maximum.
+        abstract MaxColumns : int
+        /// The maximum number of rows for which to generate layout for table-like 
+        /// structures.  -1 if no maximum.
+        abstract MaxRows : int
+      
+    /// A layout is a sequence of strings which have been joined together.
+    /// The strings are classified as words, separators and left and right parenthesis.
+    /// This classification determines where spaces are inserted.
+    /// A joint is either unbreakable, breakable or broken.
+    /// If a joint is broken the RHS layout occurs on the next line with optional indentation.
+    /// A layout can be squashed to for given width which forces breaks as required.
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module LayoutOps =
+
+        /// The empty layout
+        val emptyL     : Layout
+        /// Is it the empty layout?
+        val isEmptyL   : layout:Layout -> bool
+        
+        /// An uninterpreted leaf, to be interpreted into a string
+        /// by the layout engine. This allows leaf layouts for numbers, strings and
+        /// other atoms to be customized according to culture.
+        val objL       : value:obj -> Layout
+
+        /// An string leaf 
+        val wordL      : text:string -> Layout
+        /// An string which requires no spaces either side.
+        val sepL       : text:string -> Layout
+        /// An string which is right parenthesis (no space on the left).
+        val rightL     : text:string -> Layout
+        /// An string which is left  parenthesis (no space on the right).
+        val leftL      : text:string -> Layout
+
+        /// Join, unbreakable. 
+        val ( ^^ )     : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join, possible break with indent=0
+        val ( ++ )     : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join, possible break with indent=1
+        val ( -- )     : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join, possible break with indent=2 
+        val ( --- )    : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join broken with ident=0
+        val ( @@ )     : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join broken with ident=1 
+        val ( @@- )    : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join broken with ident=2 
+        val ( @@-- )   : layout1:Layout -> layout2:Layout -> Layout   
+
+        /// Join layouts into a comma separated list.
+        val commaListL : layouts:Layout list -> Layout
+          
+        /// Join layouts into a space separated list.    
+        val spaceListL : layouts:Layout list -> Layout
+          
+        /// Join layouts into a semi-colon separated list.
+        val semiListL  : layouts:Layout list -> Layout
+
+        /// Join layouts into a list separated using the given Layout.
+        val sepListL   : layout1:Layout -> layouts:Layout list -> Layout
+
+        /// Wrap round brackets around Layout.
+        val bracketL   : Layout:Layout -> Layout
+        /// Wrap square brackets around layout.    
+        val squareBracketL   : layout:Layout -> Layout
+        /// Wrap braces around layout.        
+        val braceL     : layout:Layout -> Layout
+        /// Form tuple of layouts.            
+        val tupleL     : layouts:Layout list -> Layout
+        /// Layout two vertically.
+        val aboveL     : layout1:Layout -> layout2:Layout -> Layout
+        /// Layout list vertically.    
+        val aboveListL : layouts:Layout list -> Layout
+
+        /// Layout like an F# option.
+        val optionL    : selector:('T -> Layout) -> value:'T option -> Layout
+        /// Layout like an F# list.    
+        val listL      : selector:('T -> Layout) -> value:'T list   -> Layout
+
+        /// See tagL
+        val tagAttrL : text:string -> maps:(string * string) list -> layout:Layout -> Layout
+
+        /// For limitting layout of list-like sequences (lists,arrays,etc).
+        /// unfold a list of items using (project and z) making layout list via itemL.
+        /// If reach maxLength (before exhausting) then truncate.
+        val unfoldL : selector:('T -> Layout) -> folder:('State -> ('T * 'State) option) -> state:'State -> count:int -> Layout list
+
+    /// A record of options to control structural formatting.
+    /// For F# Interactive properties matching those of this value can be accessed via the 'fsi'
+    /// value.
+    /// 
+    /// Floating Point format given in the same format accepted by System.Double.ToString,
+    /// e.g. f6 or g15.
+    ///
+    /// If ShowProperties is set the printing process will evaluate properties of the values being
+    /// displayed.  This may cause additional computation.  
+    ///
+    /// The ShowIEnumerable is set the printing process will force the evalution of IEnumerable objects
+    /// to a small, finite depth, as determined by the printing parameters.
+    /// This may lead to additional computation being performed during printing.
+    ///
+    /// <example>
+    /// From F# Interactive the default settings can be adjusted using, for example, 
+    /// <pre>
+    ///   open Microsoft.FSharp.Compiler.Interactive.Settings;;
+    ///   setPrintWidth 120;;
+    /// </pre>
+    /// </example>
+    [<NoEquality; NoComparison>]
+    type FormatOptions = 
+        { FloatingPointFormat: string
+          AttributeProcessor: (string -> (string * string) list -> bool -> unit);
+          FormatProvider: System.IFormatProvider
+          BindingFlags: System.Reflection.BindingFlags
+          PrintWidth : int 
+          PrintDepth : int 
+          PrintLength : int
+          PrintSize : int  
+          ShowProperties : bool
+          ShowIEnumerable: bool  }
+        static member Default : FormatOptions
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Display = 
+
+
+        /// Convert any value to a string using a standard formatter
+        /// Data is typically formatted in a structured format, e.g.
+        /// lists are formatted using the "[1;2]" notation.
+        /// The details of the format are not specified and may change
+        /// from version to version and according to the flags given
+        /// to the F# compiler.  The format is intended to be human-readable,
+        /// not machine readable.  If alternative generic formats are required
+        /// you should develop your own formatter, using the code in the
+        /// implementation of this file as a starting point.
+        ///
+        /// Data from other .NET languages is formatted using a virtual
+        /// call to Object.ToString() on the boxed version of the input.
+        val any_to_string: value:'T -> string
+
+        /// Ouput any value to a channel using the same set of formatting rules
+        /// as any_to_string
+        val output_any: writer:TextWriter -> value:'T -> unit
+
+        val any_to_layout   : options:FormatOptions -> value:'T -> Layout
+        val squash_layout   : options:FormatOptions -> layout:Layout -> Layout
+        val output_layout   : options:FormatOptions -> writer:TextWriter -> layout:Layout -> unit
+        val layout_as_string: options:FormatOptions -> value:'T -> string
+
+        /// Convert any value to a layout using the given formatting options.  The
+        /// layout can then be processed using formatting display engines such as
+        /// those in the LayoutOps module.  any_to_string and output_any are
+        /// built using any_to_layout with default format options.
+        val layout_to_string: options:FormatOptions -> layout:Layout -> string
+
+
diff --git a/src/FSharp.PowerPack/TaggedCollections.fs b/src/FSharp.PowerPack/TaggedCollections.fs
new file mode 100755
index 0000000..92ebf5b
--- /dev/null
+++ b/src/FSharp.PowerPack/TaggedCollections.fs
@@ -0,0 +1,1179 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Collections.Tagged
+
+    #nowarn "51"
+    #nowarn "69" // interface implementations in augmentations
+    #nowarn "60" // override implementations in augmentations
+
+    open System
+    open System.Collections.Generic
+    open Microsoft.FSharp.Collections
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
+    [<NoEquality; NoComparison>]
+    type SetTree<'T> = 
+        | SetEmpty                                          // height = 0   
+        | SetNode of 'T * SetTree<'T> *  SetTree<'T> * int    // height = int 
+#if ONE
+        | SetOne  of 'T                                     // height = 1   
+#endif
+        // OPTIMIZATION: store SetNode(k,SetEmpty,SetEmpty,1) --->  SetOne(k) 
+
+
+    // CONSIDER: SetTree<'T> = SetEmpty | SetNode of 'T  * SetTree<'T> *  SetTree<'T> * int
+    //  with SetOne = SetNode of (x,null,null,1)
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module SetTree = 
+        let empty = SetEmpty
+
+        let height t = 
+            match t with 
+            | SetEmpty -> 0
+#if ONE
+            | SetOne _ -> 1
+#endif
+            | SetNode (_,_,_,h) -> h
+
+#if CHECKED
+        let rec checkInvariant t =
+            // A good sanity check, loss of balance can hit perf 
+            match t with 
+            | SetEmpty -> true
+            | SetOne _ -> true
+            | SetNode (k,t1,t2,h) ->
+                let h1 = height t1 in
+                let h2 = height t2 in
+                (-2 <= (h1 - h2) && (h1 - h2) <= 2) && checkInvariant t1 && checkInvariant t2
+#else
+        let inline SetOne(x) = SetNode(x,SetEmpty,SetEmpty,1)
+#endif
+
+        let tolerance = 2
+
+        let mk l hl k r hr = 
+#if ONE
+            if hl = 0 && hr = 0 then SetOne (k)
+            else
+#endif
+              let m = if hl < hr then hr else hl 
+              SetNode(k,l,r,m+1)
+
+        let rebalance t1 k t2 =
+            let t1h = height t1 
+            let t2h = height t2
+            if  t2h > t1h + tolerance then // right is heavier than left 
+                match t2 with 
+                | SetNode(t2k,t2l,t2r,_) -> 
+                    // one of the nodes must have height > height t1 + 1 
+                    let t2lh = height t2l
+                    if t2lh > t1h + 1 then  // balance left: combination 
+                        match t2l with 
+                        | SetNode(t2lk,t2ll,t2lr,_) ->
+                            let l = mk t1 t1h k t2ll (height t2ll)
+                            let r = mk t2lr (height t2lr) t2k t2r (height t2r)
+                            mk l (height l) t2lk r (height r)
+                        | _ -> failwith "rebalance"
+                    else // rotate left 
+                        let l = mk t1 t1h k t2l t2lh
+                        mk l (height l) t2k t2r (height t2r)
+                | _ -> failwith "rebalance"
+            else
+                if  t1h > t2h + tolerance then // left is heavier than right 
+                    match t1 with 
+                    | SetNode(t1k,t1l,t1r,_) -> 
+                        // one of the nodes must have height > height t2 + 1 
+                        let t1rh = height t1r
+                        if t1rh > t2h + 1 then 
+                            // balance right: combination 
+                            match t1r with 
+                            | SetNode(t1rk,t1rl,t1rr,_) ->
+                                let l = mk t1l (height t1l) t1k t1rl (height t1rl)
+                                let r = mk t1rr (height t1rr) k t2 t2h
+                                mk l (height l) t1rk r (height r)
+                            | _ -> failwith "rebalance"
+                        else
+                            let r = mk t1r t1rh k t2 t2h
+                            mk t1l (height t1l) t1k r (height r)
+                    | _ -> failwith "rebalance"
+                else mk t1 t1h k t2 t2h
+
+        let rec add (comparer: IComparer<'T>) k t = 
+            match t with 
+            | SetNode (k2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c < 0 then rebalance (add comparer k l) k2 r
+                elif c = 0 then t
+                else            rebalance l k2 (add comparer k r)
+#if ONE
+            | SetOne(k2) -> 
+                // nb. no check for rebalance needed for small trees, also be sure to reuse node already allocated 
+                let c = comparer.Compare(k,k2) 
+                if c < 0   then SetNode (k,SetEmpty,t,2)
+                elif c = 0 then t
+                else            SetNode (k,t,SetEmpty,2)                  
+#endif
+            | SetEmpty -> SetOne(k)
+
+        let rec balance comparer t1 k t2 =
+            // Given t1 < k < t2 where t1 and t2 are "balanced",
+            // return a balanced tree for <t1,k,t2>.
+            // Recall: balance means subtrees heights differ by at most "tolerance"
+            match t1,t2 with
+            | SetEmpty,t2  -> add comparer k t2 // drop t1 = empty 
+            | t1,SetEmpty  -> add comparer k t1 // drop t2 = empty 
+#if ONE
+            | SetOne k1,t2 -> add comparer k (add comparer k1 t2)
+            | t1,SetOne k2 -> add comparer k (add comparer k2 t1)
+#endif
+            | SetNode(k1,t11,t12,t1h),SetNode(k2,t21,t22,t2h) ->
+                // Have:  (t11 < k1 < t12) < k < (t21 < k2 < t22)
+                // Either (a) h1,h2 differ by at most 2 - no rebalance needed.
+                //        (b) h1 too small, i.e. h1+2 < h2
+                //        (c) h2 too small, i.e. h2+2 < h1 
+                if   t1h+tolerance < t2h then
+                    // case: b, h1 too small 
+                    // push t1 into low side of t2, may increase height by 1 so rebalance 
+                    rebalance (balance comparer t1 k t21) k2 t22
+                elif t2h+tolerance < t1h then
+                    // case: c, h2 too small 
+                    // push t2 into high side of t1, may increase height by 1 so rebalance 
+                    rebalance t11 k1 (balance comparer t12 k t2)
+                else
+                    // case: a, h1 and h2 meet balance requirement 
+                    mk t1 t1h k t2 t2h
+
+        let rec split (comparer : IComparer<'T>) pivot t =
+            // Given a pivot and a set t
+            // Return { x in t s.t. x < pivot }, pivot in t? , { x in t s.t. x > pivot } 
+            match t with
+            | SetNode(k1,t11,t12,_) ->
+                let c = comparer.Compare(pivot,k1)
+                if   c < 0 then // pivot t1 
+                    let t11_lo,havePivot,t11_hi = split comparer pivot t11
+                    t11_lo,havePivot,balance comparer t11_hi k1 t12
+                elif c = 0 then // pivot is k1 
+                    t11,true,t12
+                else            // pivot t2 
+                    let t12_lo,havePivot,t12_hi = split comparer pivot t12
+                    balance comparer t11 k1 t12_lo,havePivot,t12_hi
+#if ONE
+            | SetOne k1 ->
+                let c = comparer.Compare(k1,pivot)
+                if   c < 0 then t       ,false,SetEmpty // singleton under pivot 
+                elif c = 0 then SetEmpty,true ,SetEmpty // singleton is    pivot 
+                else            SetEmpty,false,t        // singleton over  pivot 
+#endif
+            | SetEmpty  -> 
+                SetEmpty,false,SetEmpty
+        
+        let rec spliceOutSuccessor t = 
+            match t with 
+            | SetEmpty -> failwith "internal error: Map.splice_out_succ_or_pred"
+#if ONE
+            | SetOne (k2) -> k2,empty
+#endif
+            | SetNode (k2,l,r,_) ->
+                match l with 
+                | SetEmpty -> k2,r
+                | _ -> let k3,l' = spliceOutSuccessor l in k3,mk l' (height l') k2 r (height r)
+
+        let rec remove (comparer: IComparer<'T>) k t = 
+            match t with 
+            | SetEmpty -> t
+#if ONE
+            | SetOne (k2) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c = 0 then empty
+                else            t
+#endif
+            | SetNode (k2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c < 0 then rebalance (remove comparer k l) k2 r
+                elif c = 0 then 
+                  match l,r with 
+                  | SetEmpty,_ -> r
+                  | _,SetEmpty -> l
+                  | _ -> 
+                      let sk,r' = spliceOutSuccessor r 
+                      mk l (height l) sk r' (height r')
+                else rebalance l k2 (remove comparer k r) 
+
+        let rec contains (comparer: IComparer<'T>) k t = 
+            match t with 
+            | SetNode(k2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c < 0 then contains comparer k l
+                elif c = 0 then true
+                else contains comparer k r
+#if ONE
+            | SetOne(k2) -> (comparer.Compare(k,k2) = 0)
+#endif
+            | SetEmpty -> false
+
+        let rec iter f t = 
+            match t with 
+            | SetNode(k2,l,r,_) -> iter f l; f k2; iter f r
+#if ONE
+            | SetOne(k2) -> f k2
+#endif
+            | SetEmpty -> ()            
+
+        // Fold, left-to-right. 
+        //
+        // NOTE: This differs from the behaviour of Map.fold which folds right-to-left.
+        let rec fold f m x = 
+            match m with 
+            | SetNode(k,l,r,_) -> fold f r (f k (fold f l x))
+#if ONE
+            | SetOne(k) -> f k x
+#endif
+            | SetEmpty -> x                
+
+        let rec forAll f m = 
+            match m with 
+            | SetNode(k2,l,r,_) -> f k2 && forAll f l && forAll f r
+#if ONE
+            | SetOne(k2) -> f k2
+#endif
+            | SetEmpty -> true          
+
+        let rec exists f m = 
+            match m with 
+            | SetNode(k2,l,r,_) -> f k2 || exists f l || exists f r
+#if ONE
+            | SetOne(k2) -> f k2
+#endif
+            | SetEmpty -> false         
+
+        let isEmpty m = match m with  | SetEmpty -> true | _ -> false
+
+        let subset comparer a b  = forAll (fun x -> contains comparer x b) a
+
+        let rec elementsAux m acc = 
+            match m with 
+            | SetNode(k2,l,r,_) -> k2 :: (elementsAux l (elementsAux r acc))
+#if ONE
+            | SetOne(k2) -> k2 :: acc
+#endif
+            | SetEmpty -> acc                
+
+        let elements a  = elementsAux a []
+
+        let rec filterAux comparer f s acc = 
+            match s with 
+            | SetNode(k,l,r,_) -> 
+                let acc = if f k then add comparer k acc else acc 
+                filterAux comparer f l (filterAux comparer f r acc)
+#if ONE
+            | SetOne(k) -> if f k then add comparer k acc else acc
+#endif
+            | SetEmpty -> acc           
+
+        let filter comparer f s = filterAux comparer f s empty
+
+        let rec diffAux comparer m acc = 
+            match m with 
+            | SetNode(k,l,r,_) -> diffAux comparer l (diffAux comparer r (remove comparer k acc))
+#if ONE
+            | SetOne(k) -> remove comparer k acc
+#endif
+            | SetEmpty -> acc           
+
+        let diff comparer a b = diffAux comparer b a
+
+        let rec countAux s acc = 
+            match s with 
+            | SetNode(_,l,r,_) -> countAux l (countAux r (acc+1))
+#if ONE
+            | SetOne(k) -> acc+1
+#endif
+            | SetEmpty -> acc           
+
+        let count s = countAux s 0
+
+        let rec union comparer t1 t2 =
+            // Perf: tried bruteForce for low heights, but nothing significant 
+            match t1,t2 with               
+            | SetNode(k1,t11,t12,h1),SetNode(k2,t21,t22,h2) -> // (t11 < k < t12) AND (t21 < k2 < t22) 
+                // Divide and Quonquer:
+                //   Suppose t1 is largest.
+                //   Split t2 using pivot k1 into lo and hi.
+                //   Union disjoint subproblems and then combine. 
+                if h1 > h2 then
+                  let lo,_,hi = split comparer k1 t2 in
+                  balance comparer (union comparer t11 lo) k1 (union comparer t12 hi)
+                else
+                  let lo,_,hi = split comparer k2 t1 in
+                  balance comparer (union comparer t21 lo) k2 (union comparer t22 hi)
+            | SetEmpty,t -> t
+            | t,SetEmpty -> t
+#if ONE
+            | SetOne k1,t2 -> add comparer k1 t2
+            | t1,SetOne k2 -> add comparer k2 t1
+#endif
+
+        let rec intersectionAux comparer b m acc = 
+            match m with 
+            | SetNode(k,l,r,_) -> 
+                let acc = intersectionAux comparer b r acc 
+                let acc = if contains comparer k b then add comparer k acc else acc 
+                intersectionAux comparer b l acc
+#if ONE
+            | SetOne(k) -> 
+                if contains comparer k b then add comparer k acc else acc
+#endif
+            | SetEmpty -> acc
+
+        let intersection comparer a b = intersectionAux comparer b a empty
+
+        let partition1 comparer f k (acc1,acc2) = 
+            if f k then (add comparer k acc1,acc2) 
+            else (acc1,add comparer k acc2) 
+        
+        let rec partitionAux comparer f s acc = 
+            match s with 
+            | SetNode(k,l,r,_) -> 
+                let acc = partitionAux comparer f r acc 
+                let acc = partition1 comparer f k acc
+                partitionAux comparer f l acc
+#if ONE
+            | SetOne(k) -> partition1 comparer f k acc
+#endif
+            | SetEmpty -> acc           
+
+        let partition comparer f s = partitionAux comparer f s (empty,empty)
+
+        // It's easier to get many less-important algorithms right using this active pattern
+        let (|MatchSetNode|MatchSetEmpty|) s = 
+            match s with 
+            | SetNode(k2,l,r,_) -> MatchSetNode(k2,l,r)
+#if ONE
+            | SetOne(k2) -> MatchSetNode(k2,SetEmpty,SetEmpty)
+#endif
+            | SetEmpty -> MatchSetEmpty
+        
+        let rec nextElemCont (comparer: IComparer<'T>) k s cont = 
+            match s with 
+            | MatchSetNode(k2,l,r) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c < 0 then nextElemCont comparer k l (function None -> cont(Some(k2)) | res -> res)
+                elif c = 0 then cont(minimumElementOpt r) 
+                else nextElemCont comparer k r cont
+            | MatchSetEmpty -> cont(None)
+
+        and nextElem comparer k s = nextElemCont comparer k s (fun res -> res)
+        
+        and prevElemCont (comparer: IComparer<'T>) k s cont = 
+            match s with 
+            | MatchSetNode(k2,l,r) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c > 0 then prevElemCont comparer k r (function None -> cont(Some(k2)) | res -> res)
+                elif c = 0 then cont(maximumElementOpt r) 
+                else prevElemCont comparer k l cont
+            | MatchSetEmpty -> cont(None)
+
+        and prevElem comparer k s = prevElemCont comparer k s (fun res -> res)
+        
+        and minimumElementAux s n = 
+            match s with 
+            | SetNode(k,l,_,_) -> minimumElementAux l k
+#if ONE
+            | SetOne(k) -> k
+#endif
+            | SetEmpty -> n
+
+        and minimumElementOpt s = 
+            match s with 
+            | SetNode(k,l,_,_) -> Some(minimumElementAux l k)
+#if ONE
+            | SetOne(k) -> Some k
+#endif
+            | SetEmpty -> None
+
+        and maximumElementAux s n = 
+            match s with 
+            | SetNode(k,_,r,_) -> maximumElementAux r k
+#if ONE
+            | SetOne(k) -> k
+#endif
+            | SetEmpty -> n             
+
+        and maximumElementOpt s = 
+            match s with 
+            | SetNode(k,_,r,_) -> Some(maximumElementAux r k)
+#if ONE
+            | SetOne(k) -> Some(k)
+#endif
+            | SetEmpty -> None
+
+        let minimumElement s = 
+            match minimumElementOpt s with 
+            | Some(k) -> k
+            | None -> failwith "minimumElement"            
+
+        let maximumElement s = 
+            match maximumElementOpt s with 
+            | Some(k) -> k
+            | None -> failwith "maximumElement"
+
+
+        //--------------------------------------------------------------------------
+        // Imperative left-to-right iterators.
+        //--------------------------------------------------------------------------
+
+        type SetIterator<'T>(s:SetTree<'T>) = 
+
+            // collapseLHS:
+            // a) Always returns either [] or a list starting with SetOne.
+            // b) The "fringe" of the set stack is unchanged.
+            let rec collapseLHS stack =
+                match stack with
+                | []                       -> []
+                | SetEmpty         :: rest -> collapseLHS rest
+#if ONE
+                | SetOne k         :: rest -> stack
+#else
+                | SetNode(_,SetEmpty,SetEmpty,_) :: _ -> stack
+#endif
+                | SetNode(k,l,r,_) :: rest -> collapseLHS (l :: SetOne k :: r :: rest)
+
+            // invariant: always collapseLHS result 
+            let mutable stack = collapseLHS [s]
+            // true when MoveNext has been called   
+            let mutable started = false 
+
+            let notStarted() = raise (new System.InvalidOperationException("Enumeration has not started. Call MoveNext."))
+            let alreadyFinished() = raise (new System.InvalidOperationException("Enumeration already finished."))
+
+            member i.Current =
+                if started then
+                    match stack with
+#if ONE
+                      | SetOne k :: _ -> k
+#else
+                      | SetNode( k,_,_,_) :: _ -> k
+#endif
+                      | []            -> alreadyFinished()
+                      | _             -> failwith "Please report error: Set iterator, unexpected stack for current"
+                else
+                    notStarted()
+
+            member i.MoveNext() = 
+                if started then
+                    match stack with
+#if ONE
+                      | SetOne _ :: rest -> 
+#else
+                      | SetNode _ :: rest -> 
+#endif
+                            stack <- collapseLHS rest;
+                            not stack.IsEmpty
+                      | [] -> false
+                      | _ -> failwith "Please report error: Set iterator, unexpected stack for moveNext"
+                else
+                    started <- true;  // The first call to MoveNext "starts" the enumeration.
+                    not stack.IsEmpty
+
+        let toSeq s = 
+            let i = ref (SetIterator s) 
+            { new IEnumerator<_> with 
+                  member __.Current = (!i).Current
+              interface System.Collections.IEnumerator with 
+                  member __.Current = box (!i).Current
+                  member __.MoveNext() = (!i).MoveNext()
+                  member __.Reset() = i :=  SetIterator s
+              interface System.IDisposable with 
+                  member __.Dispose() = () }
+
+        //--------------------------------------------------------------------------
+        // Set comparison.  This can be expensive.
+        //--------------------------------------------------------------------------
+
+        let rec compareStacks (comparer: IComparer<'T>) l1 l2 =
+            match l1,l2 with 
+            | [],[] ->  0
+            | [],_  -> -1
+            | _ ,[] ->  1
+            | (SetEmpty  _ :: t1),(SetEmpty    :: t2) -> compareStacks comparer t1 t2
+#if ONE
+            | (SetOne(n1k) :: t1),(SetOne(n2k) :: t2) -> 
+                 let c = comparer.Compare(n1k,n2k) 
+                 if c <> 0 then c else compareStacks comparer t1 t2
+            | (SetOne(n1k) :: t1),(SetNode(n2k,SetEmpty,n2r,_) :: t2) -> 
+                 let c = comparer.Compare(n1k,n2k) 
+                 if c <> 0 then c else compareStacks comparer (empty :: t1) (n2r :: t2)
+            | (SetNode(n1k,(SetEmpty as emp),n1r,_) :: t1),(SetOne(n2k) :: t2) -> 
+                 let c = comparer.Compare(n1k,n2k) 
+                 if c <> 0 then c else compareStacks comparer (n1r :: t1) (emp :: t2)
+#endif
+            | (SetNode(n1k,SetEmpty,n1r,_) :: t1),(SetNode(n2k,SetEmpty,n2r,_) :: t2) -> 
+                 let c = comparer.Compare(n1k,n2k) 
+                 if c <> 0 then c else compareStacks comparer (n1r :: t1) (n2r :: t2)
+#if ONE
+            | (SetOne(n1k) :: t1),_ -> 
+                compareStacks comparer (empty :: SetOne(n1k) :: t1) l2
+#endif
+            | (SetNode(n1k,n1l,n1r,_) :: t1),_ -> 
+                compareStacks comparer (n1l :: SetNode(n1k,empty,n1r,0) :: t1) l2
+#if ONE
+            | _,(SetOne(n2k) :: t2) -> 
+                compareStacks comparer l1 (empty :: SetOne(n2k) :: t2)
+#endif
+            | _,(SetNode(n2k,n2l,n2r,_) :: t2) -> 
+                compareStacks comparer l1 (n2l :: SetNode(n2k,empty,n2r,0) :: t2)
+                
+        let compare comparer s1 s2 = 
+            match s1,s2 with 
+            | SetEmpty,SetEmpty -> 0
+            | SetEmpty,_ -> -1
+            | _,SetEmpty -> 1
+            | _ -> compareStacks comparer [s1] [s2]
+
+        let choose s = minimumElement s
+
+        let toList s = 
+            let rec loop m x = 
+                match m with 
+                | SetNode(k,l,r,_) -> loop l (k :: (loop r x))
+#if ONE
+                | SetOne(k) -> k :: x
+#endif
+                | SetEmpty -> x
+            loop s []            
+
+        let copyToArray s (arr: _[]) i =
+            let j = ref i 
+            iter (fun x -> arr.[!j] <- x; j := !j + 1) s
+
+        let toArray s = 
+            let n = (count s) 
+            let res = Array.zeroCreate n 
+            copyToArray s res 0;
+            res
+
+        let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = 
+            if e.MoveNext() then 
+              mkFromEnumerator comparer (add comparer e.Current acc) e
+            else acc
+          
+        let ofSeq comparer (c : IEnumerable<_>) =
+            use ie = c.GetEnumerator()
+            mkFromEnumerator comparer empty ie 
+
+        let ofArray comparer l = Array.fold (fun acc k -> add comparer k acc) empty l    
+
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+    [<System.Diagnostics.DebuggerDisplay ("Count = {Count}")>]
+#endif
+    [<Sealed>]
+    type Set<'T,'ComparerTag> when 'ComparerTag :> IComparer<'T>(comparer: IComparer<'T>, tree: SetTree<'T>) =
+
+        static let refresh (s:Set<_,_>) t =    Set<_,_>(comparer=s.ComparerUntyped, tree=t)
+
+        member s.Tree = tree
+        member s.ComparerUntyped : IComparer<'T> = comparer 
+        member s.Comparer = (comparer :?> 'ComparerTag)
+
+        static member Empty(comparer: 'ComparerTag) : Set<'T,'ComparerTag> =  
+            Set<_,_>(comparer=comparer, tree=SetTree.empty)
+
+
+        member s.Add(x) : Set<'T,'ComparerTag> = refresh s (SetTree.add comparer x tree)
+        member s.Remove(x) : Set<'T,'ComparerTag> = refresh s (SetTree.remove comparer x tree)
+        member s.Count = SetTree.count tree
+        member s.Contains(x) = SetTree.contains comparer  x tree
+        member s.Iterate(x) = SetTree.iter  x tree
+        member s.Fold f x  = SetTree.fold f tree x
+
+#if CHECKED
+        member s.CheckBalanceInvariant = checkInvariant tree // diagnostics...
+#endif
+        member s.IsEmpty  = SetTree.isEmpty tree
+
+        member s.Partition f  : Set<'T,'ComparerTag> *  Set<'T,'ComparerTag> = 
+            match tree with 
+            | SetEmpty -> s,s
+            | _ -> 
+                let t1,t2 = SetTree.partition comparer f tree 
+                refresh s t1, refresh s t2
+
+        member s.Filter f  : Set<'T,'ComparerTag> = 
+            match tree with 
+            | SetEmpty -> s
+            | _ -> SetTree.filter comparer f tree |> refresh s
+
+        member s.Exists f = SetTree.exists f tree
+
+        member s.ForAll f = SetTree.forAll f tree
+
+        static member (-) ((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) = Set<_,_>.Difference(a,b)
+
+        static member (+)  ((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) = Set<_,_>.Union(a,b)
+
+        static member Intersection((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) : Set<'T,'ComparerTag>  = 
+            match b.Tree with 
+            | SetEmpty -> b  (* A INTER 0 = 0 *)
+            | _ -> 
+               match a.Tree with 
+               | SetEmpty -> a (* 0 INTER B = 0 *)
+               | _ -> SetTree.intersection a.ComparerUntyped  a.Tree b.Tree |> refresh a
+           
+        static member Union(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag>  = 
+            match b.Tree with 
+            | SetEmpty -> a  (* A U 0 = A *)
+            | _ -> 
+               match a.Tree with 
+               | SetEmpty -> b  (* 0 U B = B *)
+               | _ -> SetTree.union a.ComparerUntyped  a.Tree b.Tree |> refresh a
+
+        static member Difference(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag>  = 
+            match a.Tree with 
+            | SetEmpty -> a (* 0 - B = 0 *)
+            | _ -> 
+                match b.Tree with 
+                | SetEmpty -> a (* A - 0 = A *)
+                | _ -> SetTree.diff a.ComparerUntyped  a.Tree b.Tree |> refresh a
+
+        static member Equality(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = 
+            (SetTree.compare a.ComparerUntyped  a.Tree b.Tree = 0)
+
+        static member Compare(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = 
+            SetTree.compare a.ComparerUntyped  a.Tree b.Tree
+
+        member s.Choose = SetTree.choose tree
+
+        member s.MinimumElement = SetTree.minimumElement tree
+
+        member s.MaximumElement = SetTree.maximumElement tree
+
+        member s.IsSubsetOf((y: Set<'T,'ComparerTag>)) = SetTree.subset comparer tree y.Tree 
+
+        member s.IsSupersetOf((y: Set<'T,'ComparerTag>)) = SetTree.subset comparer y.Tree tree
+
+        member s.ToList () = SetTree.toList tree
+
+        member s.ToArray () = SetTree.toArray tree
+
+        override this.Equals(that) = 
+            match that with
+            // Cast to the exact same type as this, otherwise not equal.
+            | :? Set<'T,'ComparerTag> as that -> ((this :> System.IComparable).CompareTo(that) = 0)
+            | _ -> false
+
+        interface System.IComparable with
+            // Cast s2 to the exact same type as s1, see 4884.
+            // It is not OK to cast s2 to seq<'T>, since different compares could permute the elements.
+            member s1.CompareTo(s2: obj) = SetTree.compare s1.ComparerUntyped s1.Tree ((s2 :?> Set<'T,'ComparerTag>).Tree)
+
+        member this.ComputeHashCode() = 
+                let combineHash x y = (x <<< 1) + y + 631 
+                let mutable res = 0
+                for x in this do
+                    res <- combineHash res (Unchecked.hash x)
+                abs res
+
+        override this.GetHashCode() = this.ComputeHashCode()
+          
+        interface ICollection<'T> with 
+            member s.Add(x) = raise (new System.NotSupportedException("ReadOnlyCollection"))
+            member s.Clear() = raise (new System.NotSupportedException("ReadOnlyCollection"))
+            member s.Remove(x) = raise (new System.NotSupportedException("ReadOnlyCollection"))
+            member s.Contains(x) = SetTree.contains comparer x tree
+            member s.CopyTo(arr,i) = SetTree.copyToArray tree arr i
+            member s.IsReadOnly = true
+            member s.Count = SetTree.count tree  
+
+        interface IEnumerable<'T> with
+            member s.GetEnumerator() = SetTree.toSeq tree
+
+        interface System.Collections.IEnumerable with
+            override s.GetEnumerator() = (SetTree.toSeq tree :> System.Collections.IEnumerator)
+
+        static member Singleton(comparer,x) : Set<'T,'ComparerTag>  = 
+            Set<_,_>.Empty(comparer).Add(x)
+
+        static member Create(comparer : 'ComparerTag,l : seq<'T>) : Set<'T,'ComparerTag> = 
+            Set<_,_>(comparer=comparer, tree=SetTree.ofSeq comparer l)
+
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
+    [<NoEquality; NoComparison>]
+    type MapTree<'Key,'T> = 
+        | MapEmpty 
+#if ONE 
+        | MapOne of 'Key * 'T
+#endif
+        // Note: performance rumour has it that the data held in this node should be
+        // exactly one cache line. It is currently ~7 words. Thus it might be better to
+        // move to a n-way tree.
+        | MapNode of 'Key * 'T * MapTree<'Key,'T> *  MapTree<'Key,'T> * int
+
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module MapTree = 
+
+        let empty = MapEmpty 
+
+        let inline height x  = 
+          match x with 
+          | MapEmpty -> 0
+#if ONE 
+          | MapOne _ -> 1
+#endif
+          | MapNode(_,_,_,_,h) -> h
+
+        let isEmpty m = 
+            match m with 
+            | MapEmpty -> true
+            | _ -> false
+
+        let mk l k v r = 
+#if ONE 
+            match l,r with 
+            | MapEmpty,MapEmpty -> MapOne(k,v)
+            | _ -> 
+#endif
+                let hl = height l 
+                let hr = height r 
+                let m = if hl < hr then hr else hl 
+                MapNode(k,v,l,r,m+1)
+
+        let rebalance t1 k v t2 =
+            let t1h = height t1 
+            if  height t2 > t1h + 2 then (* right is heavier than left *)
+                match t2 with 
+                | MapNode(t2k,t2v,t2l,t2r,_) -> 
+                   (* one of the nodes must have height > height t1 + 1 *)
+                   if height t2l > t1h + 1 then  (* balance left: combination *)
+                     match t2l with 
+                     | MapNode(t2lk,t2lv,t2ll,t2lr,_) ->
+                        mk (mk t1 k v t2ll) t2lk t2lv (mk t2lr t2k t2v t2r) 
+                     | _ -> failwith "rebalance"
+                   else (* rotate left *)
+                     mk (mk t1 k v t2l) t2k t2v t2r
+                | _ -> failwith "rebalance"
+            else
+                let t2h = height t2 
+                if  t1h > t2h + 2 then (* left is heavier than right *)
+                  match t1 with 
+                  | MapNode(t1k,t1v,t1l,t1r,_) -> 
+                    (* one of the nodes must have height > height t2 + 1 *)
+                      if height t1r > t2h + 1 then 
+                      (* balance right: combination *)
+                        match t1r with 
+                        | MapNode(t1rk,t1rv,t1rl,t1rr,_) ->
+                            mk (mk t1l t1k t1v t1rl) t1rk t1rv (mk t1rr k v t2)
+                        | _ -> failwith "rebalance"
+                      else
+                        mk t1l t1k t1v (mk t1r k v t2)
+                  | _ -> failwith "rebalance"
+                else mk t1 k v t2
+
+        let rec sizeAux acc m = 
+            match m with  
+            | MapEmpty -> acc
+#if ONE 
+            | MapOne _ -> acc + 1
+#endif
+            | MapNode(_,_,l,r,_) -> sizeAux (sizeAux (acc+1) l) r 
+
+#if ONE 
+#else
+        let MapOne(k,v) = MapNode(k,v,MapEmpty,MapEmpty,1)
+#endif
+        
+        let count x = sizeAux 0 x
+
+        let rec add (comparer: IComparer<'T>) k v m = 
+            match m with 
+            | MapEmpty -> MapOne(k,v)
+#if ONE 
+            | MapOne(k2,v2) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0   then MapNode (k,v,MapEmpty,m,2)
+                elif c = 0 then MapOne(k,v)
+                else            MapNode (k,v,m,MapEmpty,2)
+#endif
+            | MapNode(k2,v2,l,r,h) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0 then rebalance (add comparer k v l) k2 v2 r
+                elif c = 0 then MapNode(k,v,l,r,h)
+                else rebalance l k2 v2 (add comparer k v r) 
+
+        let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
+
+        let rec find (comparer: IComparer<'T>) k m = 
+            match m with 
+            | MapEmpty -> indexNotFound()
+#if ONE 
+            | MapOne(k2,v2) -> 
+                let c = comparer.Compare(k,k2) 
+                if c = 0 then v2
+                else indexNotFound()
+#endif
+            | MapNode(k2,v2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0 then find comparer k l
+                elif c = 0 then v2
+                else find comparer k r
+
+        let rec tryFind (comparer: IComparer<'T>) k m = 
+            match m with 
+            | MapEmpty -> None
+#if ONE 
+            | MapOne(k2,v2) -> 
+                let c = comparer.Compare(k,k2) 
+                if c = 0 then Some v2
+                else None
+#endif
+            | MapNode(k2,v2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0 then tryFind comparer k l
+                elif c = 0 then Some v2
+                else tryFind comparer k r
+
+        let partition1 (comparer: IComparer<'T>) f k v (acc1,acc2) = 
+            if f k v then (add comparer k v acc1,acc2) else (acc1,add comparer k v acc2) 
+        
+        let rec partitionAux (comparer: IComparer<'T>) f s acc = 
+            match s with 
+            | MapEmpty -> acc
+#if ONE 
+            | MapOne(k,v) -> partition1 comparer f k v acc
+#endif
+            | MapNode(k,v,l,r,_) -> 
+                let acc = partitionAux comparer f r acc 
+                let acc = partition1 comparer f k v acc
+                partitionAux comparer f l acc
+
+        let partition (comparer: IComparer<'T>) f s = partitionAux comparer f s (empty,empty)
+
+        let filter1 (comparer: IComparer<'T>) f k v acc = if f k v then add comparer k v acc else acc 
+
+        let rec filterAux (comparer: IComparer<'T>) f s acc = 
+            match s with 
+            | MapEmpty -> acc
+#if ONE 
+            | MapOne(k,v) -> filter1 comparer f k v acc
+#endif
+            | MapNode(k,v,l,r,_) ->
+                let acc = filterAux comparer f l acc
+                let acc = filter1 comparer f k v acc
+                filterAux comparer f r acc
+
+        let filter (comparer: IComparer<'T>) f s = filterAux comparer f s empty
+
+        let rec spliceOutSuccessor m = 
+            match m with 
+            | MapEmpty -> failwith "internal error: Map.splice_out_succ_or_pred"
+#if ONE 
+            | MapOne(k2,v2) -> k2,v2,MapEmpty
+#endif
+            | MapNode(k2,v2,l,r,_) ->
+                match l with 
+                | MapEmpty -> k2,v2,r
+                | _ -> let k3,v3,l' = spliceOutSuccessor l in k3,v3,mk l' k2 v2 r
+
+        let rec remove (comparer: IComparer<'T>) k m = 
+            match m with 
+            | MapEmpty -> empty
+#if ONE 
+            | MapOne(k2,v2) -> 
+                let c = comparer.Compare(k,k2) 
+                if c = 0 then MapEmpty else m
+#endif
+            | MapNode(k2,v2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0 then rebalance (remove comparer k l) k2 v2 r
+                elif c = 0 then 
+                  match l,r with 
+                  | MapEmpty,_ -> r
+                  | _,MapEmpty -> l
+                  | _ -> 
+                      let sk,sv,r' = spliceOutSuccessor r 
+                      mk l sk sv r'
+                else rebalance l k2 v2 (remove comparer k r) 
+
+        let rec containsKey (comparer: IComparer<'T>) k m = 
+            match m with 
+            | MapEmpty -> false
+#if ONE 
+            | MapOne(k2,v2) -> (comparer.Compare(k,k2) = 0)
+#endif
+            | MapNode(k2,_,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0 then containsKey comparer k l
+                else (c = 0 || containsKey comparer k r)
+
+        let rec iter f m = 
+            match m with 
+            | MapEmpty -> ()
+#if ONE 
+            | MapOne(k2,v2) -> f k2 v2
+#endif
+            | MapNode(k2,v2,l,r,_) -> iter f l; f k2 v2; iter f r
+
+        let rec first f m = 
+            match m with 
+            | MapEmpty -> None
+#if ONE 
+            | MapOne(k2,v2) -> f k2 v2 
+#endif
+            | MapNode(k2,v2,l,r,_) -> 
+                match first f l with 
+                | Some _ as res -> res 
+                | None -> 
+                match f k2 v2 with 
+                | Some _ as res -> res 
+                | None -> first f r
+
+        let rec exists f m = 
+            match m with 
+            | MapEmpty -> false
+#if ONE 
+            | MapOne(k2,v2) -> f k2 v2
+#endif
+            | MapNode(k2,v2,l,r,_) -> f k2 v2 || exists f l || exists f r
+
+        let rec forAll f m = 
+            match m with 
+            | MapEmpty -> true
+#if ONE 
+            | MapOne(k2,v2) -> f k2 v2
+#endif
+            | MapNode(k2,v2,l,r,_) -> f k2 v2 && forAll f l && forAll f r
+
+        let rec map f m = 
+            match m with 
+            | MapEmpty -> empty
+#if ONE 
+            | MapOne(k,v) -> MapOne(k,f v)
+#endif
+            | MapNode(k,v,l,r,h) -> let v2 = f v in MapNode(k,v2,map f l, map f r,h)
+
+        let rec mapi f m = 
+            match m with
+            | MapEmpty -> empty
+#if ONE 
+            | MapOne(k,v) -> MapOne(k,f k v)
+#endif
+            | MapNode(k,v,l,r,h) -> let v2 = f k v in MapNode(k,v2, mapi f l, mapi f r,h)
+
+        // Fold, right-to-left. 
+        //
+        // NOTE: This differs from the behaviour of Set.fold which folds left-to-right.
+        let rec fold f m x = 
+            match m with 
+            | MapEmpty -> x
+#if ONE 
+            | MapOne(k,v) -> f k v x
+#endif
+            | MapNode(k,v,l,r,_) -> fold f l (f k v (fold f r x))
+
+        let foldSection (comparer: IComparer<'T>) lo hi f m x =
+            let rec fold_from_to f m x = 
+                match m with 
+                | MapEmpty -> x
+#if ONE 
+                | MapOne(k,v) ->
+                    let clo_k = comparer.Compare(lo,k)
+                    let ck_hi = comparer.Compare(k,hi)
+                    let x = if clo_k <= 0 && ck_hi <= 0 then f k v x else x
+                    x
+#endif
+                | MapNode(k,v,l,r,_) ->
+                    let clo_k = comparer.Compare(lo,k)
+                    let ck_hi = comparer.Compare(k,hi)
+                    let x = if clo_k < 0                then fold_from_to f l x else x
+                    let x = if clo_k <= 0 && ck_hi <= 0 then f k v x                     else x
+                    let x = if ck_hi < 0                then fold_from_to f r x else x
+                    x
+           
+            if comparer.Compare(lo,hi) = 1 then x else fold_from_to f m x
+
+        let rec foldMap (comparer: IComparer<'T>) f m z acc = 
+            match m with 
+            | MapEmpty -> acc,z
+#if ONE 
+            | MapOne(k,v) -> 
+                let v',z = f k v z
+                add comparer k v' acc,z
+#endif
+            | MapNode(k,v,l,r,_) -> 
+                let acc,z = foldMap comparer f r z acc
+                let v',z = f k v z
+                let acc = add comparer k v' acc 
+                foldMap comparer f l z acc
+
+        let toList m = fold (fun k v acc -> (k,v) :: acc) m []
+        let toArray m = m |> toList |> Array.ofList
+        let ofList comparer l = List.fold (fun acc (k,v) -> add comparer k v acc) empty l
+
+        
+        let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = 
+            if e.MoveNext() then 
+                let (x,y) = e.Current 
+                mkFromEnumerator comparer (add comparer x y acc) e
+            else acc
+          
+        let ofSeq comparer (c : seq<_>) =
+            use ie = c.GetEnumerator()
+            mkFromEnumerator comparer empty ie 
+          
+        let copyToArray s (arr: _[]) i =
+            let j = ref i 
+            s |> iter (fun x y -> arr.[!j] <- KeyValuePair(x,y); j := !j + 1)
+
+
+        /// Imperative left-to-right iterators.
+        type MapIterator<'Key,'T>(s:MapTree<'Key,'T>) = 
+            // collapseLHS:
+            // a) Always returns either [] or a list starting with SetOne.
+            // b) The "fringe" of the set stack is unchanged. 
+            let rec collapseLHS stack =
+                match stack with
+                | []                           -> []
+                | MapEmpty             :: rest -> collapseLHS rest
+#if ONE 
+                | MapOne _         :: _ -> stack
+#else
+                | (MapNode(_,_,MapEmpty,MapEmpty,_)) :: _ -> stack
+#endif
+                | (MapNode(k,v,l,r,_)) :: rest -> collapseLHS (l :: MapOne (k,v) :: r :: rest)
+          
+              /// invariant: always collapseLHS result 
+            let mutable stack = collapseLHS [s]
+               /// true when MoveNext has been called   
+            let mutable started = false
+
+            let notStarted() = raise (new System.InvalidOperationException("Enumeration has not started. Call MoveNext."))
+            let alreadyFinished() = raise (new System.InvalidOperationException("Enumeration already finished."))
+
+            member i.Current =
+                if started then
+                    match stack with
+#if ONE
+                      | MapOne (k,v) :: _ -> new KeyValuePair<_,_>(k,v)
+#else
+                      | (MapNode(k,v,MapEmpty,MapEmpty,_)) :: _ -> new KeyValuePair<_,_>(k,v)
+#endif
+                      | []            -> alreadyFinished()
+                      | _             -> failwith "Please report error: Map iterator, unexpected stack for current"
+                else
+                    notStarted()
+
+            member i.MoveNext() =
+              if started then
+                match stack with
+#if ONE
+                  | MapOne _ :: rest -> 
+#else
+                  | (MapNode(_,_,MapEmpty,MapEmpty,_)) :: rest -> 
+#endif
+                      stack <- collapseLHS rest;
+                      not stack.IsEmpty
+                  | [] -> false
+                  | _ -> failwith "Please report error: Map iterator, unexpected stack for moveNext"
+              else
+                  // The first call to MoveNext "starts" the enumeration. 
+                  started <- true;  
+                  not stack.IsEmpty
+
+        let toSeq s = 
+            let i = ref (MapIterator(s))
+            { new IEnumerator<_> with 
+                  member self.Current = (!i).Current
+              interface System.Collections.IEnumerator with
+                  member self.Current = box (!i).Current
+                  member self.MoveNext() = (!i).MoveNext()
+                  member self.Reset() = i :=  MapIterator(s)
+              interface System.IDisposable with 
+                  member self.Dispose() = ()}
+
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+    [<System.Diagnostics.DebuggerDisplay ("Count = {Count}")>]
+#endif
+    [<Sealed>]
+    type Map<'Key,'T,'ComparerTag> when 'ComparerTag :> IComparer<'Key>( comparer: IComparer<'Key>, tree: MapTree<'Key,'T>) =
+
+        static let refresh (m:Map<_,_,'ComparerTag>) t =    Map<_,_,'ComparerTag>(comparer=m.ComparerUntyped, tree=t)
+
+        member s.Tree = tree
+        member s.ComparerUntyped : IComparer<'Key> = comparer
+        member s.Comparer = (comparer :?> 'ComparerTag)
+
+        static member Empty(comparer : 'ComparerTag) = Map<'Key,'T,'ComparerTag>(comparer=comparer, tree=MapTree.empty)
+        member m.Add(k,v) = refresh m (MapTree.add comparer k v tree)
+        member m.IsEmpty = MapTree.isEmpty tree
+        member m.Item with get(k : 'Key) = MapTree.find comparer k tree
+        member m.First(f) = MapTree.first f tree 
+        member m.Exists(f) = MapTree.exists f tree 
+        member m.Filter(f) = MapTree.filter comparer f tree |> refresh m 
+        member m.ForAll(f) = MapTree.forAll f tree 
+        member m.Fold f acc = MapTree.fold f tree acc
+        member m.FoldSection lo hi f acc = MapTree.foldSection comparer lo hi f tree acc 
+        member m.FoldAndMap f z  = 
+            let tree,z = MapTree.foldMap comparer f tree z MapTree.empty 
+            refresh m tree, z
+        member m.Iterate f = MapTree.iter f tree
+        member m.MapRange f  = refresh m (MapTree.map f tree)
+        member m.Map f  = refresh m (MapTree.mapi f tree)
+        member m.Partition(f)  =
+            let r1,r2 = MapTree.partition comparer f tree  
+            refresh m r1, refresh m r2
+        member m.Count = MapTree.count tree
+        member m.ContainsKey(k) = MapTree.containsKey comparer k tree
+        member m.Remove(k)  = refresh m (MapTree.remove comparer k tree)
+        member m.TryFind(k) = MapTree.tryFind comparer k tree
+        member m.ToList() = MapTree.toList tree
+        member m.ToArray() = MapTree.toArray tree
+
+        static member FromList(comparer : 'ComparerTag,l) : Map<'Key,'T,'ComparerTag> = 
+            Map<_,_,_>(comparer=comparer, tree=MapTree.ofList comparer l)
+
+        static member Create(comparer : 'ComparerTag, ie : seq<_>) : Map<'Key,'T,'ComparerTag> = 
+            Map<_,_,_>(comparer=comparer, tree=MapTree.ofSeq comparer ie)
+    
+        interface IEnumerable<KeyValuePair<'Key, 'T>> with
+            member s.GetEnumerator() = MapTree.toSeq tree
+
+        interface System.Collections.IEnumerable with
+            override s.GetEnumerator() = (MapTree.toSeq tree :> System.Collections.IEnumerator)
+
+        override this.Equals(that) = 
+            match that with
+            // Cast to the exact same type as this, otherwise not equal.
+            | :? Map<'Key,'T,'ComparerTag> as that -> ((this :> System.IComparable).CompareTo(that) = 0)
+            | _ -> false
+
+        interface System.IComparable with 
+             member m1.CompareTo(m2: obj) = 
+                 Seq.compareWith 
+                   (fun (kvp1 : KeyValuePair<_,_>) (kvp2 : KeyValuePair<_,_>)-> 
+                       let c = m1.ComparerUntyped.Compare(kvp1.Key,kvp2.Key) in 
+                       if c <> 0 then c else Unchecked.compare kvp1.Value kvp2.Value)
+                   // Cast m2 to the exact same type as m1, see 4884.
+                   // It is not OK to cast m2 to seq<KeyValuePair<'Key,'T>>, since different compares could permute the KVPs.
+                   m1 (m2 :?> Map<'Key,'T,'ComparerTag>)
+
+        member this.ComputeHashCode() = 
+            let combineHash x y = (x <<< 1) + y + 631 
+            let mutable res = 0
+            for KeyValue(x,y) in this do
+                res <- combineHash res (Unchecked.hash x)
+                res <- combineHash res (Unchecked.hash y)
+            abs res
+
+        override this.GetHashCode() = this.ComputeHashCode()
+
+
+    type Map<'Key,'T> = Map<'Key, 'T, IComparer<'Key>>    
+    type Set<'T> = Set<'T, IComparer<'T>>    
+
diff --git a/src/FSharp.PowerPack/TaggedCollections.fsi b/src/FSharp.PowerPack/TaggedCollections.fsi
new file mode 100755
index 0000000..0412389
--- /dev/null
+++ b/src/FSharp.PowerPack/TaggedCollections.fsi
@@ -0,0 +1,225 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+/// This namespace contains FSharp.PowerPack extensions for the F# collection types
+namespace Microsoft.FSharp.Collections.Tagged
+
+    open System
+    open System.Collections.Generic
+
+
+    /// Immutable sets based on binary trees, default tag
+
+    /// Immutable sets where a constraint tag carries information about the class of key-comparer being used.  
+    [<Sealed>]
+    type Set<'T,'ComparerTag> when 'ComparerTag :> IComparer<'T> =
+
+        /// Gets the comparer used for the set.
+        member Comparer : 'ComparerTag
+
+        /// A useful shortcut for Set.add.  Note this operation prodcues a new set
+        /// and does not mutate the original set.  The new set will share many storage
+        /// nodes with the original.  See the Set module for further operations on sets.
+        member Add : 'T -> Set<'T,'ComparerTag>
+        
+        /// A useful shortcut for Set.remove.  Note this operation produces a new set
+        /// and does not mutate the original set.  The new set will share many storage
+        /// nodes with the original.  See the Set module for further operations on sets.
+        member Remove : 'T -> Set<'T,'ComparerTag>
+        
+        /// Return the number of elements in the set
+        member Count : int
+        
+        /// A useful shortcut for Set.contains.  See the Set module for further operations on sets.
+        member Contains : 'T -> bool
+        
+        /// A useful shortcut for Set.isEmpty.  See the Set module for further operations on sets.
+        member IsEmpty  : bool
+
+        /// Apply the given function to each binding in the collection
+        member Iterate : ('T -> unit) -> unit
+
+        /// Apply the given accumulating function to all the elements of the set
+        member Fold    : ('T -> 'State -> 'State) -> 'State -> 'State
+
+        /// Build two new sets, one containing the elements for which the given predicate returns 'true',
+        /// and the other the remaining elements.
+        member Partition: predicate:('T -> bool) -> Set<'T,'ComparerTag> * Set<'T,'ComparerTag>
+
+        /// Return a new collection containing only the elements of the collection
+        /// for which the given predicate returns "true"
+        member Filter: predicate:('T -> bool) -> Set<'T,'ComparerTag> 
+
+        /// Test if any element of the collection satisfies the given predicate.
+        /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> then computes 
+        /// <c>p i0 or ... or p iN</c>.
+        member Exists: predicate:('T -> bool) -> bool
+
+        /// Test if all elements of the collection satisfy the given predicate.
+        /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> and <c>j0...jN</c> then 
+        /// computes <c>p i0 && ... && p iN</c>.
+        member ForAll: predicate:('T -> bool) -> bool
+
+        /// A set based on the given comparer containing the given initial elements
+        static member Create: 'ComparerTag * seq<'T> -> Set<'T,'ComparerTag> 
+        
+        /// The empty set based on the given comparer
+        static member Empty: 'ComparerTag -> Set<'T,'ComparerTag> 
+        
+        /// A singleton set based on the given comparison operator
+        static member Singleton: 'ComparerTag * 'T -> Set<'T,'ComparerTag> 
+        
+        /// Compares two sets and returns true if they are equal or false otherwise
+        static member Equality : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> bool
+        
+        /// Compares a and b and returns 1 if a > b, -1 if b < a and 0 if a = b        
+        static member Compare : a:Set<'T,'ComparerTag> * b:Set<'T,'ComparerTag> -> int
+
+        /// Return a new set with the elements of the second set removed from the first.
+        static member (-) : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
+
+        /// Compute the union of the two sets.
+        static member (+) : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
+
+        /// Compute the intersection of the two sets.
+        static member Intersection : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
+
+        /// Compute the union of the two sets.
+        static member Union : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag>
+
+        /// Return a new set with the elements of the second set removed from the first.
+        static member Difference: Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
+
+        /// The number of elements in the set
+        member Choose : 'T 
+
+        /// Returns the lowest element in the set according to the ordering being used for the set
+        member MinimumElement: 'T
+
+        /// Returns the highest element in the set according to the ordering being used for the set
+        member MaximumElement: 'T
+
+        /// Evaluates to "true" if all elements of the second set are in the first
+        member IsSubsetOf: Set<'T,'ComparerTag> -> bool
+
+        /// Evaluates to "true" if all elements of the first set are in the second
+        member IsSupersetOf: Set<'T,'ComparerTag> -> bool
+
+        /// The elements of the set as a list.
+        member ToList : unit -> 'T list
+        
+        /// The elements of the set as an array.
+        member ToArray: unit -> 'T array 
+
+        interface ICollection<'T> 
+        interface IEnumerable<'T> 
+        interface System.Collections.IEnumerable
+
+        interface System.IComparable
+        override Equals : obj -> bool
+
+    type Set<'T> = Set<'T, IComparer<'T>>    
+
+    /// Immutable maps.  Keys are ordered by construction function specified
+    /// when creating empty maps or by F# structural comparison if no
+    /// construction function is specified.
+    ///
+    /// <performance> 
+    ///   Maps based on structural comparison are  
+    ///   efficient for small keys. They are not a suitable choice if keys are recursive data structures 
+    ///   or require non-structural comparison semantics.
+    /// </performance>
+
+    /// Immutable maps.  A constraint tag carries information about the class of key-comparers being used.  
+    [<Sealed>]
+    type Map<'Key,'Value,'ComparerTag>  when 'ComparerTag :> IComparer<'Key> =
+        /// Return a new map with the binding added to the given map.
+        member Add: 'Key * 'Value -> Map<'Key,'Value,'ComparerTag>
+
+        /// Gets a value indicating whether there are no bindings in the map.
+        member IsEmpty: bool
+        
+        /// Gets the comparer used for the map.
+        member Comparer : 'ComparerTag
+
+        /// The empty map, and use the given comparer comparison function for all operations associated
+        /// with any maps built from this map.
+        static member Empty: 'ComparerTag -> Map<'Key,'Value,'ComparerTag>
+
+        static member FromList : 'ComparerTag * ('Key * 'Value) list -> Map<'Key,'Value,'ComparerTag>
+
+        /// Build a map that contains the bindings of the given IEnumerable
+        /// and where comparison of elements is based on the given comparison function
+        static member Create: 'ComparerTag * seq<'Key * 'Value> -> Map<'Key,'Value,'ComparerTag> 
+
+        /// Test is an element is in the domain of the map
+        member ContainsKey: 'Key -> bool
+
+        /// The number of bindings in the map
+        member Count: int
+
+        /// Lookup an element in the map. Raise <c>KeyNotFoundException</c> if no binding
+        /// exists in the map.
+        member Item : 'Key -> 'Value with get
+
+        /// Search the map looking for the first element where the given function returns a <c>Some</c> value
+        member First: ('Key -> 'Value -> 'T option) -> 'T option
+
+        /// Return true if the given predicate returns true for all of the
+        /// bindings in the map. Always returns true if the map is empty.
+        member ForAll: ('Key -> 'Value -> bool) -> bool
+
+        /// Return true if the given predicate returns true for one of the
+        /// bindings in the map. Always returns false if the map is empty.
+        member Exists: ('Key -> 'Value -> bool) -> bool
+
+        /// Build a new map containing the bindings for which the given predicate returns 'true'.
+        member Filter: ('Key -> 'Value -> bool) -> Map<'Key,'Value,'ComparerTag> 
+
+        /// Fold over the bindings in the map.  
+        member Fold: folder:('Key -> 'Value -> 'State -> 'State) -> 'State -> 'State
+
+        /// Given the start and end points of a key range,
+        /// Fold over the bindings in the map that are in the range,
+        /// and the end points are included if present (the range is considered a closed interval).
+        member FoldSection: 'Key -> 'Key -> ('Key -> 'Value -> 'State -> 'State) -> 'State -> 'State
+
+        /// Fold over the bindings in the map.  
+        member FoldAndMap: ('Key -> 'Value -> 'State -> 'T * 'State) -> 'State -> Map<'Key,'T,'ComparerTag> * 'State
+
+        /// Apply the given function to each binding in the dictionary
+        member Iterate: action:('Key -> 'Value -> unit) -> unit
+
+        /// Build a new collection whose elements are the results of applying the given function
+        /// to each of the elements of the collection. The index passed to the
+        /// function indicates the index of element being transformed.
+        member Map: mapping:('Key -> 'Value -> 'T) -> Map<'Key,'T,'ComparerTag>
+
+        /// Build a new collection whose elements are the results of applying the given function
+        /// to each of the elements of the collection.
+        member MapRange: mapping:('Value -> 'T) -> Map<'Key,'T,'ComparerTag>
+
+        /// Build two new maps, one containing the bindings for which the given predicate returns 'true',
+        /// and the other the remaining bindings.
+        member Partition: ('Key -> 'Value -> bool) -> Map<'Key,'Value,'ComparerTag> * Map<'Key,'Value,'ComparerTag>
+
+        /// Remove an element from the domain of the map.  No exception is raised if the element is not present.
+        member Remove: 'Key -> Map<'Key,'Value,'ComparerTag>
+
+        /// Lookup an element in the map, returning a <c>Some</c> value if the element is in the domain 
+        /// of the map and <c>None</c> if not.
+        member TryFind: 'Key -> 'Value option
+
+        /// The elements of the set as a list.
+        member ToList : unit -> ('Key * 'Value) list
+    
+        /// The elements of the set as an array
+        member ToArray: unit -> ('Key * 'Value) array 
+
+        interface IEnumerable<KeyValuePair<'Key, 'Value>>
+        
+        interface System.Collections.IEnumerable 
+        interface System.IComparable
+        override Equals : obj -> bool
+
+    type Map<'Key,'Value> = Map<'Key, 'Value, IComparer<'Key>>    
+
diff --git a/src/FSharp.PowerPack/TaggedHash.fs b/src/FSharp.PowerPack/TaggedHash.fs
new file mode 100755
index 0000000..bfb31cb
--- /dev/null
+++ b/src/FSharp.PowerPack/TaggedHash.fs
@@ -0,0 +1,59 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Collections.Tagged
+
+    #nowarn "51"
+
+    open System
+    open System.Collections.Generic
+    open Microsoft.FSharp.Collections
+    type UntaggedHashMultiMap<'Key,'Value> = Microsoft.FSharp.Collections.HashMultiMap<'Key,'Value>
+
+    type HashMultiMap<'Key,'Value,'HashTag>
+         when 'HashTag :> IEqualityComparer<'Key> =
+        { t : UntaggedHashMultiMap<'Key,'Value> }
+
+        static member Create(hasheq: 'HashTag,n:int)  : HashMultiMap<'Key,'Value,'HashTag> = 
+            { t = new UntaggedHashMultiMap<_,_>(n,hasheq) }
+
+        member x.Add(y,z) = x.t.Add(y,z)
+        member x.Clear() = x.t.Clear()
+        member x.Copy() : HashMultiMap<'Key,'Value,'HashTag>  = { t = x.t.Copy() }
+        member x.Item with get(y) = x.t.[y]
+                      and  set y z = x.t.[y] <- z
+        member x.FindAll(y) = x.t.FindAll(y) 
+        member x.Fold f acc =  x.t.Fold f acc
+        member x.Iterate(f) =  x.t.Iterate(f)
+        member x.Contains(y) = x.t.ContainsKey(y)
+        member x.ContainsKey(y) = x.t.ContainsKey(y)
+        member x.Remove(y) = x.t.Remove(y)
+        member x.Replace(y,z) = x.t.Replace(y,z)
+        member x.TryFind(y) = x.t.TryFind(y)
+        member x.Count = x.t.Count
+
+    type HashMultiMap<'Key,'Value> = HashMultiMap<'Key,'Value, IEqualityComparer<'Key>>    
+
+
+    [<Sealed>]
+    type HashSet<'T,'HashTag when 'T : equality> 
+         when 'HashTag :> IEqualityComparer<'T>(t:  HashSet<'T>) =
+
+        static member Create(hasheq: ('HashTag :> IEqualityComparer<'T>),size:int) : HashSet<'T,'HashTag> = 
+            new HashSet<'T,'HashTag>(HashSet<_>(size,hasheq))
+
+        member x.Add(y)    = t.Add(y)
+        member x.Clear() = t.Clear()
+        member x.Copy() = new HashSet<'T,'HashTag>(t.Copy())
+        member x.Fold f acc = t.Fold f acc
+        member x.Iterate(f) =  t.Iterate(f)
+        member x.Contains(y) = t.Contains(y)
+        member x.Remove(y) = t.Remove(y)
+        member x.Count = t.Count
+
+        interface IEnumerable<'T> with
+            member x.GetEnumerator() = (t :> seq<_>).GetEnumerator() 
+
+        interface System.Collections.IEnumerable with 
+            member x.GetEnumerator() = (t :> System.Collections.IEnumerable).GetEnumerator()  
+
+    type HashSet<'T when 'T : equality> = HashSet<'T, IEqualityComparer<'T>>    
diff --git a/src/FSharp.PowerPack/TaggedHash.fsi b/src/FSharp.PowerPack/TaggedHash.fsi
new file mode 100755
index 0000000..0ecff05
--- /dev/null
+++ b/src/FSharp.PowerPack/TaggedHash.fsi
@@ -0,0 +1,89 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Collections.Tagged
+
+    open System
+    open System.Collections.Generic
+
+    /// HashMultiMap, but where a constraint tag tracks information about the hash/equality functions used
+    /// for the hashing. When the tag is Tags.StructuralHash this is identical to HashMultiMap.
+    [<Sealed>]
+    type HashMultiMap<'Key,'Value,'HashTag> when 'HashTag :> IEqualityComparer<'Key> =
+        /// Create a new empty mutable hash table with an internal bucket array of the given approximate size
+        /// and with the given key hash/equality functions
+        static member Create: 'HashTag * int             -> HashMultiMap<'Key,'Value,'HashTag>
+
+        /// Make a shallow copy of the collection
+        member Copy    : unit    -> HashMultiMap<'Key,'Value,'HashTag>
+
+        /// Add a binding for the element to the table
+        member Add     : 'Key * 'Value -> unit
+
+        /// Clear all elements from the collection
+        member Clear   : unit    -> unit
+
+        /// Test if the collection contains any bindings for the given element
+        [<System.Obsolete("This member has been renamed to ContainsKey")>]
+        member Contains: 'Key      -> bool
+
+        /// Test if the collection contains any bindings for the given element
+        member ContainsKey: 'Key      -> bool
+
+        /// Remove the latest binding (if any) for the given element from the table
+        member Remove  : 'Key      -> unit
+
+        /// Replace the latest binding (if any) for the given element.
+        member Replace : 'Key * 'Value -> unit
+
+        /// Lookup or set the given element in the table.  Raise <c>KeyNotFoundException</c> if the element is not found.
+        member Item : 'Key -> 'Value with get,set
+
+        /// Lookup the given element in the table, returning the result as an Option
+        member TryFind : 'Key      -> 'Value option
+        /// Find all bindings for the given element in the table, if any
+        member FindAll : 'Key      -> 'Value list
+
+        /// Apply the given function to each element in the collection threading the accumulating parameter
+        /// through the sequence of function applications
+        member Fold    : ('Key -> 'Value -> 'c -> 'c) -> 'c -> 'c
+
+        /// The number of bindings in the hash table
+        member Count   : int
+
+        /// Apply the given function to each binding in the hash table 
+        member Iterate : ('Key -> 'Value -> unit) -> unit
+
+    type HashMultiMap<'Key,'Value> = HashMultiMap<'Key,'Value, IEqualityComparer<'Key>>    
+
+    /// Mutable hash sets where a constraint tag tracks information about the hash/equality functions used
+    /// for the hashing. When the tag is Tags.StructuralHash this is identical to HashSet.
+    [<Sealed>]
+    type HashSet<'T,'HashTag> when 'T : equality and 'HashTag :> IEqualityComparer<'T>  =
+        /// Create a new empty mutable hash set with an internal bucket array of the given approximate size
+        /// and with the given key hash/equality functions 
+        static member Create: 'HashTag * int             -> HashSet<'T,'HashTag>
+
+        /// Make a shallow copy of the set
+        member Copy    : unit -> HashSet<'T,'HashTag>
+        /// Add an element to the collection
+        member Add     : 'T   -> unit
+        /// Clear all elements from the set
+        member Clear   : unit -> unit
+        /// Test if the set contains the given element
+        member Contains: 'T   -> bool
+        /// Remove the given element from the set
+        member Remove  : 'T   -> unit
+        /// Apply the given function to the set threading the accumulating parameter
+        /// through the sequence of function applications
+        member Fold    : ('T -> 'State -> 'State) -> 'State -> 'State
+        
+        /// The number of elements in the set
+        member Count   : int
+
+        /// Apply the given function to each binding in the hash table 
+        member Iterate : ('T -> unit) -> unit
+
+        interface IEnumerable<'T> 
+        interface System.Collections.IEnumerable 
+
+    type HashSet<'T when 'T : equality> = HashSet<'T, IEqualityComparer<'T>>    
diff --git a/src/FSharp.PowerPack/math/INumeric.fs b/src/FSharp.PowerPack/math/INumeric.fs
new file mode 100755
index 0000000..b60ef82
--- /dev/null
+++ b/src/FSharp.PowerPack/math/INumeric.fs
@@ -0,0 +1,241 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Math
+
+open Microsoft.FSharp.Math
+open System
+open System.Numerics
+open System.Globalization
+
+type INumeric<'T> =
+    abstract Zero: 'T
+    abstract One: 'T
+    abstract Add: 'T * 'T -> 'T
+    abstract Subtract: 'T * 'T -> 'T
+    abstract Multiply : 'T * 'T -> 'T
+    abstract Compare : 'T * 'T -> int
+    abstract Equals : 'T * 'T -> bool
+    abstract Negate : 'T -> 'T
+    abstract Sign : 'T -> int
+    abstract Abs : 'T -> 'T
+    abstract ToString : 'T * string * System.IFormatProvider -> string
+    abstract Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -> 'T
+
+type IIntegral<'T> =
+    inherit INumeric<'T>
+    abstract Modulus: 'T * 'T -> 'T
+    abstract Divide : 'T * 'T -> 'T
+    abstract DivRem : 'T * 'T -> 'T * 'T
+    abstract ToBigInt : 'T -> BigInteger
+    abstract OfBigInt : BigInteger -> 'T
+  
+type IFractional<'T> =
+    inherit INumeric<'T>
+    abstract Reciprocal : 'T -> 'T
+    abstract Divide : 'T * 'T -> 'T
+
+type IFloating<'T> =
+    inherit IFractional<'T>
+    abstract Pi : 'T
+    abstract Exp : 'T -> 'T
+    abstract Log : 'T -> 'T
+    abstract Sqrt : 'T -> 'T
+    abstract LogN : 'T * 'T -> 'T
+    abstract Sin : 'T -> 'T
+    abstract Cos : 'T -> 'T
+    abstract Tan : 'T -> 'T
+    abstract Asin : 'T -> 'T
+    abstract Acos : 'T -> 'T
+    abstract Atan : 'T -> 'T
+    abstract Atan2 : 'T * 'T -> 'T
+    abstract Sinh : 'T -> 'T
+    abstract Cosh : 'T -> 'T
+    abstract Tanh : 'T -> 'T
+
+type IIEEE<'T> =
+    inherit IFloating<'T>
+    abstract PositiveInfinity : 'T
+    abstract NegativeInfinity : 'T
+    abstract NaN              : 'T
+    abstract EpsilonOne          : 'T
+    abstract IsNaN: 'T -> bool 
+    abstract IsInfinite : 'T -> bool 
+
+type INormFloat<'T> =
+    abstract Norm : 'T -> float
+ 
+module Instances = 
+  let Int32Numerics = 
+    { new IIntegral<int32> with 
+         member __.Zero = 0
+         member __.One = 1
+         member __.Add(a,b) = a + b
+         member __.Subtract(a,b) = a - b
+         member __.Multiply(a,b) = a * b
+         member __.Equals(a,b) = (a = b)
+         member __.Compare(a,b) = compare a b
+         member __.Negate(a) = - a 
+         member __.Abs(a) = a
+         member __.ToBigInt(a) = new BigInteger(a)
+         member __.OfBigInt(a) = int32 a
+         member __.Sign(a) = Math.Sign(a)
+         member __.Modulus(a,b) = a % b
+         member __.Divide(a,b) = a / b
+         member __.DivRem(a,b) = (a / b, a % b)
+         member __.ToString((x:int32),fmt,fmtprovider) = 
+                x.ToString(fmt,fmtprovider) 
+         member __.Parse(s,numstyle,fmtprovider) = 
+                System.Int32.Parse(s,numstyle,fmtprovider)
+      interface INormFloat<int32> with  
+         member __.Norm(x) = float (abs x)
+    }
+  let Int64Numerics = 
+    { new IIntegral<int64> with 
+         member __.Zero =0L
+         member __.One = 1L
+         member __.Add(a,b) = a + b
+         member __.Subtract(a,b) = a - b
+         member __.Multiply(a,b) = a * b
+         member __.Negate(a) = - a 
+         member __.Abs(a) = Math.Abs(a)
+         member __.ToBigInt(a) = new BigInteger(a)
+         member __.OfBigInt(a) = int64 a
+         member __.Sign(a) = Math.Sign(a)
+         member __.Modulus(a,b) = a % b
+         member __.Equals(a,b) = (a = b)
+         member __.Compare(a,b) = compare a b
+         member __.Divide(a,b) = a / b
+         member __.DivRem(a,b) = (a / b, a % b)
+         member __.ToString((x:int64),fmt,fmtprovider) = x.ToString(fmt,fmtprovider) 
+         member __.Parse(s,numstyle,fmtprovider) = System.Int64.Parse(s,numstyle,fmtprovider)
+      interface INormFloat<int64> with
+         member __.Norm(x) = float (Math.Abs x)
+    }
+  let FloatNumerics = 
+    { new IIEEE<float> with 
+         member __.Zero = 0.0
+         member __.One =  1.0
+         member __.Add(a,b) =  a + b
+         member __.Subtract(a,b) = a - b
+         member __.Multiply(a,b) = a * b
+         member __.Equals(a,b) = (a = b)
+         member __.Compare(a,b) = compare a b
+         member __.PositiveInfinity = Double.PositiveInfinity
+         member __.NegativeInfinity = Double.NegativeInfinity
+         member __.NaN = Double.NaN
+         member __.EpsilonOne = 0x3CB0000000000000LF
+         member __.IsInfinite(a) = Double.IsInfinity(a)
+         member __.IsNaN(a) = Double.IsNaN(a)
+         member __.Pi = Math.PI
+         member __.Reciprocal(a) = 1.0/a
+         member __.Abs(a) = Math.Abs(a)
+         member __.Sign(a) = Math.Sign(a)
+         member __.Asin(a) = Math.Asin(a)
+         member __.Acos(a) = Math.Acos(a)
+         member __.Atan(a) = Math.Atan(a)
+         member __.Atan2(a,b) = Math.Atan2(a,b)
+         member __.Tanh(a) = Math.Tanh(a)
+         member __.Tan(a) = Math.Tan(a)
+         member __.Sqrt(a) = Math.Sqrt(a)
+         member __.Sinh(a) = Math.Sinh(a)
+         member __.Cosh(a) = Math.Cosh(a)
+         member __.Sin(a) = Math.Sin(a)
+         member __.Cos(a) = Math.Cos(a)
+         member __.LogN(a,n) = 
+#if FX_NO_LOGN
+             raise (System.NotSupportedException("this operation is not supported on this platform"))
+#else
+             Math.Log(a,n)
+#endif
+         member __.Log(a) = Math.Log(a)
+         member __.Exp(a) = Math.Exp(a)
+         member __.Negate(a) = -a 
+         member __.Divide(a,b) = a / b
+         member __.ToString((x:float),fmt,fmtprovider) = x.ToString(fmt,fmtprovider) 
+         member __.Parse(s,numstyle,fmtprovider) = System.Double.Parse(s,numstyle,fmtprovider)
+      interface INormFloat<float> with
+          member __.Norm(x) = float (Math.Abs x)
+    }
+  let Float32Numerics = 
+    { new IFractional<float32> with
+           member __.Zero = 0.0f
+           member __.One =  1.0f
+           member __.Add(a,b) = a + b
+           member __.Subtract(a,b) = a - b
+           member __.Multiply(a,b) = a * b
+           member __.Equals(a,b) = (a = b)
+           member __.Compare(a,b) = compare a b
+           member __.Negate(a) = -a 
+           member __.Reciprocal(a) = 1.0f/a
+           member __.Sign(a) = Math.Sign(a)
+           member __.Abs(a) = Math.Abs(a)
+           member __.Divide(a,b) = a / b
+           member __.ToString((x:float32),fmt,fmtprovider) = x.ToString(fmt,fmtprovider) 
+           member __.Parse(s,numstyle,fmtprovider) = System.Single.Parse(s,numstyle,fmtprovider)
+       interface INormFloat<float32> with  
+           member __.Norm(x) = float (Math.Abs x)
+    }
+
+  let BigRationalNumerics = 
+    { new IFractional<bignum> with 
+         member __.Zero = BigRational.Zero
+         member __.One = BigRational.One
+         member __.Add(a,b)      = a + b
+         member __.Subtract(a,b) = a - b
+         member __.Multiply(a,b) = a * b
+         member __.Equals(a,b) = (a = b)
+         member __.Compare(a,b) = compare a b
+         member __.Divide(a,b)   = a / b
+         member __.Abs(a) = BigRational.Abs a
+         member __.Sign(a) = a.Sign
+         member __.Negate(a) = - a 
+         member __.Reciprocal(a) = BigRational.One / a 
+         // Note, this ignores fmt, fmtprovider
+         member __.ToString((x:bignum),fmt,fmtprovider) = x.ToString()
+         // Note, this ignroes numstyle, fmtprovider
+         member __.Parse(s,numstyle,fmtprovider) = BigRational.Parse(s)
+
+      interface INormFloat<bignum> with
+         member __.Norm(x) = float (BigRational.Abs x)
+    }       
+
+  let BigIntNumerics = 
+    let ZeroI = new BigInteger(0)
+    { new IIntegral<_> with 
+         member __.Zero = BigInteger.Zero
+         member __.One =  BigInteger.One
+         member __.Add(a,b) = a + b
+         member __.Subtract(a,b) = a - b
+         member __.Multiply(a,b) = a * b
+         member __.Equals(a,b) = (a = b)
+         member __.Compare(a,b) = compare a b
+         member __.Divide(a,b) = a / b
+         member __.Negate(a) = -a 
+         member __.Modulus(a,b) = a % b
+         member __.DivRem(a,b) = 
+            let mutable r = new BigInteger(0)
+            (BigInteger.DivRem (a,b,&r),r)
+         member __.Sign(a) = a.Sign
+         member __.Abs(a) = abs a
+         member __.ToBigInt(a) = a 
+         member __.OfBigInt(a) = a 
+         
+         member __.ToString(x,fmt,fmtprovider) = 
+#if FX_ATLEAST_40
+             x.ToString(fmt,fmtprovider) 
+#else
+             // Note: this ignores fmt and fmtprovider
+             x.ToString() 
+#endif
+         // Note: this ignores fmt and fmtprovider
+         member __.Parse(s,numstyle,fmtprovider) = 
+#if FX_ATLEAST_40
+             BigInteger.Parse(s,numstyle,fmtprovider)
+#else
+             BigInteger.Parse(s)
+#endif
+
+      interface INormFloat<BigInteger> with  
+         member __.Norm(x) = float (abs x)
+    }       
+
diff --git a/src/FSharp.PowerPack/math/INumeric.fsi b/src/FSharp.PowerPack/math/INumeric.fsi
new file mode 100755
index 0000000..11307df
--- /dev/null
+++ b/src/FSharp.PowerPack/math/INumeric.fsi
@@ -0,0 +1,82 @@
+// (c) Microsoft Corporation 2005-2009. 
+namespace Microsoft.FSharp.Math
+
+open Microsoft.FSharp.Math
+open System.Numerics
+open System
+
+// A type-class for numeric types
+type INumeric<'T> =
+    abstract Zero: 'T
+    abstract One: 'T
+    abstract Add: 'T * 'T -> 'T
+    abstract Equals : 'T * 'T -> bool
+    abstract Compare : 'T * 'T -> int
+    abstract Subtract: 'T * 'T -> 'T
+    abstract Multiply : 'T * 'T -> 'T
+    abstract Negate : 'T -> 'T
+    abstract Sign : 'T -> int
+    abstract Abs : 'T -> 'T    
+    abstract ToString : 'T * string * System.IFormatProvider -> string
+    abstract Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -> 'T
+
+type IIntegral<'T> =
+    inherit INumeric<'T>
+    abstract Modulus: 'T * 'T -> 'T
+    abstract Divide : 'T * 'T -> 'T
+    abstract DivRem : 'T * 'T -> 'T * 'T
+    abstract ToBigInt : 'T -> BigInteger
+    abstract OfBigInt : BigInteger -> 'T
+  
+type IFractional<'T> =
+    inherit INumeric<'T>
+    abstract Reciprocal : 'T -> 'T
+    abstract Divide : 'T * 'T -> 'T
+
+// Suggestion: IReal (since transcendentals are added here).
+type IFloating<'T> =
+    inherit IFractional<'T>
+    abstract Pi : 'T
+    abstract Exp : 'T -> 'T
+    abstract Log : 'T -> 'T
+    abstract Sqrt : 'T -> 'T
+    abstract LogN : 'T * 'T -> 'T
+    abstract Sin : 'T -> 'T
+    abstract Cos : 'T -> 'T
+    abstract Tan : 'T -> 'T
+    abstract Asin : 'T -> 'T
+    abstract Acos : 'T -> 'T
+    abstract Atan : 'T -> 'T
+    abstract Atan2 : 'T * 'T -> 'T
+    abstract Sinh : 'T -> 'T
+    abstract Cosh : 'T -> 'T
+    abstract Tanh : 'T -> 'T
+
+type INormFloat<'T> =
+    abstract Norm : 'T -> float
+  
+// Direct access to IEEE encoding not easy on .NET
+type IIEEE<'T> =
+    inherit IFloating<'T>
+    abstract PositiveInfinity : 'T
+    abstract NegativeInfinity : 'T
+    abstract NaN              : 'T
+    abstract EpsilonOne       : 'T
+
+    abstract IsNaN: 'T -> bool 
+    abstract IsInfinite : 'T -> bool 
+    //abstract IsDenormalized   : 'T -> bool 
+    //abstract IsNegativeZero   : 'T -> bool 
+    //abstract IsIEEE           : 'T -> bool 
+
+
+module Instances =
+    val Float32Numerics  : IFractional<float32> 
+    val FloatNumerics    : IIEEE<float>
+    val Int32Numerics    : IIntegral<int32>
+    val Int64Numerics    : IIntegral<int64>
+    val BigIntNumerics   : IIntegral<BigInteger>
+    val BigRationalNumerics   : IFractional<bignum>  
+
+
+
diff --git a/src/FSharp.PowerPack/math/NativeArrayExtensions.fs b/src/FSharp.PowerPack/math/NativeArrayExtensions.fs
new file mode 100755
index 0000000..858ba84
--- /dev/null
+++ b/src/FSharp.PowerPack/math/NativeArrayExtensions.fs
@@ -0,0 +1,51 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.NativeInterop
+
+#nowarn "44"
+#nowarn "9" // unverifiable constructs
+#nowarn "51" // unverifiable constructs
+
+open System
+open System.Runtime.InteropServices
+open Microsoft.FSharp.NativeInterop
+open Microsoft.FSharp.Math
+
+[<AutoOpen>]
+module NativArrayExtensionsForMatrix =
+
+    [<NoDynamicInvocation>]
+    let inline pinObjUnscoped (obj: obj) =  GCHandle.Alloc(obj,GCHandleType.Pinned) 
+    [<NoDynamicInvocation>]
+    let inline pinObj (obj: obj) f = 
+        let gch = pinObjUnscoped obj 
+        try f gch
+        finally
+            gch.Free()
+
+    type Microsoft.FSharp.NativeInterop.PinnedArray<'T when 'T : unmanaged> with
+
+        [<NoDynamicInvocation>]
+        static member inline of_vector(m:Vector<'T>) = 
+            let gch = pinObjUnscoped (box m.InternalValues) 
+            let ptr = &&m.InternalValues.[0]
+            new PinnedArray<'T>(new NativeArray<_>(ptr,m.Length),gch)
+
+        [<NoDynamicInvocation>]
+        static member inline of_rowvec(m:RowVector<'T>) = 
+            let gch = pinObjUnscoped (box m.InternalValues) 
+            let ptr = &&m.InternalValues.[0]
+            new PinnedArray<'T>(new NativeArray<_>(ptr,m.Length),gch)
+            
+
+    type Microsoft.FSharp.NativeInterop.PinnedArray2<'T when 'T : unmanaged> with
+
+        [<NoDynamicInvocation>]
+        static member inline of_matrix(m:Matrix<'T>) = 
+            if m.IsDense then
+                let gch = pinObjUnscoped (box m.InternalDenseValues) 
+                let ptr = && m.InternalDenseValues.[0,0]
+                new PinnedArray2<'T>(new NativeArray2<_>(ptr,m.NumRows,m.NumCols),gch) 
+            else
+                invalidArg "m" "cannot pin sparse matrices"
+            
diff --git a/src/FSharp.PowerPack/math/NativeArrayExtensions.fsi b/src/FSharp.PowerPack/math/NativeArrayExtensions.fsi
new file mode 100755
index 0000000..697fc0f
--- /dev/null
+++ b/src/FSharp.PowerPack/math/NativeArrayExtensions.fsi
@@ -0,0 +1,27 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.NativeInterop
+
+open Microsoft.FSharp.Math
+open System.Runtime.InteropServices
+
+[<AutoOpen>]
+module NativArrayExtensionsForMatrix =
+
+    type Microsoft.FSharp.NativeInterop.PinnedArray<'T when 'T : unmanaged> with
+
+        /// For native interop. Pin the given object
+        [<NoDynamicInvocation>]
+        static member inline of_vector : Vector<'T> -> PinnedArray<'T>
+
+        /// For native interop. Pin the given object
+        [<NoDynamicInvocation>]
+        static member inline of_rowvec : RowVector<'T> -> PinnedArray<'T>
+
+
+    type Microsoft.FSharp.NativeInterop.PinnedArray2<'T when 'T : unmanaged> with
+
+        /// For native interop. Pin the given object
+        [<NoDynamicInvocation>]
+        static member inline of_matrix : Matrix<'T> -> PinnedArray2<'T>
+
diff --git a/src/FSharp.PowerPack/math/associations.fs b/src/FSharp.PowerPack/math/associations.fs
new file mode 100755
index 0000000..46af9b5
--- /dev/null
+++ b/src/FSharp.PowerPack/math/associations.fs
@@ -0,0 +1,61 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+module GlobalAssociations =
+
+    open Microsoft.FSharp.Math
+    open Microsoft.FSharp.Math.Instances
+    open System
+    open System.Numerics
+
+    let ComplexNumerics = 
+      { new IFractional<_> with 
+          member __.Zero = Microsoft.FSharp.Math.Complex.Zero
+          member __.One = Microsoft.FSharp.Math.Complex.One
+          member __.Add(a,b) = a + b
+          member __.Subtract(a,b) = a - b
+          member __.Multiply(a,b) = a * b
+          member __.Equals(a,b) = (a = b)
+          member __.Compare(a,b) = compare a b
+          member __.Divide(a,b) = a / b
+          member __.Negate(a) = -a
+          member __.Abs(a)  = a // not signed
+          member __.Sign(a) = 1 // not signed
+          member __.Reciprocal(a) =  Microsoft.FSharp.Math.Complex.One / a 
+          member __.ToString((x:Microsoft.FSharp.Math.Complex),fmt,fmtprovider) = x.ToString(fmt,fmtprovider)
+          member __.Parse(s,numstyle,fmtprovider) = Microsoft.FSharp.Math.Complex.mkRect (System.Double.Parse(s,numstyle,fmtprovider),0.0) }
+
+    let ht = 
+        let ht = new System.Collections.Generic.Dictionary<Type,obj>() 
+        let optab =
+            [ typeof<float>,   (Some(FloatNumerics    :> INumeric<float>) :> obj);
+              typeof<int32>,   (Some(Int32Numerics    :> INumeric<int32>) :> obj);
+              typeof<int64>,   (Some(Int64Numerics    :> INumeric<int64>) :> obj);
+              typeof<BigInteger>,  (Some(BigIntNumerics   :> INumeric<BigInteger>) :> obj);
+              typeof<float32>, (Some(Float32Numerics  :> INumeric<float32>) :> obj);
+              typeof<Microsoft.FSharp.Math.Complex>, (Some(ComplexNumerics :> INumeric<Microsoft.FSharp.Math.Complex>) :> obj);
+              typeof<bignum>,  (Some(BigRationalNumerics   :> INumeric<bignum>) :> obj); ]
+           
+        List.iter (fun (ty,ops) -> ht.Add(ty,ops)) optab;
+        ht
+        
+    let Put (ty: System.Type, d : obj)  =
+        lock ht (fun () -> 
+            if ht.ContainsKey(ty) then invalidArg "ty" ("the type "+ty.Name+" already has a registered numeric association");
+            ht.Add(ty, d))
+      
+    let TryGetNumericAssociation<'a>() = 
+        lock ht (fun () -> 
+            let ty = typeof<'a>  
+            if ht.ContainsKey(ty) then
+                match ht.[ty] with
+                | :? (INumeric<'a> option) as r -> r
+                | _ -> invalidArg "ty" ("The type "+ty.Name+" has a numeric association but it was not of the correct type")
+            else
+                None)
+
+    let GetNumericAssociation() = (TryGetNumericAssociation()).Value
+    let RegisterNumericAssociation (d : INumeric<'a>)  = Put(typeof<'a>, box(Some d))
+
+
diff --git a/src/FSharp.PowerPack/math/associations.fsi b/src/FSharp.PowerPack/math/associations.fsi
new file mode 100755
index 0000000..738a888
--- /dev/null
+++ b/src/FSharp.PowerPack/math/associations.fsi
@@ -0,0 +1,28 @@
+// (c) Microsoft Corporation 2005-2009. 
+namespace Microsoft.FSharp.Math
+
+/// Associations are a way of associating dictionaries of
+/// operations with given types at runtime.  Associations are global to a 
+/// .NET application domain.  Once specified an association may not be deleted
+/// or modified.
+///
+/// In this release the system of associations is simply 
+/// limited to a registry of types that support dictionaries (i.e. interface objects)
+/// of numeric operations.  The following types are pre-registered with associated numeric
+/// operations: float, int32, int64, bigint, float32, Complex, bignum.  Other types must be
+/// registered explicitly by user code.
+///
+module GlobalAssociations =
+
+    open Microsoft.FSharp.Math
+
+    /// Attempt to determine a numeric association for the given type, i.e. a registered dictionary of
+    /// numeric operations.  The interface can be queried dynamically for additional functionality in the numerics
+    /// hierarchy.
+    val GetNumericAssociation : unit -> INumeric<'a> 
+
+    val TryGetNumericAssociation : unit -> INumeric<'a>  option
+    /// Record an AppDomain-wide association between the given type and the given dictionary of
+    /// numeric operations.  Raise an error if an existing association already exists. 
+    val RegisterNumericAssociation : INumeric<'a> -> unit
+
diff --git a/src/FSharp.PowerPack/math/complex.fs b/src/FSharp.PowerPack/math/complex.fs
new file mode 100755
index 0000000..10b859e
--- /dev/null
+++ b/src/FSharp.PowerPack/math/complex.fs
@@ -0,0 +1,130 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+#nowarn "52" // defensive copy of structs warning
+
+namespace Microsoft.FSharp.Math
+
+    open Microsoft.FSharp.Math
+    open System
+    open System.Globalization
+
+    [<Struct>]
+    [<CustomEquality; CustomComparison>]
+    type Complex(real: float, imaginary: float) =
+        //new() = new Complex(0.0,0.0)
+        member x.r = real
+        member x.i = imaginary
+        override x.ToString() = x.ToString("g")
+        member x.ToString(fmt) = x.ToString(fmt,CultureInfo.InvariantCulture)
+        member x.ToString(fmt,fmtprovider:IFormatProvider) = 
+               x.r.ToString(fmt,fmtprovider)+"r"+(if x.i < 0.0 then "-" else "+")+(System.Math.Abs x.i).ToString(fmt,fmtprovider)+"i"
+        interface IComparable with 
+            member x.CompareTo(obj) = 
+                match obj with 
+                | :? Complex as y -> 
+                     let c = compare x.r y.r
+                     if c <> 0 then c else compare x.i y.i
+                | _ -> invalidArg "obj" "not a Complex number"
+        override x.Equals(obj) = 
+                match obj with 
+                | :? Complex as y -> x.r = y.r && x.i = y.i
+                | _ -> false
+        override x.GetHashCode() = 
+                (hash x.r >>> 5) ^^^  (hash x.r <<< 3) ^^^  (((hash x.i >>> 4) ^^^  (hash x.i <<< 4)) + 0x9e3779b9)
+
+                
+    type complex = Complex
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Complex = 
+      let mkRect(a,b) = new Complex(a,b)
+      let conjugate (c:complex) = mkRect (c.r, -c.i)
+      let mkPolar(a,b) = mkRect (a * Math.Cos(b), a * Math.Sin(b))
+      let cis b = mkPolar(1.0,b)
+      let zero = mkRect(0.,0.)
+      let one = mkRect(1.,0.) 
+      let onei = mkRect(0.,1.) 
+      let magnitude (c:complex) = sqrt(c.r*c.r + c.i*c.i)
+      let phase (c:complex) = Math.Atan2(c.i,c.r)
+      let realPart (c:complex) = c.r
+      let imagPart (c:complex) = c.i  
+      let abs (a:complex) = sqrt (a.r**2.0 + a.i**2.0)
+      let add (a:complex) (b:complex) = mkRect(a.r + b.r, a.i+b.i)
+      let sub (a:complex) (b:complex) = mkRect(a.r - b.r, a.i-b.i)
+      let mul (a:complex) (b:complex) = mkRect(a.r * b.r - a.i * b.i, a.i*b.r + b.i*a.r)
+      let div (x:complex) (y:complex) = 
+          let a = x.r in let b = x.i in 
+          let c = y.r in let d = y.i in 
+          //(a+ib)/(c+id)=(ac+bd+i(bc-ad))/(c2+d2) 
+          let q = c*c + d*d in 
+          mkRect((a*c+b*d)/q, (b*c - a*d)/q)
+      let neg (a:complex) = mkRect(-a.r,-a.i)
+      let smul (a:float)(b:complex) = mkRect(a * b.r, a*b.i)
+      let muls (a:complex) (b:float) = mkRect(a.r *b, a.i*b)
+      let fmt_of_string numstyle fmtprovider (s:string) =
+        mkRect (System.Double.Parse(s,numstyle,fmtprovider),0.0) 
+      let of_string s = fmt_of_string NumberStyles.Any CultureInfo.InvariantCulture s
+
+      // ik.(r + i.th) = -k.th + i.k.r 
+      let iscale k (x:complex) = mkRect (-k * x.i , k * x.r)
+
+      // LogN : 'a * 'a -> 'a
+      // Asin : 'a -> 'a
+      // Acos : 'a -> 'a
+      // Atan : 'a -> 'a
+      // Atan2 : 'a * 'a -> 'a
+      // Sinh : 'a -> 'a
+      // Cosh : 'a -> 'a
+      // Tanh : 'a -> 'a
+
+      let pi    = mkRect (Math.PI,0.0)
+
+      // exp(r+it) = exp(r).(cos(t)+i.sin(t)) - De Moivre Theorem 
+      let exp (x:complex) = smul (exp(x.r)) (mkRect(cos(x.i), sin(x.i)))
+      // x = mag.e^(i.th) = e^ln(mag).e^(i.th) = e^(ln(mag) + i.th) 
+      let log x = mkRect (log(magnitude(x)),phase(x))
+
+      let sqrt x = mkPolar (sqrt(magnitude x),phase x / 2.0)
+
+      // cos(x) = (exp(i.x) + exp(-i.x))/2 
+      let cos x = smul 0.5 (add (exp(iscale 1.0 x)) (exp(iscale -1.0 x)))
+      // sin(x) = (exp(i.x) - exp(-i.x))/2 . (-i) 
+      let sin x = smul 0.5 (sub (exp(iscale 1.0 x)) (exp(iscale -1.0 x))) |> iscale (-1.0)
+      // tan(x) = (exp(i.x) - exp(-i.x)) . (-i) / (exp(i.x) + exp(-i.x)) 
+      //        = (exp(2i.x) - 1.0)      . (-i) / (exp(2i.x) + 1.0)      
+      let tan x = let exp2ix = exp(iscale 2.0 x) in
+                  (div (sub exp2ix one) (add exp2ix one)) |> iscale -1.0
+
+
+    type Complex with 
+        static member Create(a,b) = Complex.mkRect (a,b)
+        static member CreatePolar(a,b) = Complex.mkPolar (a,b)
+        member x.Magnitude = Complex.magnitude x
+        member x.Phase = Complex.phase x
+        member x.RealPart = x.r
+        member x.ImaginaryPart = x.i
+        member x.Conjugate = Complex.conjugate x
+
+        static member Sin(x) = Complex.sin(x)
+        static member Cos(x) = Complex.cos(x)
+        static member Abs(x) = Complex.abs(x)
+        static member Tan(x) = Complex.tan(x)
+        static member Log(x) = Complex.log(x)
+        static member Exp(x) = Complex.exp(x)
+        static member Sqrt(x) = Complex.sqrt(x)
+        
+        static member Zero = Complex.zero
+        static member One = Complex.one 
+        static member OneI = Complex.onei 
+        static member ( +  ) (a,b) = Complex.add a b
+        static member ( -  ) (a,b) = Complex.sub a b
+        static member ( *  ) (a,b) = Complex.mul a b
+        static member ( /  ) (a,b) = Complex.div a b
+        static member ( ~- ) a = Complex.neg a
+        static member ( * ) (a,b) = Complex.smul a b
+        static member ( * ) (a,b) = Complex.muls a b
+
+
+    module ComplexTopLevelOperators = 
+        let complex x y = Complex.mkRect (x,y)
+
diff --git a/src/FSharp.PowerPack/math/complex.fsi b/src/FSharp.PowerPack/math/complex.fsi
new file mode 100755
index 0000000..78b31db
--- /dev/null
+++ b/src/FSharp.PowerPack/math/complex.fsi
@@ -0,0 +1,136 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+    open System
+      
+    /// The type of complex numbers stored as pairs of 64-bit floating point numbers in rectangular coordinates
+    [<Struct>]
+    [<CustomEquality; CustomComparison>]
+    type Complex = 
+        /// The real part of a complex number
+        member r: float
+        /// The imaginary part of a complex number
+        member i: float
+        /// The polar-coordinate magnitude of a complex number
+        member Magnitude: float
+        /// The polar-coordinate phase of a complex number
+        member Phase: float
+        /// The real part of a complex number
+        member RealPart: float
+        /// The imaginary part of a complex number
+        member ImaginaryPart: float
+        /// The conjugate of a complex number, i.e. x-yi
+        member Conjugate: Complex
+        /// Create a complex number x+ij using rectangular coordinates
+        static member Create      : float * float -> Complex
+        /// Create a complex number using magnitude/phase polar coordinates
+        static member CreatePolar : float * float -> Complex
+        /// The complex number 0+0i
+        static member Zero   : Complex
+        /// The complex number 1+0i
+        static member One    : Complex
+        /// The complex number 0+1i
+        static member OneI   : Complex
+        /// Add two complex numbers
+        static member ( +  ) : Complex * Complex -> Complex
+        /// Subtract one complex number from another
+        static member ( -  ) : Complex * Complex -> Complex
+        /// Multiply two complex numbers
+        static member ( *  ) : Complex * Complex -> Complex
+        /// Complex division of two complex numbers
+        static member ( /  ) : Complex * Complex -> Complex
+        /// Unary negation of a complex number
+        static member ( ~- ) : Complex           -> Complex
+        /// Multiply a scalar by a complex number 
+        static member ( * ) : float   * Complex -> Complex
+        /// Multiply a complex number by a scalar
+        static member ( * ) : Complex * float   -> Complex
+
+        static member Sin : Complex -> Complex
+        static member Cos : Complex -> Complex
+        
+        /// Computes the absolute value of a complex number: e.g. Abs x+iy = sqrt(x**2.0 + y**2.0.)
+        /// Note: Complex.Abs(z) is the same as z.Magnitude
+        static member Abs : Complex -> float
+        static member Tan : Complex -> Complex
+        static member Log : Complex -> Complex
+        static member Exp : Complex -> Complex
+        static member Sqrt : Complex -> Complex
+        
+        override ToString : unit -> string
+        override Equals : obj -> bool
+        interface System.IComparable
+        member ToString : format:string -> string
+        member ToString : format:string * provider:System.IFormatProvider -> string
+
+    /// The type of complex numbers 
+    type complex = Complex
+
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    [<RequireQualifiedAccess>]
+    module Complex =
+
+        val mkRect: float * float -> complex
+
+          /// The polar-coordinate magnitude of a complex number
+        val magnitude: complex -> float
+          /// The polar-coordinate phase of a complex number
+        val phase     : complex -> float
+          /// The real part of a complex number
+        val realPart  : complex -> float
+          /// The imaginary part of a complex number
+        val imagPart  : complex -> float
+          /// Create a complex number using magnitude/phase polar coordinates
+        val mkPolar : float * float -> complex
+        /// A complex of magnitude 1 and the given phase and , i.e. cis x = mkPolar 1.0 x
+        val cis     : float -> complex
+        
+          /// The conjugate of a complex number, i.e. x-yi
+        val conjugate : complex -> complex
+
+          /// The complex number 0+0i
+        val zero    : complex
+          /// The complex number 1+0i
+        val one     : complex
+          /// The complex number 0+1i
+        val onei    : complex
+          /// Add two complex numbers
+        val add     : complex -> complex -> complex
+          /// Subtract one complex number from another
+        val sub     : complex -> complex -> complex
+          /// Multiply two complex numbers
+        val mul     : complex -> complex -> complex
+          /// Complex division of two complex numbers
+        val div     : complex -> complex -> complex
+          /// Unary negation of a complex number
+        val neg     : complex -> complex
+          /// Multiply a scalar by a complex number 
+        val smul    : float -> complex -> complex
+          /// Multiply a complex number by a scalar
+        val muls    : complex -> float -> complex
+
+          /// pi
+        val pi  : Complex
+          /// exp(x) = e^x
+        val exp : Complex -> Complex
+          /// log(x) is natural log (base e)
+        val log : Complex -> Complex
+          /// sqrt(x) and 0 <= phase(x) < pi
+        val sqrt : Complex -> Complex
+          /// Sine
+        val sin : Complex -> Complex    
+          /// Cosine
+        val cos : Complex -> Complex
+          /// Tagent
+        val tan : Complex -> Complex
+        
+
+    [<AutoOpen>]
+    module ComplexTopLevelOperators = 
+        /// Constructs a complex number from both the real and imaginary part.
+        val complex : float -> float -> complex
+
+
+
diff --git a/src/FSharp.PowerPack/math/matrix.fs b/src/FSharp.PowerPack/math/matrix.fs
new file mode 100755
index 0000000..8ff7ab9
--- /dev/null
+++ b/src/FSharp.PowerPack/math/matrix.fs
@@ -0,0 +1,2563 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+//----------------------------------------------------------------------------
+// An implementation of generic dense and sparse matrix types.
+//
+// Overview and suffix documentation
+//    _GU  = generic unspecialized (Matrix<T>, Vector<T> etc.) 
+//    _GUA = generic unspecialized op on (underlying) array
+//    _DS  = Double specialized (Matrix<float> = matrix, Vector<float> = vector etc.)
+//
+//    DM   = dense matrix
+//    SM   = sparse matrix
+//    V    = vector (dense)
+//    RV   = row vector (dense)
+
+
+namespace Microsoft.FSharp.Math
+
+    #nowarn "60" // implementations in augmentations
+    #nowarn "69" // implementations in augmentations
+
+    open Microsoft.FSharp.Math
+    open System
+    open System.Globalization
+    open System.Collections
+    open System.Collections.Generic
+    open System.Diagnostics
+    type permutation = int -> int
+
+
+//=========================================================================
+// (c) Microsoft Corporation 2005-2009. 
+//=========================================================================
+
+    [<AutoOpen>]
+    module Helpers = 
+        let sparseNYI() = failwith "this operation is not supported on sparse matrices"
+        let sparseNotMutable() = failwith "sparse matrices are not mutable"
+        
+        [<RequiresExplicitTypeArguments>]
+        let opsdata<'T> = GlobalAssociations.TryGetNumericAssociation<'T>()
+        
+        [<Literal>]
+        let DenseMaxDisplay = 50
+        [<Literal>]
+        let VectorMaxDisplay = 100
+    
+    
+    /// The value stored for the dictionary of numeric operations. If none is present then this indicates
+    /// no operations are known for this type.
+    type OpsData<'T> = INumeric<'T> option
+
+    type DenseMatrix<'T>(opsData : OpsData<'T>, values : 'T[,]) = 
+        member m.OpsData =  opsData
+        member m.Values =  values
+        member m.NumRows = values.GetLength(0)
+        member m.NumCols = values.GetLength(1)
+
+        member m.ElementOps = 
+            match opsData with 
+            | None -> raise (new System.NotSupportedException("The element type carried by this matrix does not support numeric operations"))
+            | Some a -> a
+
+        member m.Item
+           with get (i,j) = values.[i,j]
+           and  set (i,j) x = values.[i,j] <- x
+
+
+
+    type SparseMatrix<'T>(opsData : OpsData<'T>, sparseValues : 'T array, sparseRowOffsets : int array, ncols:int, columnValues: int array) = 
+        member m.OpsData = opsData; 
+        member m.NumCols = ncols
+        member m.NumRows = sparseRowOffsets.Length - 1
+        member m.SparseColumnValues = columnValues
+        member m.SparseRowOffsets =  sparseRowOffsets (* nrows + 1 elements *)
+        member m.SparseValues =  sparseValues
+
+        member m.ElementOps = 
+              match opsData with 
+              | None -> raise (new System.NotSupportedException("The element type carried by this matrix does not support numeric operations"))
+              | Some a -> a
+
+        member m.MinIndexForRow i = m.SparseRowOffsets.[i]
+        member m.MaxIndexForRow i = m.SparseRowOffsets.[i+1]
+              
+
+        member m.Item 
+            with get (i,j) = 
+                let imax = m.NumRows
+                let jmax = m.NumCols
+                if j < 0 || j >= jmax || i < 0 || i >= imax then raise (new System.ArgumentOutOfRangeException()) else
+                let kmin = m.MinIndexForRow i
+                let kmax = m.MaxIndexForRow i
+                let rec loopRow k =
+                    (* note: could do a binary chop here *)
+                    if k >= kmax then m.ElementOps.Zero else
+                    let j2 = columnValues.[k]
+                    if j < j2 then m.ElementOps.Zero else
+                    if j = j2 then sparseValues.[k] else 
+                    loopRow (k+1)
+                loopRow kmin
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+    [<System.Diagnostics.DebuggerDisplay("{DebugDisplay}")>]
+#endif
+    [<StructuredFormatDisplay("matrix {StructuredDisplayAsArray}")>]
+    [<CustomEquality; CustomComparison>]
+    //[<System.Diagnostics.DebuggerTypeProxy(typedefof<MatrixDebugView<_>>)>]
+    type Matrix<'T> = 
+        | DenseRepr of DenseMatrix<'T>
+        | SparseRepr of SparseMatrix<'T>
+        interface System.IComparable
+        interface IStructuralComparable
+        interface IStructuralEquatable
+        interface IEnumerable<'T> 
+        interface IEnumerable
+
+        member m.ElementOps = match m with DenseRepr mr -> mr.ElementOps | SparseRepr mr -> mr.ElementOps
+        member m.NumRows    = match m with DenseRepr mr -> mr.NumRows    | SparseRepr mr ->  mr.NumRows
+        member m.NumCols    = match m with DenseRepr mr -> mr.NumCols    | SparseRepr mr ->  mr.NumCols
+
+        member m.Item 
+            with get (i,j) = 
+                match m with 
+                | DenseRepr dm -> dm.[i,j]
+                | SparseRepr sm -> sm.[i,j]
+            and set (i,j) x = 
+              match m with 
+              | DenseRepr dm -> dm.[i,j] <- x
+              | SparseRepr _ -> sparseNotMutable()
+
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.IsDense = match m with DenseRepr _ -> true | SparseRepr _ -> false
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.IsSparse = match m with DenseRepr _ -> false | SparseRepr _ -> true
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.InternalSparseColumnValues = match m with DenseRepr _ -> invalidOp "not a sparse matrix" | SparseRepr mr -> mr.SparseColumnValues
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.InternalSparseRowOffsets = match m with DenseRepr _ -> invalidOp "not a sparse matrix" | SparseRepr mr -> mr.SparseRowOffsets
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.InternalSparseValues = match m with DenseRepr _ -> invalidOp "not a sparse matrix" | SparseRepr mr -> mr.SparseValues
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.InternalDenseValues = match m with DenseRepr mr -> mr.Values | SparseRepr _ -> invalidOp "not a dense matrix"
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+    [<System.Diagnostics.DebuggerDisplay("{DebugDisplay}")>]
+#endif
+#if FX_NO_DEBUG_PROXIES
+#else
+    [<System.Diagnostics.DebuggerTypeProxy(typedefof<RowVectorDebugView<_>>)>]
+#endif
+    [<StructuredFormatDisplay("rowvec {StructuredDisplayAsArray}")>]
+    [<Sealed>]
+    type RowVector<'T>(opsRV : INumeric<'T> option, arrRV : 'T array ) =
+        interface System.IComparable
+        interface IStructuralComparable
+        interface IStructuralEquatable 
+
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member x.InternalValues = arrRV
+        member x.Values = arrRV
+        member x.OpsData = opsRV
+        
+        
+        interface IEnumerable<'T> with 
+            member x.GetEnumerator() = (arrRV :> seq<_>).GetEnumerator()
+        interface IEnumerable  with 
+            member x.GetEnumerator() = (arrRV :> IEnumerable).GetEnumerator()
+
+        member x.Length = arrRV.Length
+        member x.NumCols = arrRV.Length
+        member x.ElementOps = 
+            match opsRV with 
+            | None -> raise (new System.NotSupportedException("The element type carried by this row vector does not support numeric operations"))
+            | Some a -> a
+
+        member v.Item
+           with get i = arrRV.[i]
+           and  set i x = arrRV.[i] <- x
+
+    and 
+        [<Sealed>]
+        RowVectorDebugView<'T>(v: RowVector<'T>)  =  
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+             [<System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)>]
+#endif
+             member x.Items = v |> Seq.truncate 1000 |> Seq.toArray 
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+    [<System.Diagnostics.DebuggerDisplay("{DebugDisplay}")>]
+#endif
+#if FX_NO_DEBUG_PROXIES
+#else
+    [<System.Diagnostics.DebuggerTypeProxy(typedefof<VectorDebugView<_>>)>]
+#endif
+    [<StructuredFormatDisplay("vector {StructuredDisplayAsArray}")>]
+    [<Sealed>]
+    type Vector<'T>(opsV : INumeric<'T> option, arrV : 'T array) =
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member x.InternalValues = arrV
+        member x.Values = arrV
+        member x.OpsData = opsV
+        interface System.IComparable
+        interface IStructuralComparable
+        interface IStructuralEquatable 
+
+        interface IEnumerable<'T> with 
+            member x.GetEnumerator() = (arrV :> seq<_>).GetEnumerator()
+        interface IEnumerable  with 
+            member x.GetEnumerator() = (arrV :> IEnumerable).GetEnumerator()
+        
+
+        member m.Length = arrV.Length
+        member m.NumRows = arrV.Length
+        member m.ElementOps = 
+            match opsV with 
+            | None -> raise (new System.NotSupportedException("The element type carried by this vector does not support numeric operations"))
+            | Some a -> a
+        member v.Item
+           with get i = arrV.[i]
+           and  set i x = arrV.[i] <- x
+
+#if FX_NO_DEBUG_PROXIES
+#else
+    and 
+        [<Sealed>]
+        VectorDebugView<'T>(v: Vector<'T>)  =  
+
+             [<System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)>]
+             member x.Items = v |> Seq.truncate 1000 |> Seq.toArray 
+#endif
+
+
+    /// Implementations of operations that will work for any type
+    module GenericImpl = 
+
+        type OpsData<'T> = INumeric<'T> option
+
+        let opsOfOpsData (d : OpsData<'T>)  =
+             match d with 
+             | None -> raise (new System.NotSupportedException("The element type '"+(typeof<'T>).ToString()+"' carried by this vector or matrix does not support numeric operations (i.e. does not have a registered numeric association)"))
+             | Some a -> a
+
+        let getNormOps (ops:INumeric<'T>) = 
+            match box ops with
+              | :? INormFloat<'T> as ops -> ops
+              | _ -> raise (new System.NotSupportedException("The element type '"+(typeof<'T>.ToString())+"' carried by this vector or matrix does not support the INormFloat<_> operation (i.e. does not have a registered numeric association that supports this type)"))
+
+        let mkDenseMatrixGU ops arr = DenseMatrix(ops,arr)
+        let mkRowVecGU ops arr = RowVector(ops, arr)
+        let mkVecGU ops arr = Vector(ops,arr)
+
+        let inline getArray2D  (arrDM : _[,]) i j   = arrDM.[i,j]
+        let inline setArray2D  (arrDM  : _[,]) i j x = arrDM.[i,j] <- x
+
+        let inline createArray m = Array.zeroCreate m
+
+        let inline createArray2D m n = Array2D.zeroCreate m n
+
+        let inline assignArray2D m n f arr =  
+            for i = 0 to m - 1 do 
+                for j = 0 to n - 1 do 
+                    (arr  : _[,]).[i,j] <- f i j
+
+        let inline assignConstArray2D m n x arr =  
+            for i = 0 to m - 1 do 
+                for j = 0 to n - 1 do 
+                    (arr  : _[,]).[i,j] <- x
+
+        let inline assignDenseMatrixGU f (a:DenseMatrix<_>) = 
+            assignArray2D a.NumRows a.NumCols f a.Values
+        
+        let inline assignArray m f (arr : _[]) = 
+            for i = 0 to m - 1 do 
+                arr.[i] <- f i
+
+        let inline assignConstArray m x (arr : _[]) = 
+            for i = 0 to m - 1 do 
+                arr.[i] <- x
+
+        let inline assignVecGU f (a:Vector<_>) = 
+            assignArray a.NumRows f a.Values
+        
+        let inline assignRowVecGU f (a:RowVector<_>) = 
+            assignArray a.NumCols f a.Values
+        
+        let createConstDenseMatrixGU ops m n x = 
+            let arr = createArray2D m n 
+            assignConstArray2D m n x arr;
+            DenseMatrix(ops,arr)
+        
+        let createConstRowVecGU ops m x = 
+            let arr = createArray m 
+            assignConstArray m x arr;
+            mkRowVecGU ops arr
+        
+        let createConstVecGU ops m x = 
+            let arr = createArray m 
+            assignConstArray m x arr;
+            mkVecGU ops arr
+
+
+        let inline createDenseMatrixGU ops m n f = (* inline eliminates unknown f call *)
+            let arr = createArray2D m n 
+            assignArray2D m n f arr;
+            DenseMatrix(ops,arr)
+        
+        let createRowVecGU ops m f = 
+            let arr = createArray m 
+            assignArray m f arr;
+            mkRowVecGU ops arr
+        
+        let inline createVecGU ops m f = (* inline eliminates unknown f call *)
+            let arr = createArray m 
+            assignArray m f arr;
+            mkVecGU ops arr
+
+        /// Create a matrix from a sparse sequence 
+        let initSparseMatrixGU maxi maxj ops s = 
+
+            (* nb. could use sorted dictionary but that is in System.dll *)
+            let tab = Array.create maxi null
+            let count = ref 0
+            for (i,j,v) in s do
+                if i < 0 || i >= maxi || j <0 || j >= maxj then failwith "initial value out of range";
+                count := !count + 1;
+                let tab2 = 
+                    match tab.[i] with 
+                    | null -> 
+                        let tab2 = new Dictionary<_,_>(3) 
+                        tab.[i] <- tab2;
+                        tab2
+                    | tab2 -> tab2
+                tab2.[j] <- v
+            // optimize this line....
+            let offsA =  
+               let rowsAcc = Array.zeroCreate (maxi + 1)
+               let mutable acc = 0 
+               for i = 0 to maxi-1 do 
+                  rowsAcc.[i] <- acc;
+                  acc <- match tab.[i] with 
+                          | null -> acc
+                          | tab2 -> acc+tab2.Count
+               rowsAcc.[maxi] <- acc;
+               rowsAcc
+               
+            let colsA,valsA = 
+               let colsAcc = new ResizeArray<_>(!count)
+               let valsAcc = new ResizeArray<_>(!count)
+               for i = 0 to maxi-1 do 
+                  match tab.[i] with 
+                  | null -> ()
+                  | tab2 -> tab2 |> Seq.toArray |> Array.sortBy (fun kvp -> kvp.Key) |> Array.iter (fun kvp -> colsAcc.Add(kvp.Key); valsAcc.Add(kvp.Value));
+               colsAcc.ToArray(), valsAcc.ToArray()
+
+            SparseMatrix(opsData=ops, sparseValues=valsA, sparseRowOffsets=offsA, ncols=maxj, columnValues=colsA)
+        
+        let zeroizeDenseMatrixGUA arr  m n : DenseMatrix<'T> = 
+            let opsData = opsdata<'T> 
+            let ops = opsOfOpsData opsData 
+            let zero = ops.Zero 
+            assignArray2D m n (fun _ _ -> zero) arr;
+            DenseMatrix(opsData,arr)
+
+        let zeroizeArray opsData arr m  = 
+            let ops = opsOfOpsData opsData 
+            let zero = ops.Zero 
+            assignArray m (fun _ -> zero) arr
+
+        let zeroizeVecGUA arr m  : Vector<'T> = 
+            let opsData = opsdata<'T> 
+            zeroizeArray opsData arr m;
+            mkVecGU opsData arr
+
+        let zeroizeRowVecGUA arr m  : RowVector<'T> = 
+            let opsData = opsdata<'T> 
+            zeroizeArray opsData arr m;
+            mkRowVecGU opsData arr
+
+        let listDenseMatrixGU ops xss =
+            let m = List.length xss
+            match xss with 
+            | [] -> invalidArg "xss" "unexpected empty list"
+            | h :: t -> 
+              let n = List.length h
+              if not (List.forall (fun xs -> List.length xs=n) t) then invalidArg "xss" "the lists are not all of the same length";
+              let values = Array2D.zeroCreate m n
+              List.iteri (fun i rw -> List.iteri (fun j x -> values.[i,j] <- x) rw) xss;
+              DenseMatrix(ops,values)
+        
+        let listRowVecGU ops xs = mkRowVecGU ops (Array.ofList xs) 
+        let listVecGU ops xs = mkVecGU ops (Array.ofList xs) 
+
+        let seqDenseMatrixGU ops xss = listDenseMatrixGU ops (xss |> Seq.toList |> List.map Seq.toList)
+        let seqVecGU  ops xss = listVecGU ops (xss |> Seq.toList)
+        let seqRowVecGU ops xss = listRowVecGU ops (xss |> Seq.toList)
+
+        let inline binaryOpDenseMatrixGU f (a:DenseMatrix<_>) (b:DenseMatrix<_>) = (* pointwise binary operator *)
+            let nA = a.NumCols
+            let mA = a.NumRows
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA<>nB || mA<>mB then invalidArg "a" "the two matrices do not have compatible dimensions";
+            let arrA = a.Values 
+            let arrB = b.Values 
+            createDenseMatrixGU a.OpsData mA nA (fun i j -> f (getArray2D arrA i j) (getArray2D arrB i j))
+
+
+        let nonZeroEntriesSparseMatrixGU  (a:SparseMatrix<_>) = 
+            // This is heavily used, and this version is much faster than
+            // the sequence operators.
+            let entries = new ResizeArray<_>(a.SparseColumnValues.Length)
+            let imax = a.NumRows
+            let ops = a.ElementOps 
+            let zero = ops.Zero
+            for i in 0 .. imax - 1 do
+              let kmin = a.MinIndexForRow i
+              let kmax = a.MaxIndexForRow i
+              for k in kmin .. kmax - 1 do
+                  let j = a.SparseColumnValues.[k]
+                  let v = a.SparseValues.[k]
+                  if not (ops.Equals(v,zero)) then
+                    entries.Add((i,j,v))
+            (entries :> seq<_>)
+
+        let nonzeroEntriesDenseMatrixGU  (a:DenseMatrix<_>) = 
+            let imax = a.NumRows
+            let jmax = a.NumCols
+            let ops = a.ElementOps 
+            let zero = ops.Zero
+            seq { for i in 0 .. imax - 1 do 
+                    for j in 0 .. jmax - 1 do 
+                        let v = a.[i,j] 
+                        if not (ops.Equals(v, zero)) then
+                             yield (i,j,v) }
+
+
+        // pointwise operation on two sparse matrices. f must be zero-zero-preserving, i.e. (f 0 0 = 0) 
+        let binaryOpSparseMatrixGU f (a:SparseMatrix<_>) (b:SparseMatrix<_>) = 
+            let ops = a.ElementOps 
+            let zero = ops.Zero
+            let imax1 = a.NumRows  
+            let imax2 = b.NumRows
+            let jmax1 = a.NumCols
+            let jmax2 = b.NumCols
+            if imax1 <> imax2 || jmax1 <> jmax2 then invalidArg "b" "the two matrices do not have compatible dimensions";
+            let imin = 0
+            let imax = imax1
+            let jmax = jmax1
+            let rowsR = Array.zeroCreate (imax+1)
+            let colsR = new ResizeArray<_>(max a.SparseColumnValues.Length b.SparseColumnValues.Length)
+            let valsR = new ResizeArray<_>(max a.SparseValues.Length b.SparseValues.Length)
+            let rec loopRows i  = 
+                rowsR.[i] <- valsR.Count;            
+                if i >= imax1 then () else
+                let kmin1 = a.MinIndexForRow i
+                let kmax1 = a.MaxIndexForRow i 
+                let kmin2 = b.MinIndexForRow i
+                let kmax2 = b.MaxIndexForRow i
+                let rec loopRow k1 k2  =
+                    if k1 >= kmax1 && k2 >= kmax2 then () else
+                    let j1 = if k1 >= kmax1 then jmax else a.SparseColumnValues.[k1]
+                    let j2 = if k2 >= kmax2 then jmax else b.SparseColumnValues.[k2]
+                    let v1 = if j1 <= j2 then a.SparseValues.[k1] else zero
+                    let v2 = if j2 <= j1 then b.SparseValues.[k2] else zero
+                    let jR = min j1 j2
+                    let vR = f v1 v2
+                    (* if vR <> zero then  *)
+                    colsR.Add(jR);
+                    valsR.Add(vR);
+                    loopRow (if j1 <= j2 then k1+1 else k1) (if j2 <= j1 then k2+1 else k2)
+                loopRow kmin1 kmin2;
+                loopRows (i+1) 
+            loopRows imin;
+            SparseMatrix(opsData= a.OpsData, 
+                         sparseRowOffsets=rowsR, 
+                         ncols= a.NumCols, 
+                         columnValues=colsR.ToArray(), 
+                         sparseValues=valsR.ToArray())
+
+        let inline binaryOpRowVecGU f (a:RowVector<_>) (b:RowVector<_>) = (* pointwise binary operator *)
+            let mA = a.NumCols
+            let mB = b.NumCols
+            if mA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            createRowVecGU a.OpsData mA (fun i -> f a.[i] b.[i])
+
+        let inline binaryOpVecGU f (a:Vector<_>) (b:Vector<_>) = (* pointwise binary operator *)
+            let mA = a.NumRows
+            let mB = b.NumRows
+            if mA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            createVecGU a.OpsData mA (fun i -> f a.[i] b.[i])
+
+        let inline unaryOpDenseMatrixGU f (a:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let arrA = a.Values 
+            createDenseMatrixGU a.OpsData mA nA (fun i j -> f (getArray2D arrA i j))
+
+        let inline unaryOpRowVecGU f (a:RowVector<_>) =
+            let mA = a.NumCols
+            let arrA = a.Values 
+            createRowVecGU a.OpsData mA (fun j -> f arrA.[j])
+
+        let inline unaryOpVectorGU f (a:Vector<_>) =
+            let mA = a.NumRows 
+            let arrA = a.Values 
+            createVecGU a.OpsData mA (fun i -> f arrA.[i])
+
+        let unaryOpSparseGU f (a:SparseMatrix<_>) = (* pointwise zero-zero-preserving binary operator (f 0 = 0) *)
+            SparseMatrix(opsData=a.OpsData,
+                         sparseRowOffsets=Array.copy a.SparseRowOffsets, 
+                         columnValues=Array.copy a.SparseColumnValues, 
+                         sparseValues=Array.map f a.SparseValues, 
+                         ncols=a.NumCols)
+
+        // Strictly speaking, sparse arrays are non mutable so no copy is ever needed. But implementing it *)
+        // anyway in case we move to mutability *)
+        let copySparseGU (a:SparseMatrix<_>) = 
+            SparseMatrix(opsData=a.OpsData,
+                         sparseRowOffsets=Array.copy a.SparseRowOffsets, 
+                         columnValues=Array.copy a.SparseColumnValues,
+                         sparseValues=Array.copy a.SparseValues, 
+                         ncols=a.NumCols)
+
+        let addDenseMatrixGU  (a:DenseMatrix<_>)  b = let ops = a.ElementOps in binaryOpDenseMatrixGU (fun x y -> ops.Add(x, y)) a b
+        let addSparseMatrixGU (a:SparseMatrix<_>) b = let ops = a.ElementOps in binaryOpSparseMatrixGU (fun x y -> ops.Add(x, y)) a b
+        let addRowVecGU       (a:RowVector<_>)    b = let ops = a.ElementOps in binaryOpRowVecGU (fun x y -> ops.Add(x, y)) a b
+        let addVecGU          (a:Vector<_>)       b = let ops = a.ElementOps in binaryOpVecGU  (fun x y -> ops.Add(x, y)) a b 
+
+        let subDenseMatrixGU  (a:DenseMatrix<_>)  b = let ops = a.ElementOps in binaryOpDenseMatrixGU (fun x y -> ops.Subtract(x, y)) a b
+        let subSparseMatrixGU (a:SparseMatrix<_>) b = let ops = a.ElementOps in binaryOpSparseMatrixGU (fun x y -> ops.Subtract(x, y)) a b
+        let subRowVecGU       (a:RowVector<_>)    b = let ops = a.ElementOps in binaryOpRowVecGU (fun x y -> ops.Subtract(x, y)) a b
+        let subVecGU          (a:Vector<_>)       b = let ops = a.ElementOps in binaryOpVecGU  (fun x y -> ops.Subtract(x, y)) a b 
+
+        ///Point-wise multiplication 
+        let cptMulDenseMatrixGU  (a:DenseMatrix<_>)  b = let ops = a.ElementOps in binaryOpDenseMatrixGU  (fun x y -> ops.Multiply(x, y)) a b
+        let cptMulSparseMatrixGU (a:SparseMatrix<_>) b = let ops = a.ElementOps in binaryOpSparseMatrixGU  (fun x y -> ops.Multiply(x, y)) a b
+        let cptMulRowVecGU       (a:RowVector<_>)    b = let ops = a.ElementOps in binaryOpRowVecGU (fun x y -> ops.Multiply(x, y)) a b
+        let cptMulVecGU          (a:Vector<_>)       b = let ops = a.ElementOps in binaryOpVecGU  (fun x y -> ops.Multiply(x, y)) a b
+
+        let cptMaxDenseMatrixGU  (a:DenseMatrix<_>) b = binaryOpDenseMatrixGU  max a b
+        let cptMinDenseMatrixGU  (a:DenseMatrix<_>) b = binaryOpDenseMatrixGU  min a b
+        let cptMaxSparseMatrixGU (a:SparseMatrix<_>) b = binaryOpSparseMatrixGU  max a b
+        let cptMinSparseMatrixGU (a:SparseMatrix<_>) b = binaryOpSparseMatrixGU  min a b
+
+        let cptMaxVecGU (a:Vector<_>) b = binaryOpVecGU max a b
+        let cptMinVecGU (a:Vector<_>) b = binaryOpVecGU min a b
+
+        let add (ops : INumeric<'T>) x y = ops.Add(x,y) 
+        let sub (ops : INumeric<'T>) x y = ops.Subtract(x,y) 
+        let mul (ops : INumeric<'T>) x y = ops.Multiply(x,y) 
+
+        let inline foldR f z (a,b) = 
+            let mutable res = z in
+            for i = a to b do
+                res <- f res i
+            res
+
+        let inline sumfR f (a,b) =
+            let mutable res = 0.0 
+            for i = a to b do
+                res <- res + f i
+            res
+          
+
+        let inline sumRGU (ops : INumeric<_>) f r = 
+            let zero = ops.Zero 
+            r |> foldR (fun z k -> add ops z (f k)) zero
+
+        let genericMulDenseMatrix (a:DenseMatrix<_>) (b:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA<>mB then invalidArg "b" "the two matrices do not have compatible dimensions"
+            let ops = a.ElementOps 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            createDenseMatrixGU a.OpsData mA nB
+              (fun i j -> (0,nA - 1) |> sumRGU ops (fun k -> mul ops (getArray2D arrA i k) (getArray2D arrB k j)))
+
+        let debug = false
+        
+        // SParse matrix multiplication algorithm. inline to get specialization at the 'double' type
+        let inline genericMulSparse zero add mul (a:SparseMatrix<_>) (b:SparseMatrix<_>) =
+            let nA = a.NumCols
+            let mA = a.NumRows
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA<>mB then invalidArg "b" "the two matrices do not have compatible dimensions"
+            let C = new ResizeArray<_>()
+            let jC = new ResizeArray<_>()
+            let MA1 = mA + 1 
+            let offsAcc = Array.zeroCreate MA1
+            let index = Array.zeroCreate mA
+            let temp = Array.create mA zero
+            let ptr = new Dictionary<_,_>(11)
+            if debug then printf "start, #items in result = %d, #offsAcc = %d, mA = %d\n" jC.Count offsAcc.Length mA;
+
+            let mutable mlast = 0
+            for i = 0 to mA-1 do
+                if debug then printf "i = %d, mlast = %d\n" i mlast;
+                offsAcc.[i] <- mlast
+                
+                let kmin1 = a.MinIndexForRow i
+                let kmax1 = a.MaxIndexForRow i
+                if kmin1 < kmax1 then 
+                    let mutable itemp = 0
+                    let mutable ptrNeedsClear = true // clear the ptr table on demand. 
+                    for j = kmin1 to kmax1 - 1 do
+                        if debug then printf "  j = %d\n" j;
+                        let ja_j = a.SparseColumnValues.[j]
+                        let kmin2 = b.MinIndexForRow ja_j
+                        let kmax2 = b.MaxIndexForRow ja_j
+                        for k = kmin2 to kmax2 - 1 do
+                            let jb_k = b.SparseColumnValues.[k]
+                            if debug then printf "    i = %d, j = %d, k = %d, ja_j = %d, jb_k = %d\n" i j k ja_j jb_k;
+                            let va = a.SparseValues.[j] 
+                            let vb = b.SparseValues.[k]
+                            if debug then printf "    va = %O, vb = %O\n" va vb;
+                            let summand = mul va vb
+                            if debug then printf "    summand = %O\n" summand;
+                            if ptrNeedsClear then (ptr.Clear();ptrNeedsClear <- false);
+
+                            if not (ptr.ContainsKey(jb_k)) then
+                                if debug then printf "    starting entry %d\n" jb_k;
+                                ptr.[jb_k] <- itemp
+                                let ptr_jb_k = itemp
+                                temp.[ptr_jb_k] <- summand
+                                index.[ptr_jb_k] <- jb_k
+                                itemp <- itemp + 1
+                            else
+                                if debug then printf "    adding to entry %d\n" jb_k;
+                                let ptr_jb_k = ptr.[jb_k]
+                                temp.[ptr_jb_k] <- add temp.[ptr_jb_k] summand
+                        done
+                    done
+                    if itemp > 0 then 
+                        // Sort by index. 
+                        // REVIEW: avoid the allocations here
+                        let sorted = (temp.[0..itemp-1],index.[0..itemp-1]) ||> Array.zip 
+                        Array.sortInPlaceBy (fun (_,idx) -> idx) sorted
+                        for s = 0 to itemp-1 do
+                            let (v,idx) = sorted.[s]
+                            if debug then printf "  writing value %O at index %d to result matrix\n" v idx;
+                            C.Add(v)
+                            jC.Add(idx)
+                        if debug then printf " itemp = %d, mlast = %d\n" itemp mlast;
+                        mlast <- mlast + itemp 
+            done
+            offsAcc.[mA] <- mlast;
+            if debug then printf "done, #items in result = %d, #offsAcc = %d, mA = %d\n" jC.Count offsAcc.Length mA;
+            SparseMatrix(opsData = a.OpsData,
+                         sparseRowOffsets=offsAcc,
+                         ncols= nB,
+                         columnValues=jC.ToArray(),
+                         sparseValues=C.ToArray())
+
+        let mulSparseMatrixGU (a: SparseMatrix<_>) b =
+            let ops = a.ElementOps 
+            let zero = ops.Zero
+            genericMulSparse zero (add ops) (mul ops) a b
+
+
+        let mulRowVecVecGU (a:RowVector<_>) (b:Vector<_>) =
+            let mA = a.NumCols 
+            let nB = b.NumRows 
+            if mA<>nB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            let ops = a.ElementOps 
+            (0,mA - 1) |> sumRGU ops (fun k -> mul ops a.[k] b.[k])
+
+        let rowvecDenseMatrixGU (x:RowVector<_>) = createDenseMatrixGU x.OpsData 1         x.NumCols (fun _ j -> x.[j]) 
+        let vectorDenseMatrixGU (x:Vector<_>)    = createDenseMatrixGU x.OpsData  x.NumRows 1         (fun i _ -> x.[i]) 
+
+        let mulVecRowVecGU a b = genericMulDenseMatrix (vectorDenseMatrixGU a) (rowvecDenseMatrixGU b)
+
+        let mulRowVecDenseMatrixGU (a:RowVector<_>) (b:DenseMatrix<_>) =
+            let    nA = a.NumCols 
+            let nB = b.NumCols
+            let mB = b.NumRows 
+            if nA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            let ops = a.ElementOps 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            createRowVecGU a.OpsData nB 
+              (fun j -> (0,nA - 1) |> sumRGU ops (fun k -> mul ops arrA.[k] (getArray2D arrB k j)))
+
+        let mulDenseMatrixVecGU (a:DenseMatrix<_>) (b:Vector<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let mB    = b.NumRows
+            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
+            let ops = b.ElementOps 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            createVecGU b.OpsData mA
+              (fun i -> (0,nA - 1) |> sumRGU ops (fun k -> mul ops (getArray2D arrA i k) arrB.[k]))
+
+        let mulSparseVecGU (a:SparseMatrix<_>) (b:Vector<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let mB    = b.NumRows 
+            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
+            let ops = b.ElementOps 
+            let zero = ops.Zero
+            createVecGU b.OpsData mA (fun i -> 
+                let mutable acc = zero
+                for k = a.MinIndexForRow i to a.MaxIndexForRow i - 1 do
+                    let j = a.SparseColumnValues.[k]
+                    let v = a.SparseValues.[k] 
+                    acc <- add ops acc (mul ops v b.[j]);
+                acc)
+
+        let mulRVSparseMatrixGU (a:RowVector<_>) (b:SparseMatrix<_>) =
+            let nA = b.NumCols
+            let mA = b.NumRows 
+            let mB    = a.NumCols 
+            if mA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
+            let ops = b.ElementOps 
+            let arr = createArray nA 
+            zeroizeArray a.OpsData arr nA;
+            for i = 0 to mA - 1 do
+                for k = b.MinIndexForRow i to b.MaxIndexForRow i - 1 do
+                    let j = b.SparseColumnValues.[k]
+                    let v = b.SparseValues.[k] 
+                    arr.[j] <- add ops arr.[j] (mul ops a.[i] v)
+            mkRowVecGU a.OpsData arr
+
+
+        let scaleDenseMatrixGU  k (a:DenseMatrix<_>)  = let ops = a.ElementOps in unaryOpDenseMatrixGU (fun x -> ops.Multiply(k,x)) a
+        let scaleRowVecGU       k (a:RowVector<_>)    = let ops = a.ElementOps in unaryOpRowVecGU (fun x -> ops.Multiply(k,x)) a
+        let scaleVecGU          k (a:Vector<_>)       = let ops = a.ElementOps in unaryOpVectorGU  (fun x -> ops.Multiply(k,x)) a
+        let scaleSparseMatrixGU k (a:SparseMatrix<_>) = let ops = a.ElementOps in unaryOpSparseGU (fun x -> ops.Multiply(k,x)) a
+        let negDenseMatrixGU  (a:DenseMatrix<_>)  = let ops = a.ElementOps in unaryOpDenseMatrixGU (fun x -> ops.Negate(x)) a
+        let negRowVecGU       (a:RowVector<_>)    = let ops = a.ElementOps in unaryOpRowVecGU (fun x -> ops.Negate(x)) a
+        let negVecGU          (a:Vector<_>)       = let ops = a.ElementOps in unaryOpVectorGU  (fun x -> ops.Negate(x)) a
+        let negSparseMatrixGU (a:SparseMatrix<_>) = let ops = a.ElementOps in unaryOpSparseGU (fun x -> ops.Negate(x)) a
+
+        let mapDenseMatrixGU f (a : DenseMatrix<'T>) : DenseMatrix<'T> = 
+            let arrA = a.Values 
+            createDenseMatrixGU a.OpsData a.NumRows a.NumCols (fun i j -> f (getArray2D arrA i j))
+
+        let mapVecGU f (a:Vector<_>) = 
+            let mA= a.NumRows
+            createVecGU a.OpsData mA (fun i -> f a.[i])
+
+        let copyDenseMatrixGU (a : DenseMatrix<'T>) : DenseMatrix<'T> = 
+            let arrA = a.Values 
+            createDenseMatrixGU a.OpsData a.NumRows a.NumCols (fun i j -> getArray2D arrA i j)
+
+        let copyVecGU (a:Vector<_>) = 
+            createVecGU a.OpsData a.NumRows (fun i -> a.[i])
+
+        let copyRowVecGU (a:RowVector<_>) = 
+            createRowVecGU a.OpsData a.NumCols (fun i -> a.[i])
+
+        let toDenseSparseMatrixGU (a:SparseMatrix<_>) = 
+            createDenseMatrixGU a.OpsData a.NumRows a.NumCols  (fun i j -> a.[i,j])
+          
+        let mapiDenseMatrixGU f (a: DenseMatrix<'T>) : DenseMatrix<'T> = 
+            let arrA = a.Values 
+            createDenseMatrixGU a.OpsData a.NumRows a.NumCols (fun i j -> f i j (getArray2D arrA i j))
+
+        let mapiRowVecGU f (a:RowVector<_>) = 
+            createRowVecGU a.OpsData a.NumCols (fun i -> f i a.[i])
+
+        let mapiVecGU f (a:Vector<_>) = 
+            createVecGU a.OpsData a.NumRows (fun i -> f i a.[i])
+
+        let permuteVecGU (p:permutation) (a:Vector<_>) = 
+            createVecGU a.OpsData a.NumRows (fun i -> a.[p i])
+
+        let permuteRowVecGU (p:permutation) (a:RowVector<_>) = 
+            createRowVecGU a.OpsData a.NumCols (fun i -> a.[p i])
+
+        let inline inplace_mapiDenseMatrixGU f (a:DenseMatrix<_>) = 
+            let arrA = a.Values 
+            assignDenseMatrixGU (fun i j -> f i j (getArray2D arrA i j)) a
+
+        let inline inplace_mapiRowVecGU f (a:RowVector<_>) = 
+            assignRowVecGU (fun i -> f i a.[i]) a
+
+        let inline inplace_mapiVecGU f (a:Vector<_>) = 
+            assignVecGU (fun i -> f i a.[i]) a
+
+        let inline foldDenseMatrixGU f z (a:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let arrA = a.Values 
+            let mutable acc = z
+            for i = 0 to mA-1 do
+                for j = 0 to nA-1 do 
+                   acc <- f acc (getArray2D arrA i j)
+            acc
+        
+        let inline foldVecGU f z (a:Vector<_>) =
+            let mutable acc = z
+            for i = 0 to a.NumRows-1 do acc <- f acc a.[i]
+            acc
+        
+        let inline foldiDenseMatrixGU f z (a:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let arrA = a.Values 
+            let mutable acc = z
+            for i = 0 to mA-1 do
+                for j = 0 to nA-1 do 
+                   acc <- f i j acc (getArray2D arrA i j)
+            acc
+        
+        let inline foldiVecGU f z (a:Vector<_>) =
+            let mA = a.NumRows
+            let mutable acc = z
+            for i = 0 to mA-1 do acc <- f i acc a.[i]
+            acc
+        
+        let rec forallR f (n,m) = (n > m) || (f n && forallR f (n+1,m))
+        let rec existsR f (n,m) = (n <= m) && (f n || existsR f (n+1,m))
+        
+        let foralliDenseMatrixGU pred (a:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let arrA = a.Values 
+            (0,mA-1) |> forallR  (fun i ->
+            (0,nA-1) |> forallR  (fun j ->
+            pred i j (getArray2D arrA i j)))
+
+        let foralliVecGU pred (a:Vector<_>) =
+            let mA = a.NumRows
+            (0,mA-1) |> forallR  (fun i ->
+            pred i a.[i])
+
+        let existsiDenseMatrixGU pred (a:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let arrA = a.Values 
+            (0,mA-1) |> existsR (fun i ->
+            (0,nA-1) |> existsR (fun j ->
+            pred i j (getArray2D arrA i j)))
+
+        let existsiVecGU pred (a:Vector<_>) =
+            let mA = a.NumRows
+            (0,mA-1) |> existsR (fun i ->
+            pred i a.[i])
+
+        let sumDenseMatrixGU  (a:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            foldDenseMatrixGU (fun acc aij -> add ops acc aij) ops.Zero a
+
+        let sumSparseMatrixGU  (a:SparseMatrix<_>) = 
+            let ops = a.ElementOps 
+            a |> nonZeroEntriesSparseMatrixGU |> Seq.fold (fun acc (_,_,aij) -> add ops acc aij) ops.Zero
+
+        let sumVecGU (a:Vector<_>) = 
+            let ops = a.ElementOps 
+            foldVecGU (fun acc ai -> add ops acc ai) ops.Zero a
+
+        let prodDenseMatrixGU (a:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            foldDenseMatrixGU (fun acc aij -> mul ops acc aij) ops.One a
+
+        let prodSparseMatrixGU  (a:SparseMatrix<_>) = a |> toDenseSparseMatrixGU |> prodDenseMatrixGU
+
+        let inline fold2DenseMatrixGU f z (a:DenseMatrix<_>) (b:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA <> nB || mA <> mB then invalidArg "b" "the two matrices do not have compatible dimensions"
+            let arrA = a.Values 
+            let arrB = b.Values 
+            let mutable acc = z
+            for i = 0 to mA-1 do
+                for j = 0 to nA-1 do 
+                   acc <- f acc (getArray2D arrA i j) (getArray2D arrB i j)
+            acc
+
+        let inline fold2VecGU f z (a:Vector<_>) (b:Vector<_>) =
+            let mA = a.NumRows
+            let mB = b.NumRows
+            if  mA <> mB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            let mutable acc = z
+            for i = 0 to mA-1 do acc <- f acc a.[i] b.[i]
+            acc
+
+        let dotDenseMatrixGU (a:DenseMatrix<_>) b =
+            let ops = a.ElementOps 
+            fold2DenseMatrixGU (fun z va vb -> add ops z (mul ops va vb)) ops.Zero a b
+
+        let dotVecGU (a:Vector<_>) b =
+            let ops =   a.ElementOps
+            let zero = ops.Zero 
+            fold2VecGU  (fun z va vb -> add ops z (mul ops va vb)) zero a b 
+
+        let normDenseMatrixGU (a:DenseMatrix<_>) = 
+            let normOps = getNormOps a.ElementOps
+            foldDenseMatrixGU (fun z aij -> z + ((normOps.Norm aij)**2.0)) 0.0 a |> sqrt
+
+        let normSparseMatrixGU (a:SparseMatrix<_>) = 
+            let normOps = getNormOps a.ElementOps
+            a |> nonZeroEntriesSparseMatrixGU |> Seq.fold (fun acc (_,_,aij) -> acc + ((normOps.Norm aij)**2.0)) 0.0 |> sqrt
+
+        let inplaceAddDenseMatrixGU  (a:DenseMatrix<_>) (b:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            let arrB = b.Values 
+            inplace_mapiDenseMatrixGU  (fun i j x -> add ops x (getArray2D arrB i j)) a
+        
+        let inplaceAddVecGU  (a:Vector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiVecGU  (fun i x   -> add ops x b.[i]) a
+
+        let inplaceAddRowVecGU (a:RowVector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiRowVecGU (fun i x   -> add ops x b.[i]) a
+
+        let inplaceSubDenseMatrixGU  (a:DenseMatrix<_>) (b:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            let arrB = b.Values 
+            inplace_mapiDenseMatrixGU  (fun i j x -> sub ops x (getArray2D  arrB i j)) a
+
+        let inplaceSubVecGU (a:Vector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps
+            inplace_mapiVecGU  (fun i x   -> sub ops x b.[i]) a
+
+        let inplaceSubRowVecGU (a:RowVector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiRowVecGU (fun i x   -> sub ops x b.[i]  ) a
+
+        let inplaceCptMulDenseMatrixGU  (a:DenseMatrix<_>) (b:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            let arrB = b.Values 
+            inplace_mapiDenseMatrixGU  (fun i j x -> mul ops x (getArray2D  arrB i j)) a
+
+        let inplaceCptMulVecGU (a:Vector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps  
+            inplace_mapiVecGU  (fun i x   -> mul ops x b.[i]) a
+
+        let inplaceCptMulRowVecGU (a:RowVector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiRowVecGU (fun i x   -> mul ops x b.[i]  ) a
+
+        let inplaceScaleDenseMatrixGU  x (a:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiDenseMatrixGU  (fun _ _ y -> ops.Multiply(x,y)) a
+
+        let inplaceScaleVecGU  x (a:Vector<_>) = 
+            let ops = a.ElementOps  
+            inplace_mapiVecGU  (fun _ y   -> ops.Multiply(x,y)) a
+
+        let inplaceScaleRowVecGU x (a:RowVector<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiRowVecGU (fun _ y   -> ops.Multiply(x,y)) a
+
+
+        let wrapList (pre,mid,post,trim) show l = 
+            let post = if trim then "; ..." + post else post
+            match l with 
+            | []    -> [pre;post]
+            | [x]   -> [pre;show x;post]
+            | x::xs -> [pre;show x] @ (List.collect (fun x -> [mid;show x]) xs) @ [post]
+
+        let showItem opsData  x = 
+            try 
+              let ops = opsOfOpsData opsData 
+              ops.ToString(x,"g10",System.Globalization.CultureInfo.InvariantCulture) 
+            with :? System.NotSupportedException -> (box x).ToString()
+        
+        let mapR f (n,m) = if m < n then [] else List.init (m-n+1) (fun i -> f (n+i))
+
+        let primShowDenseMatrixGU (sepX,sepR) (a : DenseMatrix<'e>) =
+            let nA = min a.NumCols DenseMaxDisplay
+            let mA = min a.NumRows DenseMaxDisplay
+            let ops = a.OpsData 
+            let showLine i = wrapList ("[",";","]", a.NumCols > nA) (showItem ops) ((0,nA-1) |> mapR  (fun j -> a.[i,j])) |> Array.ofList |> System.String.Concat
+            wrapList (string nA + " " + string mA + "matrix [",";"+sepX,"]"+sepR, a.NumRows > mA) showLine [0..mA-1] |> Array.ofList |> System.String.Concat
+
+        let showDenseMatrixGU     m = primShowDenseMatrixGU ("\n","\n") m
+        let debugShowDenseMatrixGU m = primShowDenseMatrixGU (""  ,""  ) m
+        
+        let showVecGU s (a : Vector<_>) =
+            let mA = min a.NumRows VectorMaxDisplay
+            let ops = a.OpsData 
+            wrapList (s+" [",";","]",a.NumRows > mA) (showItem ops) ((0,mA-1) |> mapR  (fun i -> a.[i])) |> Array.ofList |> System.String.Concat 
+
+        let showRowVecGU s (a : RowVector<_>) =
+            let mA = min a.NumCols VectorMaxDisplay
+            let ops = a.OpsData 
+            wrapList (s+" [",";","]",a.NumCols > mA) (showItem ops) ((0,mA-1) |> mapR  (fun i -> a.[i])) |> Array.ofList |> System.String.Concat 
+
+
+    /// Implementations of operations specific to floating point types
+    module DoubleImpl = 
+
+        module GU = GenericImpl
+        open Instances
+        
+        // Element type OpsData
+        //type elem = float
+        let zero = 0.0
+        let one  = 1.0
+        let inline sub (x:float) (y:float) = x - y
+        let inline add (x:float) (y:float) = x + y
+        let inline mul (x:float) (y:float) = x * y
+        let inline neg (x:float) = -x
+
+        // Specialized: these know the relevant set of 
+        // ops without doing a table lookup based on runtime type
+        let FloatOps = Some (FloatNumerics :> INumeric<float>)
+        let inline initDenseMatrixDS m n f = GU.createDenseMatrixGU FloatOps m n f
+        let inline createRowVecDS m f      = GU.createRowVecGU      FloatOps m f
+        let inline createVecDS m f         = GU.createVecGU         FloatOps m f
+        let inline mkDenseMatrixDS  arr    = GU.mkDenseMatrixGU     FloatOps arr
+        let inline mkRowVecDS arr          = GU.mkRowVecGU          FloatOps arr
+        let inline mkVecDS  arr            = GU.mkVecGU             FloatOps arr
+        let inline listDenseMatrixDS  ll   = GU.listDenseMatrixGU   FloatOps ll
+        let inline listRowVecDS l          = GU.listRowVecGU        FloatOps l
+        let inline listVecDS  l            = GU.listVecGU           FloatOps l
+        let inline seqDenseMatrixDS  ll    = GU.seqDenseMatrixGU    FloatOps ll
+        let inline seqRowVecDS l           = GU.seqRowVecGU         FloatOps l
+        let inline seqVecDS  l             = GU.seqVecGU            FloatOps l
+
+        let constDenseMatrixDS  m n x      = GU.createDenseMatrixGU  FloatOps m n (fun _ _ -> x)
+        let constRowVecDS m x              = GU.createRowVecGU FloatOps m   (fun _ -> x)
+        let constVecDS  m x                = GU.createVecGU  FloatOps m   (fun _ -> x)
+        let scalarDenseMatrixDS   x        = constDenseMatrixDS  1 1 x 
+        let scalarRowVecDS  x              = constRowVecDS 1   x 
+        let scalarVecDS   x                = constVecDS  1   x 
+
+        // Beware - when compiled with non-generic code createArray2D creates an array of null values,
+        // not zero values. Hence the optimized version can only be used when compiling with generics.
+        let inline zeroDenseMatrixDS m n = 
+          let arr = GU.createArray2D m n 
+          GU.mkDenseMatrixGU FloatOps arr
+        // Specialized: these inline down to the efficient loops we need
+        let addDenseMatrixDS     a b = GU.binaryOpDenseMatrixGU  add a b
+        let addSparseDS     a b = GU.binaryOpSparseMatrixGU  add a b
+        let addRowVecDS    a b = GU.binaryOpRowVecGU add a b
+        let addVecDS     a b = GU.binaryOpVecGU  add a b
+        let subDenseMatrixDS     a b = GU.binaryOpDenseMatrixGU  sub a b 
+        let subSparseDS     a b = GU.binaryOpSparseMatrixGU  sub a b 
+        let mulSparseDS     a b = GU.genericMulSparse zero add mul a b
+        let subRowVecDS    a b = GU.binaryOpRowVecGU sub a b 
+        let subVecDS     a b = GU.binaryOpVecGU  sub a b 
+        let cptMulDenseMatrixDS  a b = GU.binaryOpDenseMatrixGU  mul a b
+        let cptMulSparseDS  a b = GU.binaryOpSparseMatrixGU  mul a b
+        let cptMulRowVecDS a b = GU.binaryOpRowVecGU mul a b
+        let cptMulVecDS  a b = GU.binaryOpVecGU  mul a b
+        type smatrix = SparseMatrix<float>
+        type dmatrix = DenseMatrix<float>
+        type vector = Vector<float>
+        type rowvec = RowVector<float>
+        let cptMaxDenseMatrixDS  (a:dmatrix) (b:dmatrix) = GU.binaryOpDenseMatrixGU  max a b
+        let cptMinDenseMatrixDS  (a:dmatrix) (b:dmatrix) = GU.binaryOpDenseMatrixGU  min a b
+        let cptMaxSparseDS  (a:smatrix) (b:smatrix) = GU.binaryOpSparseMatrixGU  max a b
+        let cptMinSparseDS  (a:smatrix) (b:smatrix) = GU.binaryOpSparseMatrixGU  min a b
+        let cptMaxVecDS  (a:vector) (b:vector) = GU.binaryOpVecGU  max a b
+        let cptMinVecDS  (a:vector) (b:vector) = GU.binaryOpVecGU  min a b
+
+        // Don't make any mistake about these ones re. performance.
+        let mulDenseMatrixDS (a:dmatrix) (b:dmatrix) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA<>mB then invalidArg "b" "the two matrices do not have compatible dimensions"
+            let arr = GU.createArray2D mA nB 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            for i = 0 to mA - 1 do 
+                for j = 0 to nB - 1 do 
+                    let mutable r = 0.0 
+                    for k = 0 to mB - 1 do 
+                        r <- r + mul (GU.getArray2D arrA i k) (GU.getArray2D arrB k j)
+                    GU.setArray2D arr i j r
+            mkDenseMatrixDS arr
+
+        let mulRowVecDenseMatrixDS (a:rowvec) (b:dmatrix) =
+            let nA = a.NumCols 
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
+            let arr = Array.zeroCreate nB 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            for j = 0 to nB - 1 do 
+                let mutable r = 0.0 
+                for k = 0 to mB - 1 do 
+                    r <- r + mul arrA.[k] (GU.getArray2D arrB k j)
+                arr.[j] <- r
+            mkRowVecDS arr
+
+        let mulDenseMatrixVecDS (a:dmatrix) (b:vector) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let mB = b.NumRows 
+            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
+            let arr = Array.zeroCreate mA 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            for i = 0 to mA - 1 do 
+                let mutable r = 0.0 
+                for k = 0 to nA - 1 do 
+                    r <- r + mul (GU.getArray2D arrA i k) arrB.[k]
+                arr.[i] <- r
+            mkVecDS arr
+
+        let mulRowVecVecDS (a:rowvec) (b:vector) =
+            let nA = a.NumCols 
+            let mB = b.NumRows 
+            if nA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            let arrA = a.Values 
+            let arrB = b.Values 
+            let mutable r = 0.0 
+            for k = 0 to nA - 1 do 
+                r <- r + mul arrA.[k] arrB.[k]
+            r
+
+        let rowvecDenseMatrixDS (x:rowvec) = initDenseMatrixDS 1          x.NumCols (fun _ j -> x.[j]) 
+        let vectorDenseMatrixDS (x:vector) = initDenseMatrixDS x.NumRows  1         (fun i _ -> x.[i]) 
+        let mulVecRowVecDS a b = mulDenseMatrixDS (vectorDenseMatrixDS a) (rowvecDenseMatrixDS b) 
+
+        let scaleDenseMatrixDS   k m = GU.unaryOpDenseMatrixGU  (fun x -> mul k x) m
+        let scaleSparseDS   k m = GU.unaryOpSparseGU  (fun x -> mul k x) m
+        let scaleRowVecDS  k m = GU.unaryOpRowVecGU (fun x -> mul k x) m
+        let scaleVecDS   k m = GU.unaryOpVectorGU  (fun x -> mul k x) m
+        let negDenseMatrixDS     m   = GU.unaryOpDenseMatrixGU  (fun x -> neg x) m
+        let negSparseDS     m   = GU.unaryOpSparseGU  (fun x -> neg x) m
+        let negRowVecDS    m   = GU.unaryOpRowVecGU (fun x -> neg x) m
+        let negVecDS     m   = GU.unaryOpVectorGU  (fun x -> neg x) m
+
+        let traceDenseMatrixDS (a:dmatrix) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            if nA<>mA then invalidArg "a" "expected a square matrix";
+            let arrA = a.Values 
+            (0,nA-1) |> GU.sumfR (fun i -> GU.getArray2D arrA i i) 
+
+        let sumDenseMatrixDS  a = GU.foldDenseMatrixGU add zero a
+        let sumVecDS   a = GU.foldVecGU  add zero a
+        let prodDenseMatrixDS a = GU.foldDenseMatrixGU mul one  a
+        let prodVecDS  a = GU.foldVecGU  mul one  a
+
+        let dotDenseMatrixDS a b = GU.fold2DenseMatrixGU (fun z va vb -> add z (mul va vb)) zero a b
+        let dotVecDS a b = GU.fold2VecGU (fun z va vb -> add z (mul va vb)) zero a b
+        let sumfDenseMatrixDS  f m = GU.foldDenseMatrixGU (fun acc aij -> add acc (f aij)) zero m
+        let normDenseMatrixDS m = sqrt (sumfDenseMatrixDS (fun x -> x*x) m)
+
+        let inplaceAddDenseMatrixDS  a (b:DenseMatrix<_>) = let arrB = b.Values  in GU.inplace_mapiDenseMatrixGU  (fun i j x -> x + GU.getArray2D arrB i j) a
+        let inplaceAddVecDS    a (b:Vector<_>) = let arrB = b.Values  in GU.inplace_mapiVecGU  (fun i x   -> x + arrB.[i]) a
+        let inplace_addRowVecDS a (b:RowVector<_>) = let arrB = b.Values in GU.inplace_mapiRowVecGU (fun i x   -> x + arrB.[i]) a
+        let inplaceSubDenseMatrixDS  a (b:DenseMatrix<_>) = let arrB = b.Values  in GU.inplace_mapiDenseMatrixGU  (fun i j x -> x - GU.getArray2D  arrB i j) a
+        let inplaceSubVecDS  a (b:Vector<_>) = let arrB = b.Values  in GU.inplace_mapiVecGU  (fun i x   -> x - arrB.[i]) a
+        let inplace_subRowVecDS a (b:RowVector<_>) = let arrB = b.Values in GU.inplace_mapiRowVecGU (fun i x   -> x - arrB.[i]) a
+        let inplaceCptMulDenseMatrixDS  a (b:DenseMatrix<_>) = let arrB = b.Values  in GU.inplace_mapiDenseMatrixGU  (fun i j x -> x * GU.getArray2D arrB i j) a
+        let inplaceCptMulVecDS  a (b:Vector<_>) = let arrB = b.Values  in GU.inplace_mapiVecGU  (fun i x   -> x * arrB.[i]) a
+        let inplace_cptMulRowVecDS a (b:RowVector<_>) = let arrB = b.Values in GU.inplace_mapiRowVecGU (fun i x   -> x * arrB.[i]) a
+        let inplaceScaleDenseMatrixDS  (a:float) b = GU.inplace_mapiDenseMatrixGU  (fun _ _ x -> a * x) b
+        let inplaceScaleVecDS  (a:float) b = GU.inplace_mapiVecGU  (fun _ x   -> a * x) b
+        let inplace_scaleRowVecDS (a:float) b = GU.inplace_mapiRowVecGU (fun _ x   -> a * x) b
+
+
+
+    /// Generic operations that, when used on floating point types, use the specialized versions in DoubleImpl
+    module SpecializedGenericImpl = 
+
+        open Microsoft.FSharp.Math.Instances
+        open Microsoft.FSharp.Math.GlobalAssociations
+
+        module GU = GenericImpl
+        module DS = DoubleImpl
+
+          
+        type smatrix = SparseMatrix<float>
+        type dmatrix = DenseMatrix<float>
+        type vector = Vector<float>
+        type rowvec = RowVector<float>
+        let inline dense x = DenseRepr(x)
+        let inline sparse x = SparseRepr(x)
+        let inline createMx  ops rows columns f = GU.createDenseMatrixGU ops rows columns f |> dense
+        let inline createVx  ops m f   = GU.createVecGU ops m f
+        let inline createRVx ops m f   = GU.createRowVecGU ops m f
+
+        let nonZeroEntriesM a   = 
+            match a with 
+            | DenseRepr a -> GU.nonzeroEntriesDenseMatrixGU a 
+            | SparseRepr a -> GU.nonZeroEntriesSparseMatrixGU a 
+
+        /// Merge two sorted sequences
+        let mergeSorted cf (s1: seq<'T>) (s2: seq<'b>) =
+            seq { use e1 = s1.GetEnumerator()
+                  use e2 = s2.GetEnumerator()
+                  let havee1 = ref (e1.MoveNext())
+                  let havee2 = ref (e2.MoveNext())
+                  while !havee1 || !havee2 do
+                    if !havee1 && !havee2 then
+                        let v1 = e1.Current
+                        let v2 = e2.Current
+                        let c = cf v1 v2 
+                        if c < 0 then 
+                            do havee1 := e1.MoveNext()
+                            yield Some(v1),None
+                        elif c = 0 then
+                            do havee1 := e1.MoveNext()
+                            do havee2 := e2.MoveNext()
+                            yield Some(v1),Some(v2)
+                        else 
+                            do havee2 := e2.MoveNext()
+                            yield (None,Some(v2))
+                    elif !havee1 then 
+                        let v1 = e1.Current
+                        do havee1 := e1.MoveNext()
+                        yield (Some(v1),None)
+                    else 
+                        let v2 = e2.Current
+                        do havee2 := e2.MoveNext()
+                        yield (None,Some(v2)) }
+
+        /// Non-zero entries from two sequences
+        let mergedNonZeroEntriesM  (a:Matrix<_>) (b:Matrix<_>) = 
+            let ops = a.ElementOps 
+            let zero = ops.Zero
+            mergeSorted (fun (i1,j1,_) (i2,j2,_) -> let c = compare i1 i2 in if c <> 0 then c else compare j1 j2) (nonZeroEntriesM a) (nonZeroEntriesM b)
+            |> Seq.map (function | Some(i,j,v1),Some(_,_,v2) -> (v1,v2)
+                                 | Some(i,j,v1),None         -> (v1,zero)
+                                 | None,        Some(i,j,v2) -> (zero,v2)
+                                 | None,        None          -> failwith "unreachable")
+
+
+        
+        // Creation
+        let listM    xss : Matrix<'T>    = GU.listDenseMatrixGU opsdata<'T> xss |> dense
+        let listV    xss : Vector<'T>    = GU.listVecGU         opsdata<'T> xss
+        let listRV   xss : RowVector<'T> = GU.listRowVecGU      opsdata<'T> xss
+
+        let arrayM    xss : Matrix<'T>    = GU.mkDenseMatrixGU  opsdata<'T> (Array2D.copy xss) |> dense
+        let arrayV    xss : Vector<'T>    = GU.mkVecGU          opsdata<'T> (Array.copy xss)
+        let arrayRV   xss : RowVector<'T> = GU.mkRowVecGU       opsdata<'T> (Array.copy xss)
+
+        let seqM    xss : Matrix<'T>    = GU.seqDenseMatrixGU   opsdata<'T> xss |> dense
+        let seqV    xss : Vector<'T>    = GU.seqVecGU           opsdata<'T> xss
+        let seqRV   xss : RowVector<'T> = GU.seqRowVecGU        opsdata<'T> xss
+
+        let initM  m n f : Matrix<'T>    = GU.createDenseMatrixGU opsdata<'T> m n f |> dense
+        let initRV m   f : RowVector<'T> = GU.createRowVecGU      opsdata<'T> m   f
+        let initV  m   f : Vector<'T>    = GU.createVecGU         opsdata<'T> m   f
+
+        let constM  m n x : Matrix<'T>    = GU.createConstDenseMatrixGU opsdata<'T> m n x |> dense
+        let constRV m   x : RowVector<'T> = GU.createConstRowVecGU      opsdata<'T> m   x
+        let constV  m   x : Vector<'T>    = GU.createConstVecGU         opsdata<'T> m   x
+
+        let inline inplaceAssignM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNotMutable()
+            | DenseRepr a -> GU.assignDenseMatrixGU  f a
+        let inline assignV  f a = GU.assignVecGU  f a
+
+        let coerce2 x = unbox(box(x))
+        let loosenDM (x: dmatrix) : DenseMatrix<_>  = coerce2 x
+        let loosenSM (x: smatrix) : SparseMatrix<_> = coerce2 x
+        let loosenV  (x: vector)  : Vector<_>       = coerce2 x
+        let loosenRV (x: rowvec)  : RowVector<_>    = coerce2 x
+        let loosenF  (x: float)   : 'T              = coerce2 x
+
+        let tightenDM (x: DenseMatrix<_>)  : dmatrix = coerce2 x
+        let tightenSM (x: SparseMatrix<_>) : smatrix = coerce2 x
+        let tightenV  (x: Vector<_>)       : vector  = coerce2 x
+        let tightenRV (x: RowVector<_>)    : rowvec  = coerce2 x
+        let tightenF  (x: 'T)              : float   = coerce2 x
+
+        let zeroM m n = 
+            let arr = GU.createArray2D m n
+            // This is quite performance critical
+            // Avoid assigining zeros into the array
+            match box arr with 
+            | :? (float[,])   as arr -> GU.mkDenseMatrixGU DS.FloatOps arr |> loosenDM |> dense
+            | _ -> 
+            GU.zeroizeDenseMatrixGUA arr m n  |> dense
+
+        let zeroV m  : Vector<'T> = 
+            let arr = GU.createArray m 
+            // Avoid assigining zeros into the array
+            match box (arr: 'T[]) with 
+            | :? (float[])   as arr -> GU.mkVecGU DS.FloatOps arr |> loosenV
+            | _ -> 
+            GU.zeroizeVecGUA arr m
+
+        let zeroRV m  : RowVector<'T> = 
+            let arr = GU.createArray m 
+            // Avoid assigining zeros into the array
+            match box (arr: 'T[]) with 
+            | :? (float[])   as arr -> GU.mkRowVecGU DS.FloatOps arr |> loosenRV
+            | _ -> 
+            GU.zeroizeRowVecGUA arr m
+            
+        let initNumericM m n f   = 
+            let arr = GU.createArray2D m n 
+            let opsData = opsdata<'T> 
+            let ops = GU.opsOfOpsData opsData 
+            GU.assignArray2D m n (f ops) arr;
+            GU.mkDenseMatrixGU opsData arr |> dense
+
+        let identityM m   = 
+            let arr = GU.createArray2D m m 
+            // This is quite performance critical
+            // Avoid assigining zeros into the array
+            match box arr with 
+            | :? (float[,])   as arr -> 
+                for i = 0 to m - 1 do 
+                   arr.[i,i] <- 1.0 
+                GU.mkDenseMatrixGU DS.FloatOps arr |> loosenDM |> dense
+            | _ -> 
+            let opsData = opsdata<'T> 
+            let ops = GU.opsOfOpsData opsData 
+            let zero = ops.Zero 
+            let one = ops.One 
+            GU.assignArray2D m m (fun i j -> if i = j then one else zero) arr;
+            GU.mkDenseMatrixGU opsData arr |> dense
+
+        let createNumericV m f  : Vector<'T> = 
+            let arr = GU.createArray m 
+            let opsData = opsdata<'T> 
+            let ops = GU.opsOfOpsData opsData 
+            GU.assignArray m (f ops) arr;
+            GU.mkVecGU opsData arr
+            
+        let scalarM   x = constM 1 1 x 
+        let scalarRV  x = constRV 1 x 
+        let scalarV   x = constV 1 x 
+
+        let diagnM (v:Vector<_>) n = 
+            let ops = v.ElementOps
+            let zero = ops.Zero 
+            let nV = v.NumRows + (if n < 0 then -n else n) 
+            createMx v.OpsData nV nV (fun i j -> if i+n=j then v.[i] else zero)
+
+        let diagM v = diagnM v 0
+
+        let constDiagM  n x : Matrix<'T> = 
+            let opsData = opsdata<'T> 
+            let ops = GU.opsOfOpsData opsData 
+            let zero = ops.Zero 
+            createMx opsData n n (fun i j -> if i=j then x else zero) 
+
+        // Note: we drop sparseness on pointwise multiplication of sparse and dense.
+        let inline binaryOpM opDenseDS opDenseGU opSparseDS opSparseMatrixGU a b = 
+            match a,b with 
+            | DenseRepr a,DenseRepr b -> 
+                match box a with 
+                | (:? dmatrix as a) -> opDenseDS   a (tightenDM b) |> loosenDM |> dense
+                | _                 -> opDenseGU a b                           |> dense
+            | SparseRepr a,SparseRepr b ->
+                match box a with 
+                | (:? smatrix as a) -> opSparseDS a (tightenSM b) |> loosenSM |> sparse
+                | _                 -> opSparseMatrixGU a b                         |> sparse
+            | SparseRepr a, DenseRepr b     -> opDenseGU (GU.toDenseSparseMatrixGU a) b         |> dense
+            | DenseRepr  a, SparseRepr b    -> opDenseGU a (GU.toDenseSparseMatrixGU b)         |> dense
+
+        let inline unaryOpM opDenseDS opDenseGU opSparseDS opSparseMatrixGU  b = 
+            match b with 
+            | DenseRepr b -> 
+                match box b with 
+                | (:? dmatrix as b)  -> opDenseDS b |> loosenDM |> dense
+                | _                  -> opDenseGU b             |> dense
+            | SparseRepr b ->             
+                match box b with 
+                | (:? smatrix as b) -> opSparseDS b |> loosenSM |> sparse
+                | _                 -> opSparseMatrixGU b             |> sparse
+
+        let inline floatUnaryOpM opDenseDS opDenseGU opSparseDS opSparseMatrixGU  b = 
+            match b with 
+            | DenseRepr b -> 
+                match box b with 
+                | (:? dmatrix as b)  -> opDenseDS b |> loosenF
+                | _                  -> opDenseGU b             
+            | SparseRepr b ->             
+                match box b with 
+                | (:? smatrix as b) -> opSparseDS b |> loosenF 
+                | _                 -> opSparseMatrixGU b             
+
+        let addM a b = binaryOpM DS.addDenseMatrixDS GU.addDenseMatrixGU DS.addSparseDS GU.addSparseMatrixGU a b
+        let subM a b = binaryOpM DS.subDenseMatrixDS GU.subDenseMatrixGU DS.subSparseDS GU.subSparseMatrixGU a b
+        let mulM a b = binaryOpM DS.mulDenseMatrixDS GU.genericMulDenseMatrix DS.mulSparseDS GU.mulSparseMatrixGU a b
+        let cptMulM a b = binaryOpM DS.cptMulDenseMatrixDS GU.cptMulDenseMatrixGU DS.cptMulSparseDS GU.cptMulSparseMatrixGU a b
+        let cptMaxM a b = binaryOpM DS.cptMaxDenseMatrixDS GU.cptMaxDenseMatrixGU DS.cptMaxSparseDS GU.cptMaxSparseMatrixGU a b
+        let cptMinM a b = binaryOpM DS.cptMinDenseMatrixDS GU.cptMinDenseMatrixGU DS.cptMinSparseDS GU.cptMinSparseMatrixGU a b
+
+        let addRV a b = 
+            match box a with 
+            | (:? rowvec as a) -> DS.addRowVecDS a (tightenRV b) |> loosenRV
+            | _                -> GU.addRowVecGU a b
+
+        let addV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.addVecDS a (tightenV b) |> loosenV
+            | _                -> GU.addVecGU a b
+
+        let subRV a b = 
+            match box a with 
+            | (:? rowvec as a) -> DS.subRowVecDS   a (tightenRV b) |> loosenRV
+            | _                -> GU.subRowVecGU a b
+
+        let subV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.subVecDS   a (tightenV b) |> loosenV
+            | _                -> GU.subVecGU a b
+
+        let mulRVM a b = 
+            match b with 
+            | DenseRepr b -> 
+                match box a with 
+                | (:? rowvec as a) -> DS.mulRowVecDenseMatrixDS   a (tightenDM b) |> loosenRV
+                | _                -> GU.mulRowVecDenseMatrixGU a b
+            | SparseRepr b -> GU.mulRVSparseMatrixGU a b
+
+        let mulMV a b = 
+            match a with 
+            | DenseRepr a -> 
+                match box a with 
+                | (:? dmatrix as a) -> DS.mulDenseMatrixVecDS   a (tightenV b) |> loosenV
+                | _                 -> GU.mulDenseMatrixVecGU a b
+            | SparseRepr a -> GU.mulSparseVecGU a b 
+
+        let mulRVV a b = 
+            match box a with 
+            | (:? rowvec as a) -> DS.mulRowVecVecDS   a (tightenV b) |> loosenF
+            | _                -> GU.mulRowVecVecGU a b
+
+        let mulVRV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.mulVecRowVecDS   a (tightenRV b) |> loosenDM |> dense
+            | _                -> GU.mulVecRowVecGU a b |> dense
+
+        let cptMulRV a b = 
+            match box a with 
+            | (:? rowvec as a) -> DS.cptMulRowVecDS   a (tightenRV b) |> loosenRV
+            | _                -> GU.cptMulRowVecGU a b
+
+        let cptMulV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.cptMulVecDS   a (tightenV b) |> loosenV
+            | _                -> GU.cptMulVecGU a b
+
+        let cptMaxV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.cptMaxVecDS   a (tightenV b) |> loosenV
+            | _                -> GU.cptMaxVecGU a b
+
+        let cptMinV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.cptMinVecDS   a (tightenV b) |> loosenV
+            | _                -> GU.cptMinVecGU a b
+
+        let scaleM a b = unaryOpM (fun b -> DS.scaleDenseMatrixDS (tightenF a) b) (GU.scaleDenseMatrixGU a)
+                                  (fun b -> DS.scaleSparseDS (tightenF a) b) (GU.scaleSparseMatrixGU a) b
+
+        let scaleRV a b = 
+            match box b with 
+            | (:? rowvec as b)  -> DS.scaleRowVecDS (tightenF a) b |> loosenRV 
+            | _                 -> GU.scaleRowVecGU a b
+
+        let scaleV a b = 
+            match box b with 
+            | (:? vector as b)  -> DS.scaleVecDS (tightenF a) b |> loosenV
+            | _                 -> GU.scaleVecGU a b
+
+        let dotM a b = 
+            match a,b with 
+            | DenseRepr a,DenseRepr b -> 
+                match box b with 
+                | (:? dmatrix as b)  -> DS.dotDenseMatrixDS   (tightenDM a) b |> loosenF
+                | _                  -> GU.dotDenseMatrixGU a b
+            | _ ->  
+                let ops = a.ElementOps 
+                mergedNonZeroEntriesM a b |> Seq.fold (fun z (va,vb) -> GU.add ops z (GU.mul ops va vb)) ops.Zero 
+
+        let dotV a b = 
+            match box b with 
+            | (:? vector as b)  -> DS.dotVecDS   (tightenV a) b |> loosenF
+            | _                 -> GU.dotVecGU a b
+
+        let negM a = unaryOpM DS.negDenseMatrixDS GU.negDenseMatrixGU DS.negSparseDS GU.negSparseMatrixGU a
+
+        let negRV a = 
+            match box a with 
+            | (:? rowvec as a) -> DS.negRowVecDS a |> loosenRV
+            | _               ->  GU.negRowVecGU a
+
+        let negV a = 
+            match box a with 
+            | (:? vector as a) -> DS.negVecDS a |> loosenV
+            | _               ->  GU.negVecGU a
+
+        let traceMGU (a:Matrix<_>) =
+            let nA = a.NumCols  
+            let mA = a.NumRows 
+            if nA<>mA then invalidArg "a" "expected a square matrix";
+            let ops = a.ElementOps 
+            (0,nA-1) |> GU.sumRGU ops (fun i -> a.[i,i]) 
+
+        let traceM a = floatUnaryOpM DS.traceDenseMatrixDS (dense >> traceMGU) (sparse >> traceMGU) (sparse >> traceMGU) a
+        let sumM a = floatUnaryOpM DS.sumDenseMatrixDS GU.sumDenseMatrixGU GU.sumSparseMatrixGU GU.sumSparseMatrixGU a
+        let prodM a = floatUnaryOpM DS.prodDenseMatrixDS GU.prodDenseMatrixGU GU.prodSparseMatrixGU GU.prodSparseMatrixGU a
+        let normM a = floatUnaryOpM DS.normDenseMatrixDS GU.normDenseMatrixGU GU.normSparseMatrixGU GU.normSparseMatrixGU a
+
+        let opsM a = 
+            match a with 
+            | DenseRepr a -> a.OpsData 
+            | SparseRepr a -> a.OpsData 
+        
+        let transM a = 
+            match a with 
+            | DenseRepr a -> 
+                // rows of transposed matrix = columns of original matrix and vice versa
+                createMx a.OpsData a.NumCols a.NumRows (fun i j -> a.[j,i])
+            | SparseRepr a -> 
+                a |> GU.nonZeroEntriesSparseMatrixGU  |> Seq.map (fun (i,j,v) -> (j,i,v)) |> GU.initSparseMatrixGU a.NumCols a.NumRows a.OpsData |> sparse
+        
+        let permuteRows (p: permutation) a =
+            match a with
+            | DenseRepr a ->
+                createMx a.OpsData a.NumRows a.NumCols (fun i j -> a.[p i,j])
+            | SparseRepr a ->
+                a |> GU.nonZeroEntriesSparseMatrixGU  |> Seq.map (fun (i,j,v) -> (p i,j,v)) |> GU.initSparseMatrixGU a.NumCols a.NumRows a.OpsData |> sparse
+
+        let permuteColumns (p: permutation) a =
+            match a with
+            | DenseRepr a ->
+                createMx a.OpsData a.NumRows a.NumCols (fun i j -> a.[i,p j])
+            | SparseRepr a ->
+                a |> GU.nonZeroEntriesSparseMatrixGU  |> Seq.map (fun (i,j,v) -> (i,p j,v)) |> GU.initSparseMatrixGU a.NumCols a.NumRows a.OpsData |> sparse
+
+        let transRV (a:RowVector<_>) = 
+            createVx a.OpsData  a.NumCols (fun i -> a.[i])
+
+        let transV (a:Vector<_>)  = 
+            createRVx a.OpsData a.NumRows (fun i -> a.[i])
+
+        let inplaceAddM a b = 
+            match a,b with 
+            | DenseRepr a,DenseRepr b -> 
+                match box a with 
+                | (:? dmatrix as a) -> DS.inplaceAddDenseMatrixDS   a (tightenDM b)
+                | _                 -> GU.inplaceAddDenseMatrixGU a b
+            | _ -> sparseNotMutable()
+
+        let inplaceAddV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.inplaceAddVecDS   a (tightenV b)
+            | _                -> GU.inplaceAddVecGU a b
+
+        let inplaceSubM a b = 
+            match a,b with 
+            | DenseRepr a,DenseRepr b -> 
+                match box a with 
+                | (:? dmatrix as a) -> DS.inplaceSubDenseMatrixDS   a (tightenDM b)
+                | _                -> GU.inplaceSubDenseMatrixGU a b
+            | _ -> sparseNotMutable()
+
+        let inplaceSubV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.inplaceSubVecDS   a (tightenV b)
+            | _                -> GU.inplaceSubVecGU a b
+
+
+        let inplaceCptMulM a b = 
+            match a,b with 
+            | DenseRepr a,DenseRepr b -> 
+                match box a with 
+                | (:? dmatrix as a) -> DS.inplaceCptMulDenseMatrixDS   a (tightenDM b)
+                | _                -> GU.inplaceCptMulDenseMatrixGU a b
+            | _ -> sparseNotMutable()
+
+        let inplaceCptMulV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.inplaceCptMulVecDS   a (tightenV b)
+            | _                -> GU.inplaceCptMulVecGU a b
+
+        let inplaceScaleM a b = 
+            match b with 
+            | DenseRepr b -> 
+                match box b with 
+                | (:? dmatrix as b)  -> DS.inplaceScaleDenseMatrixDS   (tightenF a) b
+                | _                 -> GU.inplaceScaleDenseMatrixGU a b
+            | _ -> sparseNotMutable()
+
+        let inplaceScaleV a b = 
+            match box b with 
+            | (:? vector as b)  -> DS.inplaceScaleVecDS   (tightenF a) b
+            | _                 -> GU.inplaceScaleVecGU a b
+
+        let existsM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI() // note: martin says "run f on a token element if it's not full"
+            | DenseRepr a -> GU.existsiDenseMatrixGU  (fun _ _ -> f) a
+
+        let existsV  f a = GU.existsiVecGU  (fun _ -> f) a
+
+        let forallM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> GU.foralliDenseMatrixGU  (fun _ _ -> f) a
+
+        let forallV  f a = GU.foralliVecGU  (fun _ -> f) a
+
+        let existsiM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> GU.existsiDenseMatrixGU  f a
+
+        let existsiV  f a = GU.existsiVecGU  f a
+
+        let foralliM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> GU.foralliDenseMatrixGU  f a
+
+        let foralliV  f a = GU.foralliVecGU  f a
+
+        let mapM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> DenseRepr(GU.mapDenseMatrixGU f a)
+
+        let mapV  f a = GU.mapVecGU f a
+
+        let copyM  a = 
+            match a with 
+            | SparseRepr a -> SparseRepr (GU.copySparseGU a)
+            | DenseRepr a -> DenseRepr (GU.copyDenseMatrixGU a)
+
+        let copyV  a = GU.copyVecGU a
+
+        let copyRV  a = GU.copyRowVecGU a
+
+        let mapiM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> DenseRepr (GU.mapiDenseMatrixGU f a)
+
+        let mapiV  f a = GU.mapiVecGU f a
+        let permuteV p a = GU.permuteVecGU p a
+        let permuteRV p a = GU.permuteRowVecGU p a
+
+        let mapiRV  f a = GU.mapiRowVecGU f a
+
+        let toDenseM a = 
+            match a with 
+            | SparseRepr a -> GU.toDenseSparseMatrixGU a |> dense
+            | DenseRepr _ -> a
+
+        let initSparseM i j x : Matrix<'T> = 
+            let opsData = opsdata<'T> 
+            GU.initSparseMatrixGU i j opsData x |> sparse
+          
+        let initDenseM i j x : Matrix<'T> = 
+            let r = zeroM i j
+            x |> Seq.iter (fun (i,j,v) -> r.[i,j] <- v);
+            r
+
+        let getDiagnM (a:Matrix<_>) n =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            if nA<>mA then invalidArg "a" "expected a square matrix";
+            let ni = if n < 0 then -n else 0 
+            let nj = if n > 0 then  n else 0 
+            GU.createVecGU (opsM a) (max (nA-abs(n)) 0) (fun i -> a.[i+ni,i+nj]) 
+
+        let getDiagM  a = getDiagnM a 0
+
+        let inline inplace_mapiM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNotMutable()
+            | DenseRepr a -> GU.inplace_mapiDenseMatrixGU f a
+
+        let inline inplace_mapiV  f a = GU.inplace_mapiVecGU f a
+        
+        let inline foldM  f z a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> GU.foldDenseMatrixGU f z a
+
+        let inline foldV  f z a = GU.foldVecGU f z a
+
+        let inline foldiM  f z a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> GU.foldiDenseMatrixGU f z a
+
+        let inline foldiV  f z a = GU.foldiVecGU f z a
+
+        let compareM (comp: IComparer) (a:Matrix<'T>) (b:Matrix<'T>) = 
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let nB = b.NumCols 
+            let mB = b.NumRows 
+            let c = compare mA mB 
+            if c <> 0 then c else
+            let c = compare nA nB 
+            if c <> 0 then c else
+            match a,b with 
+            | DenseRepr a, DenseRepr b -> 
+              let rec go2 i j = 
+                 if j < nA then 
+                   let c = comp.Compare( a.[i,j], b.[i,j])
+                   if c <> 0 then c else 
+                   go2 i (j+1) 
+                 else 0 
+              let rec go1 i = 
+                 if i < mA then 
+                   let c = go2 i 0 
+                   if c <> 0 then c 
+                   else go1 (i+1) 
+                 else 0 
+              go1 0
+            | _ -> 
+              match (mergedNonZeroEntriesM a b |> Seq.tryPick (fun (v1,v2) -> let c = comp.Compare(v1,v2) in if c = 0 then None else Some(c))) with
+              | None -> 0
+              | Some(c) -> c
+             
+        let equalsM (comp: IEqualityComparer) (a:Matrix<'T>) (b:Matrix<'T>) = 
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let nB = b.NumCols 
+            let mB = b.NumRows 
+            (mA = mB ) && (nA = nB) && 
+            match a,b with 
+            | DenseRepr a, DenseRepr b -> 
+                let rec go2 i j =  j >= nA || (comp.Equals( a.[i,j], b.[i,j]) && go2 i (j+1) )
+                let rec go1 i = i >= mA || (go2 i 0  && go1 (i+1))
+                go1 0
+            | _ -> 
+                mergedNonZeroEntriesM a b |> Seq.forall (fun (v1,v2) -> comp.Equals(v1,v2))
+             
+
+        let compareV (comp: IComparer) (a:Vector<'T>) (b:Vector<'T>) = 
+            let mA = a.NumRows
+            let mB = b.NumRows 
+            let c = compare mA mB 
+            if c <> 0 then c else
+            let rec go2 j = 
+               if j < mA then 
+                 let c = comp.Compare(a.[j],b.[j])
+                 if c <> 0 then c else go2 (j+1) 
+               else 0 
+            go2 0
+
+        let equalsV (comp: IEqualityComparer) (a:Vector<'T>) (b:Vector<'T>) = 
+            let mA = a.NumRows
+            let mB = b.NumRows 
+            (mA = mB) && 
+            let rec go2 j = (j >= mA) || (comp.Equals(a.[j],b.[j]) && go2 (j+1))
+            go2 0
+
+        let equalsRV (comp: IEqualityComparer) (a:RowVector<'T>) (b:RowVector<'T>) = 
+            let mA = a.NumCols 
+            let mB = b.NumCols 
+            (mA = mB) && 
+            let rec go2 j = (j >= mA) || (comp.Equals(a.[j],b.[j]) && go2 (j+1))
+            go2 0
+
+        let compareRV (comp: IComparer) (a:RowVector<'T>) (b:RowVector<'T>) = 
+            let mA = a.NumCols 
+            let mB = b.NumCols 
+            let c = compare mA mB 
+            if c <> 0 then c else
+            let rec go2 j = 
+               if j < mA then 
+                 let c = comp.Compare(a.[j],b.[j])
+                 if c <> 0 then c else go2 (j+1) 
+               else 0 
+            go2 0
+
+        let inline combineHash x y = (x <<< 1) + y + 631 
+
+        let hashM (comp:IEqualityComparer) (a:Matrix<_>) = 
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let acc = hash mA + hash nA
+            a |> nonZeroEntriesM |> Seq.truncate 20 |> Seq.fold (fun z v -> combineHash z (comp.GetHashCode v)) acc
+          
+        let hashV (comp:IEqualityComparer) (a:Vector<_>) = 
+            let mA = a.NumRows 
+            hash mA +
+            (let mutable c = 0 
+             for i = 0 to mA - 1 do
+                 c <- combineHash c (comp.GetHashCode a.[i])
+             c)
+          
+        let hashRV (comp:IEqualityComparer) (a:RowVector<_>) = 
+            let mA = a.NumCols 
+            hash mA +
+            (let mutable c = 0 
+             for i = 0 to mA - 1 do
+                 c <- combineHash c (comp.GetHashCode a.[i])
+             c)
+          
+        type range = int * int
+
+        let startR ((a,_) : range)   = a
+        let countR ((a,b) : range)   = (b-a)+1
+        let idxR    ((a,_) : range) i = a+i
+        let inR    ((a,b) : range) i = a <= i && i <= b
+        
+        let getRowM  (a:Matrix<_>) i = createRVx (opsM a) a.NumCols (fun j -> a.[i,j])
+        let selColM  (a:Matrix<_>) j = createVx (opsM a) a.NumRows (fun i -> a.[i,j]) 
+        let getRegionV  (a:Vector<_>)    r      = createVx a.OpsData (countR r) (fun i -> a.[idxR r i]) 
+        let getRegionRV (a:RowVector<_>) r      = createRVx a.OpsData (countR r) (fun i -> a.[idxR r i]) 
+
+        let getRegionM  a ri rj    = 
+            match a with 
+            | DenseRepr a -> createMx a.OpsData (countR ri) (countR rj) (fun i j -> a.[idxR ri i, idxR rj j]) 
+            | _ -> nonZeroEntriesM a 
+                   |> Seq.filter (fun (i,j,_) -> inR ri i && inR rj j) 
+                   |> Seq.map (fun (i,j,v) -> (i-startR ri,j-startR rj,v)) 
+                   |> initSparseM (countR ri) (countR rj)
+
+        let getColsM (a:Matrix<_>) rj         = getRegionM a (0,a.NumRows - 1) rj
+        let getRowsM (a:Matrix<_>) ri         = getRegionM a ri (0,a.NumCols - 1)
+
+        let rowvecM (x:RowVector<_>) = initM 1         x.NumCols (fun _ j -> x.[j]) 
+        let vectorM (x:Vector<_>) = initM x.NumRows  1         (fun i _ -> x.[i])  
+        let toVectorM x = selColM x 0 
+        let toRowVectorM x = getRowM x 0 
+        let toScalarM (x:Matrix<_>) = x.[0,0]
+
+
+
+//----------------------------------------------------------------------------
+// type Matrix<'T> augmentation
+//--------------------------------------------------------------------------*)
+
+    type Matrix<'T> with
+        static member ( +  )(a: Matrix<'T>,b) = SpecializedGenericImpl.addM a b
+        static member ( -  )(a: Matrix<'T>,b) = SpecializedGenericImpl.subM a b
+        static member ( *  )(a: Matrix<'T>,b) = SpecializedGenericImpl.mulM a b
+        static member ( *  )(a: Matrix<'T>,b : Vector<'T>) = SpecializedGenericImpl.mulMV a b
+
+        static member ( * )((m: Matrix<'T>),k : 'T) = SpecializedGenericImpl.scaleM k m
+
+        static member ( .* )(a: Matrix<'T>,b) = SpecializedGenericImpl.cptMulM a b
+        static member ( * )(k,m: Matrix<'T>) = SpecializedGenericImpl.scaleM k m
+        static member ( ~- )(m: Matrix<'T>)     = SpecializedGenericImpl.negM m
+        static member ( ~+ )(m: Matrix<'T>)     = m
+
+        member m.GetSlice (start1,finish1,start2,finish2) = 
+            let start1 = match start1 with None -> 0 | Some v -> v 
+            let finish1 = match finish1 with None -> m.NumRows - 1 | Some v -> v 
+            let start2 = match start2 with None -> 0 | Some v -> v 
+            let finish2 = match finish2 with None -> m.NumCols - 1 | Some v -> v 
+            SpecializedGenericImpl.getRegionM m (start1,finish1) (start2,finish2)
+
+        member m.SetSlice (start1,finish1,start2,finish2,vs:Matrix<_>) = 
+            let start1 = match start1 with None -> 0 | Some v -> v 
+            let finish1 = match finish1 with None -> m.NumRows - 1 | Some v -> v 
+            let start2 = match start2 with None -> 0 | Some v -> v 
+            let finish2 = match finish2 with None -> m.NumCols - 1 | Some v -> v 
+            for i = start1 to finish1  do 
+               for j = start2 to finish2 do
+                   m.[i,j] <- vs.[i-start1,j-start2]
+
+        override m.ToString() = 
+           match m with 
+           | DenseRepr m -> GenericImpl.showDenseMatrixGU m
+           | SparseRepr _ -> "<sparse>"
+
+        member m.DebugDisplay = 
+           let txt = 
+               match m with 
+               | DenseRepr m -> GenericImpl.debugShowDenseMatrixGU m
+               | SparseRepr _ -> "<sparse>"
+           new System.Text.StringBuilder(txt)  // return an object with a ToString with the right value, rather than a string. (strings get shown using quotes)
+
+        member m.StructuredDisplayAsArray =  
+            let rec layout m = 
+                match m with 
+                | DenseRepr _ -> box (Array2D.init m.NumRows m.NumCols (fun i j -> m.[i,j]))
+                | SparseRepr _ -> (if m.NumRows < 20 && m.NumCols < 20 then layout (SpecializedGenericImpl.toDenseM m) else box(SpecializedGenericImpl.nonZeroEntriesM m))
+            layout m
+        member m.Dimensions = m.NumRows,m.NumCols
+
+        member m.Transpose = SpecializedGenericImpl.transM m
+        member m.PermuteRows (p: permutation) : Matrix<'T> = SpecializedGenericImpl.permuteRows p m
+        member m.PermuteColumns (p: permutation) : Matrix<'T> = SpecializedGenericImpl.permuteColumns p m
+
+        interface IEnumerable<'T> with 
+            member m.GetEnumerator() = 
+               (seq { for i in 0 .. m.NumRows-1 do
+                        for j in 0 .. m.NumCols - 1 do 
+                            yield m.[i,j] }).GetEnumerator()
+
+        interface IEnumerable with 
+            member m.GetEnumerator() =  ((m :> IEnumerable<_>).GetEnumerator() :> IEnumerator)
+                                    
+        interface System.IComparable with 
+             member m.CompareTo(yobj:obj) = SpecializedGenericImpl.compareM LanguagePrimitives.GenericComparer m (yobj :?> Matrix<'T>)
+             
+        interface IStructuralComparable with
+            member m.CompareTo(yobj:obj,comp:System.Collections.IComparer) = SpecializedGenericImpl.compareM comp m (yobj :?> Matrix<'T>)
+            
+        override m.GetHashCode() = SpecializedGenericImpl.hashM LanguagePrimitives.GenericEqualityComparer m 
+        override m.Equals(yobj:obj) = 
+            match yobj with 
+            | :? Matrix<'T> as m2 -> SpecializedGenericImpl.equalsM LanguagePrimitives.GenericEqualityComparer m m2
+            | _ -> false
+        
+        interface IStructuralEquatable with
+            member m.GetHashCode(comp:System.Collections.IEqualityComparer) = SpecializedGenericImpl.hashM comp m
+            member m.Equals(yobj:obj,comp:System.Collections.IEqualityComparer) = 
+                match yobj with 
+                | :? Matrix<'T> as m2 -> SpecializedGenericImpl.equalsM comp m m2
+                | _ -> false
+
+
+//----------------------------------------------------------------------------
+// type Vector<'T> augmentation
+//--------------------------------------------------------------------------*)
+
+    type Vector<'T> with
+        static member ( +  )(a: Vector<'T>,b) = SpecializedGenericImpl.addV a b
+        static member ( -  )(a: Vector<'T>,b) = SpecializedGenericImpl.subV a b
+        static member ( .* )(a: Vector<'T>,b) = SpecializedGenericImpl.cptMulV a b
+        
+        static member ( * )(k,m: Vector<'T>) = SpecializedGenericImpl.scaleV k m
+        
+        static member ( * )(a: Vector<'T>,b) = SpecializedGenericImpl.mulVRV a b
+        
+        static member ( * )(m: Vector<'T>,k) = SpecializedGenericImpl.scaleV k m
+        
+        static member ( ~- )(m: Vector<'T>)     = SpecializedGenericImpl.negV m
+        static member ( ~+ )(m: Vector<'T>)     = m
+
+        member m.GetSlice (start,finish) = 
+            let start = match start with None -> 0 | Some v -> v 
+            let finish = match finish with None -> m.NumRows - 1 | Some v -> v 
+            SpecializedGenericImpl.getRegionV m (start,finish)
+
+        member m.SetSlice (start,finish,vs:Vector<_>) = 
+            let start = match start with None -> 0 | Some v -> v 
+            let finish = match finish with None -> m.NumRows - 1 | Some v -> v 
+            for i = start to finish  do 
+                   m.[i] <- vs.[i-start]
+
+
+        override m.ToString() = GenericImpl.showVecGU "vector" m
+
+        member m.DebugDisplay = 
+            let txt = GenericImpl.showVecGU "vector" m
+            new System.Text.StringBuilder(txt)  // return an object with a ToString with the right value, rather than a string. (strings get shown using quotes)
+
+        member m.StructuredDisplayAsArray =  Array.init m.NumRows (fun i -> m.[i])
+
+        member m.Details = m.Values
+
+        member m.Transpose = SpecializedGenericImpl.transV m
+        
+        member m.Permute (p:permutation) = SpecializedGenericImpl.permuteV p m
+      
+        interface System.IComparable with 
+             member m.CompareTo(y:obj) = SpecializedGenericImpl.compareV LanguagePrimitives.GenericComparer m (y :?> Vector<'T>)
+        
+        interface IStructuralComparable with
+            member m.CompareTo(y:obj,comp:System.Collections.IComparer) = SpecializedGenericImpl.compareV comp m (y :?> Vector<'T>)
+
+        interface IStructuralEquatable with
+            member x.GetHashCode(comp) = SpecializedGenericImpl.hashV comp x
+            member x.Equals(yobj,comp) = 
+                match yobj with 
+                | :? Vector<'T> as v2 -> SpecializedGenericImpl.equalsV comp x v2
+                | _ -> false
+
+        override x.GetHashCode() = 
+            SpecializedGenericImpl.hashV LanguagePrimitives.GenericEqualityComparer x
+
+        override x.Equals(yobj) = 
+            match yobj with 
+            | :? Vector<'T> as v2 -> SpecializedGenericImpl.equalsV LanguagePrimitives.GenericEqualityComparer x v2
+            | _ -> false
+
+//----------------------------------------------------------------------------
+// type RowVector<'T> augmentation
+//--------------------------------------------------------------------------*)
+
+    type RowVector<'T> with
+        static member ( +  )(a: RowVector<'T>,b) = SpecializedGenericImpl.addRV a b
+        static member ( -  )(a: RowVector<'T>,b) = SpecializedGenericImpl.subRV a b
+        static member ( .* )(a: RowVector<'T>,b) = SpecializedGenericImpl.cptMulRV a b
+        static member ( * )(k,v: RowVector<'T>) = SpecializedGenericImpl.scaleRV k v
+        
+        static member ( * )(a: RowVector<'T>,b: Matrix<'T>) = SpecializedGenericImpl.mulRVM a b
+        static member ( * )(a: RowVector<'T>,b:Vector<'T>) = SpecializedGenericImpl.mulRVV a b
+        static member ( * )(v: RowVector<'T>,k:'T) = SpecializedGenericImpl.scaleRV k v
+        
+        static member ( ~- )(v: RowVector<'T>)     = SpecializedGenericImpl.negRV v
+        static member ( ~+ )(v: RowVector<'T>)     = v
+
+        member m.GetSlice (start,finish) = 
+            let start = match start with None -> 0 | Some v -> v
+            let finish = match finish with None -> m.NumCols - 1 | Some v -> v 
+            SpecializedGenericImpl.getRegionRV m (start,finish)
+
+        member m.SetSlice (start,finish,vs:RowVector<_>) = 
+            let start = match start with None -> 0 | Some v -> v 
+            let finish = match finish with None -> m.NumCols - 1 | Some v -> v 
+            for i = start to finish  do 
+                   m.[i] <- vs.[i-start]
+
+        override m.ToString() = GenericImpl.showRowVecGU "rowvec" m
+
+        member m.DebugDisplay = 
+            let txt = GenericImpl.showRowVecGU "rowvec" m
+            new System.Text.StringBuilder(txt)  // return an object with a ToString with the right value, rather than a string. (strings get shown using quotes)
+
+        member m.StructuredDisplayAsArray =  Array.init m.NumCols (fun i -> m.[i])
+
+        member m.Details = m.Values
+
+        member m.Transpose = SpecializedGenericImpl.transRV m
+        
+        member m.Permute (p:permutation) = SpecializedGenericImpl.permuteRV p m
+      
+        interface System.IComparable with 
+            member m.CompareTo(y) = SpecializedGenericImpl.compareRV LanguagePrimitives.GenericComparer m (y :?> RowVector<'T>)
+        
+        interface IStructuralComparable with
+            member m.CompareTo(y,comp) = SpecializedGenericImpl.compareRV comp m (y :?> RowVector<'T>)
+
+        interface IStructuralEquatable with
+            member x.GetHashCode(comp) = SpecializedGenericImpl.hashRV comp x
+            member x.Equals(yobj,comp) = 
+                match yobj with 
+                | :? RowVector<'T> as rv2 -> SpecializedGenericImpl.equalsRV comp x rv2
+                | _ -> false
+
+        override x.GetHashCode() = 
+            SpecializedGenericImpl.hashRV LanguagePrimitives.GenericEqualityComparer x
+
+        override x.Equals(yobj) = 
+            match yobj with 
+            | :? RowVector<'T> as rv2 -> SpecializedGenericImpl.equalsRV LanguagePrimitives.GenericEqualityComparer x rv2
+            | _ -> false
+
+    type matrix = Matrix<float>
+    type vector = Vector<float>
+    type rowvec = RowVector<float>
+
+    module MRandom = 
+        let seed = 99
+        let randomGen = new System.Random(seed)
+        let float f = randomGen.NextDouble() * f 
+
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Matrix = begin
+        
+        module Generic = begin
+
+            module MS = SpecializedGenericImpl
+
+            // Accessors
+            let get (a:Matrix<_>) i j   = a.[i,j]
+            let set (a:Matrix<_>) i j x = a.[i,j] <- x
+            
+            // Creation
+            let ofList    xss      = MS.listM  xss
+            let ofSeq     xss      = MS.seqM  xss
+            let init  m n f       = MS.initM  m n f
+            let ofArray2D (arr: 'T[,])  : Matrix<'T>       = MS.arrayM arr
+            let toArray2D (m:Matrix<_>) = Array2D.init m.NumRows m.NumCols (fun i j -> get m i j)
+            let initNumeric m n f = MS.initNumericM m n f
+            let zero m n            = MS.zeroM m n
+            let identity m          = MS.identityM m
+            let create  m n x       = MS.constM m n x
+
+            let ofScalar   x        = MS.scalarM x
+
+            let diag v              = MS.diagM v
+            let initDiagonal v      = MS.diagM v
+            let constDiag   n x     = MS.constDiagM n x
+          
+            // Operators
+            let add a b = MS.addM a b
+            let sub a b = MS.subM a b
+            let mul a b = MS.mulM a b
+            let mulRV a b = MS.mulRVM a b
+            let mulV a b = MS.mulMV a b
+            let cptMul a b = MS.cptMulM a b
+            let cptMax a b = MS.cptMaxM a b
+            let cptMin a b = MS.cptMinM a b
+            let scale a b = MS.scaleM a b
+            let dot a b = MS.dotM a b
+            let neg a = MS.negM a 
+            let trace a = MS.traceM a
+            let sum a = MS.sumM a
+            let prod a = MS.prodM a
+            let norm a = MS.normM a
+            let transpose a = MS.transM a
+            let inplaceAdd a b = MS.inplaceAddM a b
+            let inplaceSub a b = MS.inplaceSubM a b
+
+            let exists  f a = MS.existsM  f a
+            let forall  f a = MS.forallM  f a
+            let existsi  f a = MS.existsiM  f a
+            let foralli  f a = MS.foralliM  f a
+            let map  f a = MS.mapM f a
+            let copy a = MS.copyM a
+            let mapi  f a = MS.mapiM f a
+            let getDiagN  a n = MS.getDiagnM a n
+            let getDiag  a = MS.getDiagnM a 0
+            let toDense a = MS.toDenseM a 
+
+            let initDense i j a = MS.initDenseM i j a 
+            let initSparse i j a = MS.initSparseM i j a 
+
+            let fold  f z a = MS.foldM f z a
+            let foldi f z a = MS.foldiM f z a
+          
+            let compare a b = MS.compareM LanguagePrimitives.GenericComparer a b
+            let hash a      = MS.hashM LanguagePrimitives.GenericEqualityComparer a
+            let getRow    a i           = MS.getRowM a i
+            let getCol    a j           = MS.selColM a j
+            let getCols   a i1 i2       = MS.getColsM a (i1,i1+i2-1)
+            let getRows   a j1 j2       = MS.getRowsM a (j1,j1+j2-1)
+            let getRegion a i1 j1 i2 j2 = MS.getRegionM a (i1,i1+i2-1) (j1,j1+j2-1)
+            
+            let ofRowVector x = MS.rowvecM x
+            let ofVector    x = MS.vectorM x
+            let toVector    x = MS.toVectorM x
+            let toRowVector x = MS.toRowVectorM x
+            let toScalar    x = MS.toScalarM x
+
+            let inplace_assign f a  = MS.inplaceAssignM  f a
+            let inplace_cptMul a b = MS.inplaceCptMulM a b
+            let inplace_scale a b = MS.inplaceScaleM a b
+            let inplace_mapi  f a = MS.inplace_mapiM f a
+            let of_rowvec x           = ofRowVector x
+            let of_vector x           = ofVector x
+            let to_vector x           = toVector x
+            let to_rowvec x           = toRowVector x
+            let to_scalar x           = toScalar x
+            let inplace_add a b       = inplaceAdd a b
+            let inplace_sub a b       = inplaceSub a b
+            let of_scalar   x         = ofScalar x
+            let of_list    xss        = ofList xss
+            let of_seq     xss        = ofSeq xss
+            let inline of_array2D arr = ofArray2D arr
+            let inline to_array2D m   = toArray2D m
+            let init_diagonal v       = initDiagonal v
+            let to_dense a            = toDense a
+            let init_dense i j a      = initDense i j a
+            let init_sparse i j a     = initSparse i j a
+            let nonzero_entries a     = MS.nonZeroEntriesM a 
+         
+        end
+
+        module MG = Generic
+        module DS = DoubleImpl
+        module GU = GenericImpl
+        module MS = SpecializedGenericImpl
+
+        // Element type OpsData
+        type elem = float
+
+        // Accessors
+        let get (a:matrix) i j   = MG.get a i j
+        let set (a:matrix) i j x = MG.set a i j x
+        
+        // Creation
+        let init  m n f = DS.initDenseMatrixDS  m n f |> MS.dense 
+        let ofList    xss   = DS.listDenseMatrixDS    xss |> MS.dense
+        let ofSeq     xss   = DS.seqDenseMatrixDS    xss |> MS.dense
+        let diag  (v:vector)   = MG.diag v 
+        let initDiagonal  (v:vector)   = MG.diag v 
+        let constDiag  n x : matrix  = MG.constDiag n x 
+        let create  m n x  = DS.constDenseMatrixDS  m n x |> MS.dense
+        let ofScalar x     = DS.scalarDenseMatrixDS x |> MS.dense
+
+        let ofArray2D arr : matrix = MG.ofArray2D arr
+        let toArray2D (m : matrix) = MG.toArray2D m
+
+        let getDiagN  (a:matrix) n = MG.getDiagN a n
+        let getDiag  (a:matrix) = MG.getDiag a
+
+        // Operators
+        let add (a:matrix) (b:matrix) = MS.addM   a b
+        let sub (a:matrix) (b:matrix) = MS.subM   a b
+        let mul (a:matrix) (b:matrix) = MS.mulM   a b
+        let mulV (a:matrix) (b:vector) = MS.mulMV   a b
+        let mulRV (a:rowvec) (b:matrix) = MS.mulRVM   a b
+        let cptMul (a:matrix) (b:matrix) = MS.cptMulM   a b
+        let cptMax (a:matrix) (b:matrix) = MS.cptMaxM a b
+        let cptMin (a:matrix) (b:matrix) = MS.cptMinM a b
+        let scale a (b:matrix) = MS.scaleM   a b
+        let neg (a:matrix)  = MS.negM a
+        let trace (a:matrix)  = MS.traceM a
+        let transpose  (a:matrix) = MG.transpose a
+        let forall f (a:matrix) = MG.forall f a
+        let exists  f (a:matrix) = MG.exists f a
+        let foralli f (a:matrix) = MG.foralli f a
+        let existsi  f (a:matrix) = MG.existsi f a
+        let map  f (a:matrix) = MG.map f a
+        let copy  (a:matrix) = MG.copy a
+        let mapi  f (a:matrix) : matrix = MG.mapi f a
+        let fold  f z (a:matrix) = MG.fold f z a
+        let foldi  f z (a:matrix) = MG.foldi f z a
+
+        let toDense (a:matrix) = MG.toDense a 
+        let initDense i j a : matrix = MG.initDense i j a 
+        let initSparse i j a : matrix = MG.initSparse i j a 
+        let nonzero_entries (a:matrix) = MG.nonzero_entries a 
+
+        let zero m n  = DS.zeroDenseMatrixDS m n |> MS.dense
+        let identity m  : matrix = MG.identity m 
+        
+        let ones m n  = create m n 1.0
+        
+        let getRow (a:matrix) i      = MG.getRow a i
+        let getCol (a:matrix) j      = MG.getCol a j
+        let getCols (a:matrix) i1 i2    = MG.getCols a i1 i2
+        let getRows (a:matrix) j1 j2    = MG.getRows a j1 j2
+        let getRegion (a:matrix) i1 j1 i2 j2    = MG.getRegion a i1 j1 i2 j2
+
+        let rowRange (a:Matrix<_>) = (0,a.NumRows - 1)
+        let colRange (a:Matrix<_>) = (0,a.NumCols - 1)
+        let wholeRegion a = (colRange a, rowRange a)
+        
+        let foldByRow f (z:Vector<'T>) (a:matrix) = 
+          colRange a |> GU.foldR (fun z j -> MS.mapiV (fun i z -> f z (get a i j)) z) z
+        let foldByCol f (z:RowVector<'T>) (a:matrix) = 
+          rowRange a |> GU.foldR (fun z i -> MS.mapiRV (fun j z -> f z (get a i j)) z) z
+
+        let foldRow f (z:'T) (a:matrix) i = 
+          colRange a |> GU.foldR (fun (z:'T) j -> f z (get a i j)) z
+        let foldCol f (z:'T) (a:matrix) j = 
+          rowRange a |> GU.foldR (fun (z:'T) i -> f z (get a i j)) z
+
+        let sum (a:matrix)  = MS.sumM a
+        let prod (a:matrix)  = MS.prodM a
+        let norm  (a:matrix) = MS.normM  a
+        let dot (a:matrix) b = MS.dotM a b
+
+        let cptPow  a y = map (fun x -> x ** y) a
+        
+        // Functions that only make sense on this type
+        let randomize v = map (fun vij -> MRandom.float vij) v      (* res_ij = random [0,vij] values *)
+
+        let ofRowVector x : matrix = MS.rowvecM x
+        let ofVector    x : matrix = MS.vectorM x
+        let toVector    x : vector = MS.toVectorM x
+        let toRowVector x : rowvec = MS.toRowVectorM x
+        let toScalar    x : float  = MS.toScalarM x
+
+        let inplaceAdd  (a:matrix) b = MS.inplaceAddM a b
+        let inplaceSub  (a:matrix) b = MS.inplaceSubM a b
+
+        // Mutation
+        let inplace_assign  f (a:matrix) = MG.inplace_assign f a
+        let inplace_mapi  f (a:matrix) = MG.inplace_mapi f a
+        let inplace_cptMul (a:matrix) b = MS.inplaceCptMulM a b
+        let inplace_scale  a (b:matrix) = MS.inplaceScaleM a b
+
+        let inplace_add  a b = inplaceAdd a b
+        let inplace_sub  a b = inplaceSub a b
+        let of_rowvec x = ofRowVector x
+        let of_vector x = ofVector x
+        let to_vector x = toVector x
+        let to_rowvec x = toRowVector x
+        let to_scalar x = toScalar x
+        let inline of_array2D arr  = ofArray2D arr
+        let inline to_array2D m = toArray2D m
+        let of_list    xss   = ofList xss
+        let of_seq     xss   = ofSeq xss
+        let init_diagonal v   = initDiagonal   v
+        let of_scalar x     = ofScalar x
+        let to_dense x = toDense x
+        let init_dense i j a = initDense i j a
+        let init_sparse i j a = initSparse i j a
+
+
+    end
+
+
+//----------------------------------------------------------------------------
+// module Vector
+//--------------------------------------------------------------------------*)
+      
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Vector = 
+
+        module Generic = 
+
+            module OpsS = SpecializedGenericImpl
+
+            let get (a:Vector<_>) i   = a.[i]
+            let set (a:Vector<_>) i x = a.[i] <- x
+            let length (v:Vector<_>) = v.Length
+            let ofList    xss   = OpsS.listV xss
+            let ofSeq    xss   = OpsS.seqV xss
+            let init  m   f = OpsS.initV m f
+            let initNumeric  m   f = OpsS.createNumericV m f
+            let ofArray arr       = OpsS.arrayV arr
+            let toArray (v:Vector<_>) = Array.init v.Length (get v)
+
+            let create  m x   = OpsS.constV m x
+            let zero n = OpsS.zeroV n
+            let ones n = OpsS.createNumericV n (fun ops _ -> ops.One)
+            let ofScalar   x = OpsS.scalarV x
+            let add a b = OpsS.addV a b
+            let sub a b = OpsS.subV a b
+            let mulRVV a b = OpsS.mulRVV a b
+            let mulVRV a b = OpsS.mulVRV a b
+            let cptMul a b = OpsS.cptMulV a b
+            let cptMax a b = OpsS.cptMaxV a b
+            let cptMin a b = OpsS.cptMinV a b
+            let scale a b = OpsS.scaleV a b
+            let dot a b = OpsS.dotV a b
+            let neg a = OpsS.negV a 
+            let transpose a = OpsS.transV a 
+            let inplaceAdd a b = OpsS.inplaceAddV a b
+            let inplaceSub a b = OpsS.inplaceSubV a b
+            let inplace_cptMul a b = OpsS.inplaceCptMulV a b
+            let inplace_scale a b = OpsS.inplaceScaleV a b
+
+
+
+            let exists  f a = OpsS.existsV  f a
+            let forall  f a = OpsS.forallV  f a
+            let existsi  f a = OpsS.existsiV  f a
+            let foralli  f a = OpsS.foralliV  f a
+            let map  f a = OpsS.mapV f a
+            let mapi f a = OpsS.mapiV f a
+            let copy a = OpsS.copyV a
+            let inplace_mapi  f a = OpsS.inplace_mapiV f a
+            let fold  f z a = OpsS.foldV f z a
+            let foldi  f z a = OpsS.foldiV f z a
+            let compare a b = OpsS.compareV a b
+            let hash a = OpsS.hashV a
+            let inplace_assign  f a = OpsS.assignV f a
+            let sum  (a:Vector<_>) = let ops = a.ElementOps in fold (fun x y -> ops.Add(x,y)) ops.Zero a
+            let prod (a:Vector<_>) = let ops = a.ElementOps in fold (fun x y -> ops.Multiply(x,y)) ops.One a
+            let norm (a:Vector<_>) = 
+                let normOps = GenericImpl.getNormOps a.ElementOps 
+                sqrt (fold (fun x y -> x + normOps.Norm(y)**2.0) 0.0 a)
+
+            let of_list    xss  = ofList xss
+            let of_seq    xss   = ofSeq xss
+            let of_array arr    = ofArray arr
+            let to_array v      = toArray v
+            let of_scalar   x   = ofScalar x
+            let inplace_add a b = inplaceAdd a b
+            let inplace_sub a b = inplaceSub a b
+
+        module VG = Generic
+        module VecDS = DoubleImpl
+        module VecGU = GenericImpl
+
+        let get (a:vector) j   = VG.get a j 
+        let set (a:vector) j x = VG.set a j x
+        let length (a:vector)     = VG.length a
+        let nrows (a:vector)   = VG.length a
+        let init  m   f = VecDS.createVecDS  m   f
+        let ofArray arr : vector = VG.ofArray arr
+        let toArray (m : vector) = VG.toArray m
+
+        type range = int * int
+        let countR ((a,b) : range)   = (b-a)+1
+        let idxR    ((a,_) : range) i = a+i
+        type rangef = float * float * float // start, skip, end
+        let countRF ((a,d,b) : rangef)   = System.Convert.ToInt32((b-a)/d) + 1
+        //let countRF ((a,d,b) : rangef)   = Float.to_int((b-a)/d) + 1
+        let idxRF  ((a,d,b) : rangef) i = System.Math.Min (a + d * float(i),b)
+
+        let range n1 n2    = let r = (n1,n2)   in init (countR  r) (fun i -> float(idxR r i)) 
+
+        let rangef a b c  = let r = (a,b,c) in init (countRF r) (fun i -> idxRF r i)
+
+        let ofList    xs    = VecDS.listVecDS    xs
+        let ofSeq    xs    = VecDS.seqVecDS    xs
+        let create  m   x  = VecDS.constVecDS  m   x
+        let ofScalar x     = VecDS.scalarVecDS x
+        let add a b = VecDS.addVecDS   a b
+        let sub a b = VecDS.subVecDS   a b
+        let mulRVV a b = VecDS.mulRowVecVecDS   a b
+        let mulVRV a b = VecDS.mulVecRowVecDS   a b 
+        let cptMul a b = VecDS.cptMulVecDS   a b
+        let cptMax a b = VecDS.cptMaxVecDS a b
+        let cptMin a b = VecDS.cptMinVecDS a b
+        let scale a b = VecDS.scaleVecDS   a b
+        let neg a  = VecDS.negVecDS a
+        let dot a b = VecDS.dotVecDS a b
+        let transpose  (a:vector) = VG.transpose a
+        let exists  f (a:vector) = VG.exists f a
+        let forall  f (a:vector) = VG.forall f a
+        let existsi  f (a:vector) = VG.existsi f a
+        let foralli  f (a:vector) = VG.foralli f a
+        let map  f (a:vector) = VG.map f a
+        let copy (a:vector) = VG.copy a
+        let mapi  f (a:vector) : vector = VG.mapi f a
+        let fold  f z (a:vector) = VG.fold f z a
+        let foldi  f z (a:vector) = VG.foldi f z a
+        let zero n = create n 0.0
+        let ones n = create n 1.0
+        let sum a  = VecDS.sumVecDS a
+        let prod a   = fold      (fun x y -> x * y) 1.0 a
+        let norm  (a:vector) = sqrt (fold (fun x y -> x + y * y) 0.0 a) (* fixed *)
+        let cptPow  a y = map  (fun x -> x ** y) a
+        let inplace_assign  f (a:vector) = VG.inplace_assign f a
+        let inplace_mapi f (a:vector) = VG.inplace_mapi f a
+        let inplace_add a b = VecDS.inplaceAddVecDS a b
+        let inplace_sub a b = VecDS.inplaceSubVecDS a b
+        let inplace_cptMul a b = VecDS.inplaceCptMulVecDS a b
+        let inplace_scale a b = VecDS.inplaceScaleVecDS a b  
+
+        let of_array arr   = ofArray arr
+        let to_array m     = toArray m
+        let of_list    xs  = ofList xs
+        let of_seq    xs   = ofSeq xs
+        let of_scalar x    = ofScalar x
+
+
+
+//----------------------------------------------------------------------------
+// module RowVector
+//--------------------------------------------------------------------------*)
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module RowVector = 
+
+        module Generic = 
+
+            module OpsS = SpecializedGenericImpl
+
+            let get (a:RowVector<_>) i          = a.[i]
+            let set (a:RowVector<_>) i x        = a.[i] <- x
+            let zero n           = OpsS.zeroRV n
+            let length (v:RowVector<_>) = v.Length
+            let init m   f       = OpsS.initRV m   f
+            let create  m x      = OpsS.constRV m x
+            let transpose a      = OpsS.transRV a
+            let copy a           = OpsS.copyRV a
+            let ofList a         = OpsS.listRV a
+            let ofArray a        = OpsS.arrayRV a
+            let ofSeq a          = OpsS.seqRV a
+            let toArray m        = Array.init (length m) (get m)
+
+            let of_list a        = ofList a
+            let of_array a       = ofArray a
+            let of_seq a         = ofSeq a
+            let to_array m       = toArray m
+
+
+        module RVG = Generic
+
+        let get (a:rowvec) i   = RVG.get a i 
+        let set (a:rowvec) i x = RVG.set a i x
+        let length (a:rowvec)  = RVG.length a
+        let ncols (a:rowvec)   = RVG.length a
+        let ofArray arr : rowvec = RVG.ofArray arr
+        let toArray (m : rowvec) = RVG.toArray m
+        
+        let init m   f : rowvec      = RVG.init m   f
+        let create m   f : rowvec    = RVG.create m   f
+        let zero n = create n 0.0
+        let ofList x : rowvec       = RVG.ofList x
+        let ofSeq x : rowvec       = RVG.ofSeq x
+        let transpose x : vector     = RVG.transpose x
+        let copy x : rowvec          = RVG.copy x
+
+        let of_list x    = ofList x
+        let of_seq x     = ofSeq x
+        let of_array arr = ofArray arr
+        let to_array m   = toArray m
+
+
+    type Matrix<'T> with 
+        member x.ToArray2()        = Matrix.Generic.toArray2D x
+        member x.ToArray2D()        = Matrix.Generic.toArray2D x
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+
+        member x.NonZeroEntries    = Matrix.Generic.nonzero_entries x
+        member x.ToScalar()        = Matrix.Generic.toScalar x
+        member x.ToRowVector()     = Matrix.Generic.toRowVector x               
+        member x.ToVector()        = Matrix.Generic.toVector x
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member x.Norm              = Matrix.Generic.norm x
+
+        member x.Column(n)         = Matrix.Generic.getCol x n
+        member x.Row(n)            = Matrix.Generic.getRow x n
+        member x.Columns (i,ni)    = Matrix.Generic.getCols x i ni
+        member x.Rows (j,nj)       = Matrix.Generic.getRows x j nj
+        member x.Region(i,j,ni,nj) = Matrix.Generic.getRegion x i j ni nj
+        member x.GetDiagonal(i)    = Matrix.Generic.getDiagN x i
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member x.Diagonal          = Matrix.Generic.getDiag x
+
+        member x.Copy () = Matrix.Generic.copy x
+
+
+    type Vector<'T> with 
+        member x.ToArray() = Vector.Generic.toArray x
+        member x.Norm      = Vector.Generic.norm x
+        member x.Copy ()   = Vector.Generic.copy x
+
+
+    type RowVector<'T> with 
+        member x.ToArray() = RowVector.Generic.toArray x
+        member x.Copy ()   = RowVector.Generic.copy x
+
+
+    module MatrixTopLevelOperators = 
+
+        let matrix ll = Matrix.ofSeq ll
+        let vector l  = Vector.ofSeq  l
+        let rowvec l  = RowVector.ofSeq l
+
diff --git a/src/FSharp.PowerPack/math/matrix.fsi b/src/FSharp.PowerPack/math/matrix.fsi
new file mode 100755
index 0000000..d5b0a14
--- /dev/null
+++ b/src/FSharp.PowerPack/math/matrix.fsi
@@ -0,0 +1,1100 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+open Microsoft.FSharp.Math
+open System
+open System.Collections
+open System.Collections.Generic
+
+/// The type of matrices. The arithmetic operations on the element type are determined by inspection on the element type itself.
+/// Two representations are supported: sparse and dense. 
+[<Sealed>]
+type Matrix<'T> = 
+
+    /// Get the number of rows in a matrix
+    member NumRows : int
+
+    /// Get the number of columns in a matrix
+    member NumCols : int
+
+    /// Get the number of (rows,columns) in a matrix
+    member Dimensions : int * int
+
+    /// Get the item at the given position in a matrix
+    member Item : int * int -> 'T with get,set
+
+    /// Supports the slicing syntax 'A.[idx1..idx2,idx1..idx2]'
+    member GetSlice : start1:int option * finish1:int option * start2:int option * finish2:int option -> Matrix<'T>
+
+    /// Supports the slicing syntax 'A.[idx1..idx2,idx1..idx2] <- B'
+    member SetSlice : start1:int option * finish1:int option * start2:int option * finish2:int option * source:Matrix<'T> -> unit
+    
+    /// Retrieve the dictionary of numeric operations associated with the element
+    /// type of this matrix. Accessing the property may raise an NotSupportedException if the element
+    /// type doesn't support any numeric operations. The object returned
+    /// may support additional numeric operations such as IFractional: 
+    /// this can be determined by a dynamic type test against the object
+    /// returned.
+    member ElementOps : INumeric<'T>
+
+    /// Point-wise addition of two matrices. An InvalidArgument exception will be
+    /// raised if the dimensions do not match.
+    static member ( +  ) : Matrix<'T> * Matrix<'T> -> Matrix<'T>
+
+    /// Point-wise subtraction of two matrices. An InvalidArgument exception will be
+    /// raised if the dimensions do not match.
+    static member ( -  ) : Matrix<'T> * Matrix<'T> -> Matrix<'T>
+
+    /// Matrix negation. 
+    static member ( ~- ) : Matrix<'T>              -> Matrix<'T>
+
+    /// Prefix '+' operator. A nop.
+    static member ( ~+ ) : Matrix<'T>              -> Matrix<'T>
+
+    /// Matrix multiplication. An InvalidArgument exception will be
+    /// raised if the dimensions do not match.
+    static member ( * ) : Matrix<'T> * Matrix<'T> -> Matrix<'T>
+
+    /// Matrix-vector multiplication. 
+    static member ( * ) : Matrix<'T> * Vector<'T> -> Vector<'T>
+
+    /// Multiply each element of a matrix by the given scalar value
+    static member ( * ) : Matrix<'T> * 'T          -> Matrix<'T>
+
+    /// Point-wise matrix multiplication. An InvalidArgument exception will be
+    /// raised if the dimensions do not match.
+    static member ( .* ) : Matrix<'T> * Matrix<'T>  -> Matrix<'T>
+
+    /// Multiply each element of a matrix by a scalar value
+    static member ( * ) : 'T          * Matrix<'T> -> Matrix<'T>
+    
+    /// Get the transpose of a matrix.
+    member Transpose : Matrix<'T>
+    
+    /// Permutes the rows of a matrix.
+    member PermuteRows : permutation:(int -> int) -> Matrix<'T>
+    
+    /// Permutes the columns of a matrix.
+    member PermuteColumns : permutation:(int -> int) -> Matrix<'T>
+
+
+    //interface IMatrix<'T>
+    interface IComparable
+    interface IStructuralComparable
+    interface IStructuralEquatable
+    interface IEnumerable<'T>
+    override GetHashCode : unit -> int
+    override Equals : obj -> bool
+  
+    /// Return a new array containing the elements of a matrix
+    member ToArray2D : unit -> 'T[,]  
+
+    /// Return the non-zero entries of a sparse or dense matrix
+    member NonZeroEntries: seq<int * int * 'T> 
+
+    /// Convert a matrix to a row vector
+    member ToRowVector : unit -> RowVector<'T>                 
+
+    /// Convert a matrix to a column vector
+    member ToVector : unit -> Vector<'T> 
+
+    /// Returns sqrt(sum(norm(x)*(norm(x))) of all the elements of a matrix.
+    /// The element type of a matrix must have an associated instance of INormFloat<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+    member Norm : float
+
+    /// Select a column from a matrix
+    member Column : index:int -> Vector<'T>
+
+    /// Select a row from a matrix
+    member Row :  index:int -> RowVector<'T>
+
+    /// Select a range of columns from a matrix
+    member Columns : start:int  * length:int -> Matrix<'T>
+
+    /// Select a range of rows from a matrix
+    member Rows : start:int * length:int -> Matrix<'T>
+
+    /// Select a region from a matrix
+    member Region : starti:int * startj:int * lengthi:int * lengthj:int -> Matrix<'T>
+
+
+    /// Return the nth diagonal of a matrix, as a vector. Diagonal 0 is the primary
+    /// diagonal, positive diagonals are further to the upper-right of a matrix.
+    member GetDiagonal : int -> Vector<'T>
+
+    /// Get the main diagonal of a matrix, as a vector
+    member Diagonal : Vector<'T>
+
+    /// Create a new matrix that is a copy of an array
+    member Copy : unit -> Matrix<'T>
+
+    /// Get the internal array of values for a dense matrix. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalDenseValues : 'T[,]
+    /// Get the internal array of values for a sparse matrix. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalSparseValues : 'T[]
+    /// Get the internal array of row offsets for a sparse matrix. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalSparseRowOffsets : int[]
+    /// Get the internal array of column values for a sparse matrix. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalSparseColumnValues : int[]
+
+    /// Indicates if a matrix uses the sparse representation.
+    member IsSparse : bool
+
+    /// Indicates if a matrix uses the dense representation.
+    member IsDense : bool
+
+    [<System.Obsolete("This member has been renamed to 'ToArray2D'")>]
+    member ToArray2 : unit -> 'T[,]  
+
+    member StructuredDisplayAsArray : obj
+
+/// The type of column vectors. The arithmetic operations on the element type are determined by inspection 
+/// on the element type itself
+and 
+
+  [<Sealed>]
+  Vector<'T> = 
+
+
+    /// Get the underlying internal array of values for a vector. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalValues : 'T[]
+
+    /// Gets the number of entries in a vector
+    member Length : int
+
+    /// Gets the number of rows in a vector
+    member NumRows : int
+
+    /// Gets an item from a vector
+    member Item : int -> 'T with get,set
+
+    /// Gets the element operations for the element type of a vector, if any
+    member ElementOps : INumeric<'T>
+    
+    /// Supports the slicing syntax 'v.[idx1..idx2]'
+    member GetSlice      : start:int option * finish:int option -> Vector<'T>
+
+    /// Supports the slicing syntax 'v.[idx1..idx2] <- v2'
+    member SetSlice      : start:int option * finish:int option * source:Vector<'T> -> unit
+
+    /// Add two vectors, pointwise
+    static member ( +  ) : Vector<'T>    * Vector<'T> -> Vector<'T>
+
+    /// Subtract two vectors, pointwise
+    static member ( -  ) : Vector<'T>    * Vector<'T> -> Vector<'T>
+
+    /// Negate a vector
+    static member ( ~- ) : Vector<'T>                  -> Vector<'T>
+
+    /// Return the input vector 
+    static member ( ~+ ) : Vector<'T>                  -> Vector<'T>
+
+    /// Point-wise multiplication of two vectors.
+    static member ( .* ) : Vector<'T>    * Vector<'T> -> Vector<'T>
+
+    /// Multiply each element of a vector by a scalar value.
+    static member ( * ) : 'T             * Vector<'T> -> Vector<'T>
+
+    /// Multiply a column vector and a row vector to produce a matrix
+    static member ( * )   : Vector<'T>    * RowVector<'T> -> Matrix<'T>
+
+    /// Multiply a vector by a scalar
+    static member ( * )   : Vector<'T>    * 'T          -> Vector<'T>
+
+    /// Get the transpose of a vector.
+    member Transpose : RowVector<'T>
+    
+    /// Permute the elements of a vector.
+    member Permute : permutation:(int -> int) -> Vector<'T>    
+    
+    interface IComparable
+    interface IStructuralComparable
+    interface IStructuralEquatable
+    interface IEnumerable<'T>
+    override GetHashCode : unit -> int
+    override Equals : obj -> bool
+
+    /// Return a new array containing a copy of the elements of a vector
+    member ToArray : unit    -> 'T[]
+
+    /// Computes the 2-norm of a vector: sqrt(x.Transpose*x).
+    member Norm : float
+
+    /// Create a new matrix that is a copy of a array
+    member Copy : unit -> Vector<'T>
+
+    member StructuredDisplayAsArray : 'T[]
+
+
+
+
+/// The type of row vectors. 
+and [<Sealed>]
+    RowVector<'T> =
+
+    /// Get the underlying internal array of values for a vector. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalValues : 'T[]
+
+    // Basic access
+    member Length : int
+    member NumCols : int
+    member Item : int -> 'T with get,set
+    member ElementOps : INumeric<'T>
+
+    /// Supports the slicing syntax 'rv.[idx1..idx2]'
+    member GetSlice      : start:int option * finish:int option -> RowVector<'T>
+
+    /// Supports the slicing syntax 'rv.[idx1..idx2] <- rv2'
+    member SetSlice      : start:int option * finish:int option * source:RowVector<'T> -> unit
+
+
+    /// Point-wise addition of two row vectors
+    static member ( +  )  : RowVector<'T>    * RowVector<'T> -> RowVector<'T>
+
+    /// Point-wise subtraction of two row vectors
+    static member ( -  )  : RowVector<'T>    * RowVector<'T> -> RowVector<'T>
+
+    /// Point-wise negation of a row vector
+    static member ( ~- )  : RowVector<'T>                  -> RowVector<'T>
+
+    /// Return a row vector, unchanged
+    static member ( ~+ )  : RowVector<'T>                  -> RowVector<'T>
+
+    /// Point-wise multiplication of two row vectors
+    static member ( .* )  : RowVector<'T> * RowVector<'T>    -> RowVector<'T>
+    
+    /// Multiply a row vector by a vector
+    static member ( * ) : RowVector<'T> * Vector<'T>    -> 'T
+
+    /// Multiply a row vector by a matrix
+    static member ( * )   : RowVector<'T> * Matrix<'T>    -> RowVector<'T>
+
+    /// Multiply a row vector by a scalar
+    static member ( * )   : RowVector<'T> * 'T            -> RowVector<'T>
+
+    /// Multiply a scalar by a row vector
+    static member ( * )  : 'T            * RowVector<'T>    -> RowVector<'T>
+
+    /// Get the transpose of the row vector.
+    member Transpose : Vector<'T>
+    
+    /// Permute the elements of the row vector.
+    member Permute : permutation:(int -> int) -> RowVector<'T>  
+
+    interface IComparable
+    interface IStructuralComparable
+    interface IStructuralEquatable
+    interface IEnumerable<'T>
+    override GetHashCode : unit -> int
+    override Equals : obj -> bool
+
+    /// Return a new array containing a copy of the elements of a vector
+    member ToArray : unit    -> 'T[]
+
+    /// Create a new matrix that is a copy of a array
+    member Copy : unit -> RowVector<'T>
+
+    member StructuredDisplayAsArray : 'T[]
+  
+/// The type of floating point matrices
+type matrix = Matrix<float>
+/// The type of floating point column vectors
+type vector = Vector<float>
+/// The type of floating point row vectors
+type rowvec = RowVector<float>
+
+/// Operations to manipulate floating
+/// point matrices. The submodule <c>Matrix.Generic</c> contains a 
+/// matching set of operations to manipulate matrix types carrying
+/// arbitrary element types.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<RequireQualifiedAccess>]
+module Matrix =
+
+
+    /// Get an element of a matrix
+    val get : matrix -> int -> int -> float
+
+    /// Set an element of a matrix
+    val set : matrix -> int -> int -> float -> unit
+
+    // Creation: general
+    val init  : int -> int -> (int -> int -> float) -> matrix
+
+    /// Create a matrix with all entries the given constant
+    val create : int -> int -> float -> matrix
+    
+    /// Create a dense representation matrix with the given entries. 
+    val initDense : int -> int -> seq<int * int * float> -> matrix
+
+    /// Create a sparse representation matrix with the given entries. Not all 
+    /// operations are available for sparse matrices, and mutation is not permitted.
+    /// If an operation on sparse matrices raises a runtime exception then consider 
+    /// converting to a dense matrix using to_dense.
+    val initSparse : int -> int -> seq<int * int * float> -> matrix
+
+    /// Create a matrix with all entries zero
+    val zero     : int -> int          -> matrix
+    
+    /// Create a square matrix with the constant 1.0 lying on diagonal
+    val identity      : int -> matrix
+
+    /// Create a square matrix with a vector lying on diagonal
+    val initDiagonal : vector -> matrix
+    
+    /// Create a matrix from the given data
+    val ofList   : float list list     -> matrix
+
+    /// Create a matrix from the given data
+    val ofSeq    : seq<#seq<float>>   -> matrix
+
+    /// Create a matrix from the given data
+    val ofArray2D : float[,]            -> matrix
+
+    /// Return a new array containing the elements of the given matrix
+    val toArray2D : matrix              -> float[,]
+
+
+    /// Create a 1x1 matrix containing the given value 
+    val ofScalar : float               -> matrix
+    /// Create a matrix with one row from the given row vector
+    val ofRowVector : rowvec              -> matrix
+    /// Create a matrix with one column from the given vector
+    val ofVector : vector              -> matrix
+
+    /// Return the element at row 0, column 0 of a matrix
+    val toScalar : matrix              -> float                
+    /// Return the first row of a matrix
+    val toRowVector : matrix              -> rowvec                
+    /// Return the first column of a matrix
+    val toVector : matrix              -> vector
+    /// Ensure that a matrix uses dense representation
+    val toDense  : matrix              -> matrix
+
+    /// Point-wise maximum element of two matrices
+    val cptMax    : matrix -> matrix -> matrix
+    
+    /// Point-wise minimum element of two matrices
+    val cptMin    : matrix -> matrix -> matrix
+    
+    /// Add two matrices (operator +)
+    val add       : matrix -> matrix -> matrix
+
+    /// Dot product
+    val dot       : matrix -> matrix -> float
+
+    /// Point-wise exponential of a matrix.
+    val cptPow       : matrix -> float -> matrix
+
+    /// Transpose of a matrix. Use also m.Transpose
+    val transpose     :           matrix -> matrix
+
+    /// Sum of the diagonal elements of a matrix
+    val trace     : matrix -> float
+    
+    /// Generate a new matrix of the same size as the input with random entries 
+    /// drawn from the range 0..aij. Random numbers are generated using a globally 
+    /// shared System.Random instance with the initial seed 99.
+    val randomize : matrix -> matrix
+
+    /// Sum all the elements of a matrix
+    val sum       : matrix -> float
+
+    ///Multiply all the elements of a matrix
+    val prod      : matrix -> float
+
+    ///sqrt(sum(x*x)) of all the elements of a matrix
+    val norm      : matrix -> float
+
+    /// Check if a predicate holds for all elements of a matrix
+    val forall  : (float -> bool) -> matrix -> bool
+
+    /// Check if a predicate holds for at least one element of a matrix
+    val exists  : (float -> bool) -> matrix -> bool 
+
+    /// Check if a predicate holds for all elements of a matrix
+    val foralli  : (int -> int -> float -> bool) -> matrix -> bool
+
+    /// Check if a predicate holds for at least one element of a matrix
+    val existsi  : (int -> int -> float -> bool) -> matrix -> bool 
+
+    /// Fold a function over all elements of a matrix
+    val fold      : ('T -> float -> 'T) -> 'T         -> matrix -> 'T
+
+    /// Fold an indexed function over all elements of a matrix
+    val foldi      : (int -> int -> 'T -> float -> 'T) -> 'T         -> matrix -> 'T
+
+    /// Fold a function down each column of a matrix
+    val foldByCol : ('T -> float -> 'T) -> RowVector<'T> -> matrix -> RowVector<'T>
+
+    /// Fold a function along each row of a matrix
+    val foldByRow : ('T -> float -> 'T) -> Vector<'T> -> matrix -> Vector<'T>
+
+    /// Fold a function along a particular column of a matrix
+    val foldCol   : ('T -> float -> 'T) -> 'T         -> matrix -> int -> 'T 
+
+    /// Fold a function down a particular row of a matrix
+    val foldRow   : ('T -> float -> 'T) -> 'T         -> matrix -> int -> 'T
+    
+    /// Map a function over each element of a matrix, producing a new matrix
+    val map  : (float -> float) -> matrix -> matrix
+   
+    /// Map the given indexed function over each element of a matrix, producing a new matrix
+    val mapi  : (int -> int -> float -> float) -> matrix -> matrix
+   
+    /// Create a new matrix that is a copy of the given array
+    val copy : matrix -> matrix
+   
+    /// In-place addition, mutating the first matrix argument.
+    val inplaceAdd    : matrix -> matrix -> unit
+
+    /// In-place subtraction, mutating the first matrix argument. 
+    val inplaceSub    : matrix -> matrix -> unit
+
+    [<Obsolete("Use the '.NonZeroEntries' property instead")>]
+    val nonzero_entries : matrix -> seq<int * int * float>         
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.inplaceAdd' instead")>]
+    val inplace_add    : matrix -> matrix -> unit
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.inplaceSub' instead")>]
+    val inplace_sub    : matrix -> matrix -> unit
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofList' instead")>]
+    val of_list   : float list list     -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofSeq' instead")>]
+    val of_seq    : seq<#seq<float>>   -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofArray2D' instead")>]
+    val inline of_array2D : float[,]            -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.toArray2D' instead")>]
+    val inline to_array2D : matrix              -> float[,]
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofScalar' instead")>]
+    val of_scalar : float               -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofRowVector' instead")>]
+    val of_rowvec : rowvec              -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofVector' instead")>]
+    val of_vector : vector              -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.toScalar' instead")>]
+    val to_scalar : matrix              -> float                
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.toRowVector' instead")>]
+    val to_rowvec : matrix              -> rowvec                
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.toVector' instead")>]
+    val to_vector : matrix              -> vector
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.toDense' instead")>]
+    val to_dense  : matrix              -> matrix
+    [<Obsolete("Use the '*' operator instead")>]
+    val mul       : matrix -> matrix -> matrix
+    [<Obsolete("This function has been renamed to 'initDiagonal'")>]
+    val init_diagonal : vector -> matrix
+    [<Obsolete("Use the 'Matrix.init' function instead")>]
+    val constDiag : int -> float        -> matrix
+    [<Obsolete("Use the 'initDiagonal' function instead")>]
+    val diag      : vector -> matrix
+    [<Obsolete("This function has been renamed to 'initDense'")>]
+    val init_dense : int -> int -> seq<int * int * float> -> matrix
+    [<Obsolete("This function has been renamed to 'initSparse'")>]
+    val init_sparse : int -> int -> seq<int * int * float> -> matrix
+    [<Obsolete("Use the '.*' operator instead")>]
+    val cptMul    : matrix -> matrix -> matrix
+    [<Obsolete("Use the '*' operator instead")>]
+    val mulV      : matrix -> vector -> vector
+    [<Obsolete("Use the '*' operator instead")>]
+    val mulRV     : rowvec -> matrix -> rowvec
+    [<Obsolete("Use the '-' operator instead")>]
+    val sub       : matrix -> matrix -> matrix
+    [<Obsolete("Use the '-' prefix operator instead")>]
+    val neg       :           matrix -> matrix
+    [<Obsolete("Use the '*' operator instead")>]
+    val scale     : float  -> matrix -> matrix
+    [<Obsolete("Use the '.Column' method instead")>]
+    val getCol  : matrix -> int -> vector
+    [<Obsolete("Use the '.Row' method instead")>]
+    val getRow  : matrix -> int -> rowvec
+    [<Obsolete("Use the '.Columns' method instead")>]
+    val getCols : matrix -> start:int -> length:int -> matrix
+    [<Obsolete("Use the '.Rows' method instead")>]
+    val getRows : matrix -> start:int -> length:int -> matrix
+    [<Obsolete("Use the '.Region' method instead")>]
+    val getRegion  : matrix -> starti:int -> startj:int -> lengthi:int -> lengthj:int -> matrix
+    [<Obsolete("Use the '.Diagonal' method instead")>]
+    val getDiagN : matrix -> int    -> vector
+    [<Obsolete("Use the '.Diagonal' property instead")>]
+    val getDiag  : matrix           -> vector
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+    val inplace_assign       : (int -> int -> float) -> matrix -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+    val inplace_mapi  : (int -> int -> float -> float) -> matrix -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+    val inplace_cptMul : matrix -> matrix -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+    val inplace_scale  : float -> matrix -> unit
+
+    /// Operations to manipulate matrix types carrying
+    /// arbitrary element types. The names and types of the operations match those
+    /// in the containing module Math.Matrix. 
+    ///
+    /// The numeric operations on the element type (add, zero etc.) are inferred from the type
+    /// argument itself. That is, for some operations 
+    /// the element type of a matrix must have an associated instance of INumeric<'T> 
+    /// or some more specific numeric association (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+    [<RequireQualifiedAccess>]
+    module Generic =
+
+        /// Get an element from a matrix. The indexes are given in row/column order.
+        val get   : Matrix<'T> -> int -> int -> 'T
+        /// Set an element in a matrix. The indexes are given in row/column order.
+        val set   : Matrix<'T> -> int -> int -> 'T -> unit
+
+        /// Create a matrix from the given data  
+        val ofList      : 'T list list       -> Matrix<'T>
+
+        /// Create a matrix from the given data  
+        val ofSeq       : seq<#seq<'T>>     -> Matrix<'T>
+
+        /// Create a matrix from the given data  
+        val ofArray2D    : 'T[,]              -> Matrix<'T>
+
+        /// Return a new array containing the elements of the given matrix
+        val toArray2D : Matrix<'T>         -> 'T[,]  
+
+        /// Create a matrix containing the given value at every element.
+        val create     : int -> int -> 'T   -> Matrix<'T>
+
+        /// Create a dense matrix from the given sequence of elements
+        val initDense : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
+
+        /// Create a sparse matrix from the given sequence of elements
+        val initSparse : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
+
+        /// Create a 1x1 matrix containing the given value 
+        val ofScalar    : 'T                 -> Matrix<'T>
+
+        /// Create a matrix from a row vector
+        val ofRowVector  : RowVector<'T>     -> Matrix<'T>
+        /// Create a matrix from a column vector
+        val ofVector  : Vector<'T>        -> Matrix<'T>
+
+        /// Get the element at column zero, row zero
+        val toScalar : Matrix<'T>         -> 'T                
+        /// Extract the first row of a matrix
+        val toRowVector : Matrix<'T>         -> RowVector<'T>                 
+        /// Extract the first column of a matrix
+        val toVector : Matrix<'T>         -> Vector<'T> 
+
+
+        /// Create a matrix using a function to compute the item at each index.
+        val init : int -> int -> (int -> int -> 'T) -> Matrix<'T>
+
+        /// Create a matrix using a function to compute the item at each index.
+        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        /// The function is passed the dictionary of associated operations in addition to the index pair.
+        val initNumeric  : int -> int -> (INumeric<'T> -> int -> int -> 'T)        -> Matrix<'T>
+
+        /// Create a matrix containing the zero element at each index.
+        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        val zero      : int -> int         -> Matrix<'T>
+
+        /// Create a square matrix with the one for the element type lying on diagonal
+        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        val identity      : int -> Matrix<'T>
+
+        /// Create a matrix containing the given vector along the diagonal.
+        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        val initDiagonal : Vector<'T>        -> Matrix<'T>
+
+        ///Take the pointwise maximum of two matrices
+        val cptMax    : Matrix<'T> -> Matrix<'T> -> Matrix<'T> when 'T : comparison
+
+        ///Take the pointwise maximum of two matrices
+        val cptMin    : Matrix<'T> -> Matrix<'T> -> Matrix<'T> when 'T : comparison
+
+        /// Sum of the point-wise multiple of the two matrices.
+        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        val dot       : Matrix<'T> -> Matrix<'T> -> 'T
+
+
+        /// Return a new matrix which is the transpose of the input matrix
+        val transpose : Matrix<'T> -> Matrix<'T>
+
+        /// Compute the sum of the diagonal of a square matrix
+        val trace     : Matrix<'T> -> 'T
+        /// Compute the sum of the elements in a matrix
+        val sum       : Matrix<'T> -> 'T
+        /// Compute the product of the elements in a matrix
+        val prod      : Matrix<'T> -> 'T
+        /// Returns sqrt(sum(norm(x)*(norm(x))) of all the elements of a matrix.
+        /// The element type of a matrix must have an associated instance of INormFloat<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        val norm      : Matrix<'T> -> float
+
+        /// Fold a function over all elements of a matrix
+        val fold  : folder:('State -> 'T -> 'State) -> 'State -> Matrix<'T> -> 'State
+
+        /// Fold an indexed function over all elements of a matrix
+        val foldi  : (int -> int -> 'State -> 'T -> 'State) -> 'State -> Matrix<'T> -> 'State
+
+        /// Return true if a predicate returns true for all values in a matrix
+        val forall: ('T -> bool)           -> Matrix<'T> -> bool
+
+        /// Return true if a predicate returns true for some value in a matrix
+        val exists: ('T -> bool)           -> Matrix<'T> -> bool 
+
+        /// Return true if an indexed predicate returns true for all values in a matrix
+        val foralli: (int -> int -> 'T -> bool)           -> Matrix<'T> -> bool
+
+        /// Return true if an indexed predicate returns true for some value in a matrix
+        val existsi: (int -> int -> 'T -> bool)           -> Matrix<'T> -> bool 
+
+        /// Create a new matrix that is a copy of the given array
+        val copy : Matrix<'T> -> Matrix<'T>
+   
+        /// Map a function over a matrix
+        val map   : ('T -> 'T) -> Matrix<'T> -> Matrix<'T>
+
+        /// Map the given position-indexed function over a matrix
+        val mapi  : (int -> int -> 'T -> 'T) -> Matrix<'T> -> Matrix<'T>
+
+        /// Add the second matrix to the first by, mutating the first
+        val inplaceAdd    : Matrix<'T> -> Matrix<'T> -> unit
+        /// Subtract the second matrix from the first, by mutating the first
+        val inplaceSub    : Matrix<'T> -> Matrix<'T> -> unit
+
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.inplaceAdd' instead")>]
+        val inplace_add    : Matrix<'T> -> Matrix<'T> -> unit
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.inplaceSub' instead")>]
+        val inplace_sub    : Matrix<'T> -> Matrix<'T> -> unit
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofList' instead")>]
+        val of_list      : 'T list list       -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofSeq' instead")>]
+        val of_seq       : seq<#seq<'T>>     -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofArray2D' instead")>]
+        val inline of_array2D    : 'T[,]              -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toArray2D' instead")>]
+        val inline to_array2D : Matrix<'T>         -> 'T[,]  
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofScalar' instead")>]
+        val of_scalar    : 'T                 -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofRowVector' instead")>]
+        val of_rowvec  : RowVector<'T>     -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofVector' instead")>]
+        val of_vector  : Vector<'T>        -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toScalar' instead")>]
+        val to_scalar : Matrix<'T>         -> 'T                
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toRowVector' instead")>]
+        val to_rowvec : Matrix<'T>         -> RowVector<'T>                 
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toVector' instead")>]
+        val to_vector : Matrix<'T>         -> Vector<'T> 
+        [<Obsolete("This function has been renamed to 'initDiagonal'")>]
+        val init_diagonal : Vector<'T>        -> Matrix<'T>
+        [<Obsolete("This function has been renamed to 'initDense'")>]
+        val init_dense : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
+        [<Obsolete("This function has been renamed to 'initSparse'")>]
+        val init_sparse : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
+        [<Obsolete("Use the '.NonZeroEntries' property instead")>]
+        val nonzero_entries : Matrix<'T> -> seq<int * int * 'T> 
+        [<Obsolete("Use the 'Matrix.Generic.init' function instead")>]
+        val constDiag : int -> 'T          -> Matrix<'T>
+        [<Obsolete("Use the '+' operator instead")>]
+        val add       : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the 'initDiagonal' function instead")>]
+        val diag      : Vector<'T>        -> Matrix<'T>
+        [<Obsolete("Use the '*' operator instead")>]
+        val mul       : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the '*' operator instead")>]
+        val mulV      : Matrix<'T> -> Vector<'T> -> Vector<'T>
+        [<Obsolete("Use the '*' operator instead")>]
+        val mulRV     : RowVector<'T> -> Matrix<'T> -> RowVector<'T>
+        [<Obsolete("Use the '.*' operator instead")>]
+        val cptMul    : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the '-' operator instead")>]
+        val sub       : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the '-' prefix operator instead")>]
+        val neg       : Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the '*' operator instead")>]
+        val scale     : 'T  -> Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the '.Column' method instead")>]
+        val getCol  : Matrix<'T> -> int -> Vector<'T>
+        [<Obsolete("Use the '.Row' method instead")>]
+        val getRow  : Matrix<'T> -> int -> RowVector<'T>
+        [<Obsolete("Use the '.Columns' method instead")>]
+        val getCols : Matrix<'T> -> start:int -> length:int -> Matrix<'T>
+        [<Obsolete("Use the '.Rows' method instead")>]
+        val getRows : Matrix<'T> -> start:int -> length:int -> Matrix<'T>
+        [<Obsolete("Use the '.Region' method instead")>]
+        val getRegion  : Matrix<'T> -> starti:int -> startj:int -> lengthi:int -> lengthj:int -> Matrix<'T>
+        [<Obsolete("Use the '.Diagonal' method instead")>]
+        val getDiagN : Matrix<'T> -> int    -> Vector<'T>
+        [<Obsolete("Use the '.Diagonal' property instead")>]
+        val getDiag  : Matrix<'T>           -> Vector<'T>
+        [<Obsolete("This function will be removed in a future revision of this library. Just use 'compare m1 m2' instead")>]
+        val compare  : Matrix<'T> -> Matrix<'T> -> int
+        [<Obsolete("This function will be removed in a future revision of this library. Just use 'hash m' instead")>]
+        val hash     : Matrix<'T> -> int
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+        val inplace_assign       : (int -> int -> 'T) -> Matrix<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+        val inplace_mapi  : (int -> int -> 'T -> 'T) -> Matrix<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+        val inplace_cptMul : Matrix<'T> -> Matrix<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+        val inplace_scale  : 'T -> Matrix<'T> -> unit
+
+
+/// Operations to manipulate floating
+/// point column vectors. The submodule VectorOps.Generic contains a 
+/// matching set of operations to manipulate column vectors carrying
+/// arbitrary element types.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<RequireQualifiedAccess>]
+module Vector =
+
+    /// Get an element of a column vector
+    val get   : vector -> int -> float
+
+    /// Set an element of a column vector
+    val set   : vector -> int -> float -> unit
+
+    /// Get the dimensions (number of rows) of a column vector. Identical to <c>nrows</c>
+    val length   : vector -> int 
+
+    /// Create a vector of a fixed length using a function to compute the initial element values
+    val init  : int ->        (int -> float)        -> vector
+
+    /// Create a vector from a list of numbers
+    val ofList   : float list          -> vector
+    
+    /// Create a vector from a sequence of numbers
+    val ofSeq    : seq<float>         -> vector
+
+    /// Create a vector from an array of double precision floats
+    val ofArray  : float array         -> vector
+
+    /// Return a new array containing a copy of the elements of the given vector
+    val toArray  : vector           -> float array
+    
+    /// Create a 1-element vector
+    val ofScalar  : float              -> vector
+
+    /// Generate a vector of the given length where each entry contains the given value
+    val create    : int        -> float -> vector
+    
+    /// Return a vector of the given length where every entry is zero.
+    val zero     : int                 -> vector
+    
+    /// Create a vector that represents a mesh over the given range
+    /// e.g. rangef (-1.0) 0.5 1.0 = vector [ -1.0; -0.5; 0.0; 0.5; 1.0]
+    val rangef : float -> float -> float -> vector
+    
+    /// Create a vector that represents a integral mesh over the given range
+    /// e.g. range 1 5 = vector [ 1.;2.;3.;4.;5. ]
+    val range  : int -> int              -> vector
+      
+    ///Dot product
+    val dot       : vector -> vector -> float
+
+    ///Point-wise exponential of a vector.
+    val cptPow    : vector -> float -> vector
+
+    ///Transpose of a matrix. Use also m.Transpose
+    val transpose     :           vector -> rowvec
+
+    ///Sum all the elements of a vector
+    val sum       : vector -> float
+
+    ///Multiply all the elements of a matrix
+    val prod      : vector -> float
+
+    /// Computes the 2-norm of a vector: sqrt(x.Transpose*x).
+    val norm      : vector -> float
+
+    /// Return true if a predicate returns true for all values in a vector
+    val forall  : (float -> bool) -> vector -> bool
+
+    /// Return true if a predicate returns true for some value in a vector
+    val exists  : (float -> bool) -> vector -> bool 
+
+    /// Return true if an indexed predicate returns true for all values in a vector
+    val foralli  : (int ->        float -> bool) -> vector -> bool
+
+    /// Return true if an indexed predicate returns true for some value in a vector
+    val existsi  : (int ->        float -> bool) -> vector -> bool 
+
+    /// Fold a function over all elements of a vector
+    val fold      : ('T -> float -> 'T) -> 'T         -> vector -> 'T
+
+    /// Fold an indexed function over all elements of a vector
+    val foldi      : (int -> 'T -> float -> 'T) -> 'T         -> vector -> 'T
+
+    /// Copy a vector
+    val copy : vector -> vector
+    
+    /// Map a function over each element of a vector
+    val map  : (float -> float) -> vector -> vector
+   
+    /// Map an indexed function over each element of a vector
+    val mapi  : (int        -> float -> float) -> vector -> vector
+   
+    [<System.Obsolete("This function has been renamed. Use 'Vector.ofList' instead")>]
+    val of_list   : float list          -> vector
+    [<System.Obsolete("This function has been renamed. Use 'Vector.ofSeq' instead")>]
+    val of_seq    : seq<float>         -> vector
+    [<System.Obsolete("This function has been renamed. Use 'Vector.ofArray' instead")>]
+    val of_array  : float array         -> vector
+    [<System.Obsolete("This function has been renamed. Use 'Vector.toArray' instead")>]
+    val to_array  : vector           -> float array
+    [<System.Obsolete("This function has been renamed. Use 'Vector.ofScalar' instead")>]
+    val of_scalar  : float              -> vector
+    [<Obsolete("Use the '+' operator instead")>]
+    val add       : vector -> vector -> vector
+    [<Obsolete("Use the '-' operator instead")>]
+    val sub       : vector -> vector -> vector
+    [<Obsolete("Use the '-' prefix operator instead")>]
+    val neg       :           vector -> vector
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_assign       : (int ->        float) -> vector -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_mapi  : (int ->        float -> float) -> vector -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_add    : vector -> vector -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_sub    : vector -> vector -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_cptMul : vector -> vector -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_scale  : float -> vector -> unit
+    [<Obsolete("Use the '.*' operator instead")>]
+    val cptMul    : vector -> vector -> vector
+    [<Obsolete("Use the '*' operator instead")>]
+    val scale     : float  -> vector -> vector
+
+    
+    /// Operations to manipulate column vectors carrying
+    /// arbitrary element types. 
+    module Generic =
+        // Accessors
+
+        /// Get an element of a column vector
+        val get   : Vector<'T> -> int -> 'T
+
+        /// Set an element of a column vector
+        val set   : Vector<'T> -> int -> 'T -> unit
+
+        /// Get the dimensions (number of rows) of a column vector. Identical to <c>nrows</c>
+        val length   : Vector<'T> -> int 
+
+        /// Creation: general
+        val init  : int ->        (int -> 'T)        -> Vector<'T>
+
+        /// Creation: useful when the element type has associated operations.
+        val initNumeric  : int ->        (INumeric<'T> -> int -> 'T)        -> Vector<'T>
+
+        /// Create a vector from a list of numbers
+        val ofList   : 'T list          -> Vector<'T>
+      
+        /// Create a vector from a sequence of numbers
+        val ofSeq    : seq<'T>         -> Vector<'T>
+
+        /// Create a 1-element vector
+        val ofScalar  : 'T              -> Vector<'T>
+
+        /// Create a vector from an array of elements
+        val ofArray  : 'T[]         -> Vector<'T>
+
+        /// Return a new array containing a copy of the elements of the given vector
+        val toArray  : Vector<'T>    -> 'T[]
+
+        /// Generate a vector of the given length where each entry contains the given value
+        val create    : int        -> 'T -> Vector<'T>
+      
+        /// Return a vector of the given length where every entry is zero.
+        val zero     : int                 -> Vector<'T>
+      
+        ///Take the pointwise maximum of two vectors
+        val cptMax    : Vector<'T> -> Vector<'T> -> Vector<'T> when 'T : comparison
+
+        ///Take the pointwise minimum of two vectors
+        val cptMin    : Vector<'T> -> Vector<'T> -> Vector<'T> when 'T : comparison
+
+        ///Dot product
+        val dot       : Vector<'T> -> Vector<'T> -> 'T
+
+        ///Sum all the elements of a vector
+        val sum       : Vector<'T> -> 'T
+      
+        ///Multiply all the elements of a matrix
+        val prod      : Vector<'T> -> 'T
+
+        /// Computes the 2-norm of a vector: sqrt(x.Transpose*x).
+        val norm      : Vector<'T> -> float
+
+        /// Return true if a predicate returns true for all values in a vector
+        val forall  : predicate:('T -> bool) -> Vector<'T> -> bool
+
+        /// Return true if a predicate returns true for some value in a vector
+        val exists  : predicate:('T -> bool) -> Vector<'T> -> bool 
+
+        /// Return true if an indexed predicate returns true for all values in a vector
+        val foralli  : (int -> 'T -> bool) -> Vector<'T> -> bool
+
+        /// Return true if an indexed predicate returns true for some value in a vector
+        val existsi  : (int -> 'T -> bool) -> Vector<'T> -> bool 
+
+        /// Fold a function over all elements of a vector
+        val fold      : folder:('State -> 'T -> 'State) -> 'State -> Vector<'T> -> 'State
+
+        /// Fold an indexed function over all elements of a vector
+        val foldi      : (int -> 'State -> 'T -> 'State) -> 'State -> Vector<'T> -> 'State
+
+        /// Copy the vector
+        val copy: Vector<'T> -> Vector<'T>
+        
+        /// Map a function over each element of a vector
+        val map  : ('T -> 'T) -> Vector<'T> -> Vector<'T>
+     
+        /// Map an indexed function over each element of a vector
+        val mapi  : (int        -> 'T -> 'T) -> Vector<'T> -> Vector<'T>
+     
+
+        [<System.Obsolete("This function has been renamed. Use 'Vector.ofList' instead")>]
+        val of_list   : 'T list          -> Vector<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Vector.ofSeq' instead")>]
+        val of_seq    : seq<'T>         -> Vector<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Vector.ofScalar' instead")>]
+        val of_scalar  : 'T              -> Vector<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Vector.ofArray' instead")>]
+        val of_array  : 'T[]         -> Vector<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Vector.toArray' instead")>]
+        val to_array  : Vector<'T>    -> 'T[]
+        [<Obsolete("Use the .* operator instead")>]
+        val cptMul    : Vector<'T> -> Vector<'T> -> Vector<'T>      
+        [<Obsolete("Use the 'vector.Transpose' property instead")>]
+        val transpose : Vector<'T> -> RowVector<'T>
+        [<Obsolete("Use the '+' operator instead")>]
+        val add       : Vector<'T> -> Vector<'T> -> Vector<'T>
+        [<Obsolete("Use the '-' operator instead")>]
+        val sub       : Vector<'T> -> Vector<'T> -> Vector<'T>
+        [<Obsolete("Use the '-' prefix operator instead")>]
+        val neg       : Vector<'T> -> Vector<'T>
+        [<Obsolete("Use the '*' operator instead")>]
+        val scale     : 'T  -> Vector<'T> -> Vector<'T>
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_assign : (int -> 'T) -> Vector<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_mapi  : (int -> 'T -> 'T) -> Vector<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_add    : Vector<'T> -> Vector<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_sub    : Vector<'T> -> Vector<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_cptMul : Vector<'T> -> Vector<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_scale  : 'T -> Vector<'T> -> unit
+
+
+
+/// Operations to manipulate floating
+/// point row vectors. These are included for completeness and are
+/// nearly always transposed to column vectors.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<RequireQualifiedAccess>]
+module RowVector =
+
+    /// Get an element of a column vector
+    val get   : rowvec -> int -> float
+
+    /// Set an element of a column rowvec
+    val set   : rowvec -> int -> float -> unit
+
+    /// Get the dimensions (number of rows) of a column rowvec. 
+    val length   : rowvec -> int 
+
+    /// Create by constant initialization
+    val create : int -> float  -> rowvec
+
+    /// Create by comprehension
+    val init : int ->  (int -> float) -> rowvec
+
+    /// Return a vector of the given length where every entry is zero.
+    val zero     : int -> rowvec
+
+    // Transpose the row vector
+    val transpose : rowvec -> vector
+
+    // Copy the row vector
+    val copy : rowvec -> rowvec
+
+    /// Create a vector from a list of numbers
+    val ofList   : float list          -> rowvec
+
+    /// Create a vector from a sequence of numbers
+    val ofSeq    : seq<float>         -> rowvec
+
+    /// Create a vector from an array of double precision floats
+    val ofArray  : float array         -> rowvec
+
+    /// Return a new array containing a copy of the elements of the given vector
+    val toArray  : rowvec              -> float array
+    
+    [<System.Obsolete("This function has been renamed. Use 'RowVector.ofList' instead")>]
+    val of_list   : float list          -> rowvec
+    [<System.Obsolete("This function has been renamed. Use 'RowVector.ofSeq' instead")>]
+    val of_seq    : seq<float>         -> rowvec
+    [<System.Obsolete("This function has been renamed. Use 'RowVector.ofArray' instead")>]
+    val of_array  : float array         -> rowvec
+    [<System.Obsolete("This function has been renamed. Use 'RowVector.toArray' instead")>]
+    val to_array  : rowvec              -> float array
+    
+    
+    /// Operations to manipulate row vectors types carrying
+    /// arbitrary element types. 
+    module Generic =
+        // Accessors
+
+        /// Get an element from a column vector. 
+        val get   : RowVector<'T> -> int -> 'T
+        /// Set an element in a column vector. 
+        val set   : RowVector<'T> -> int -> 'T -> unit
+        /// Get the number of rows in a column vector. 
+        val length: RowVector<'T> -> int 
+        /// Transpose the row vector
+        val transpose        : RowVector<'T>  -> Vector<'T> 
+        /// Create by comprehension
+        val init       : int ->        (int -> 'T)        -> RowVector<'T> 
+        /// Create by constant initialization
+        val create       : int ->      'T  -> RowVector<'T> 
+        /// Return a vector of the given length where every entry is zero.
+        val zero     : int                 -> RowVector<'T>
+        /// Create a row vector from a list of elements
+        val ofList   : 'T list          -> RowVector<'T> 
+        /// Create a row vector from a sequence of elements
+        val ofSeq    : seq<'T>         -> RowVector<'T> 
+
+        /// Create a row vector from an array of elements
+        val ofArray  : 'T[]         -> RowVector<'T>
+
+        /// Return a new array containing a copy of the elements of the given vector
+        val toArray  : RowVector<'T>    -> 'T[]         
+
+        // Copy the row vector
+        val copy    :   RowVector<'T> -> RowVector<'T>
+
+        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.ofList' instead")>]
+        val of_list   : 'T list          -> RowVector<'T> 
+        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.ofSeq' instead")>]
+        val of_seq    : seq<'T>         -> RowVector<'T> 
+        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.ofArray' instead")>]
+        val of_array  : 'T[]         -> RowVector<'T>
+        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.toArray' instead")>]
+        val to_array  : RowVector<'T>    -> 'T[]         
+
+[<AutoOpen>]
+module MatrixTopLevelOperators = 
+    /// Builds a matrix from a sequence of sequence of floats.
+    val matrix : seq<#seq<float>> -> matrix
+    /// Builds a (column) vector from a sequence of floats.
+    val vector : seq<float> -> vector
+    /// Builds a (row) vector from a sequence of floats.
+    val rowvec : seq<float> -> rowvec
+
diff --git a/src/FSharp.PowerPack/math/q.fs b/src/FSharp.PowerPack/math/q.fs
new file mode 100755
index 0000000..8eac6cb
--- /dev/null
+++ b/src/FSharp.PowerPack/math/q.fs
@@ -0,0 +1,305 @@
+// (c) Microsoft Corporation. All rights reserved 
+
+#nowarn "44"  // OK to use the "compiler only" function RangeGeneric
+#nowarn "52"  // The value has been copied to ensure the original is not mutated by this operation
+
+namespace Microsoft.FSharp.Math
+
+    open System
+    open System.Numerics
+    open System.Globalization
+
+    module BigRationalLargeImpl = 
+        let ZeroI = new BigInteger(0)
+        let OneI = new BigInteger(1)
+        let bigint (x:int) = new BigInteger(x)
+        let ToDoubleI (x:BigInteger) =  double x
+        let ToInt32I (x:BigInteger) = int32 x
+
+    open BigRationalLargeImpl
+        
+    [<CustomEquality; CustomComparison>]
+    type BigRationalLarge = 
+        | Q of BigInteger * BigInteger // invariants: (p,q) in lowest form, q >= 0 
+
+        override n.ToString() =
+            let (Q(p,q)) = n 
+            if q.IsOne then p.ToString() 
+            else p.ToString() + "/" + q.ToString()
+
+
+        static member Hash (Q(ap,aq)) = 
+            // This hash code must be identical to the hash for BigInteger when the numbers coincide.
+            if aq.IsOne then ap.GetHashCode() else (ap.GetHashCode() <<< 3) + aq.GetHashCode()
+        
+
+        override x.GetHashCode()            = BigRationalLarge.Hash(x)
+        
+        static member Equals(Q(ap,aq), Q(bp,bq)) = 
+            BigInteger.(=)  (ap,bp) && BigInteger.(=) (aq,bq)   // normal form, so structural equality 
+        
+        static member LessThan(Q(ap,aq), Q(bp,bq)) = 
+            BigInteger.(<)  (ap * bq,bp * aq)
+        
+        // note: performance improvement possible here
+        static member Compare(p,q) = 
+            if BigRationalLarge.LessThan(p,q) then -1 
+            elif BigRationalLarge.LessThan(q,p)then  1 
+            else 0 
+
+        interface System.IComparable with 
+            member this.CompareTo(obj:obj) = 
+                match obj with 
+                | :? BigRationalLarge as that -> BigRationalLarge.Compare(this,that)
+                | _ -> invalidArg "obj" "the object does not have the correct type"
+
+        override this.Equals(that:obj) = 
+            match that with 
+            | :? BigRationalLarge as that -> BigRationalLarge.Equals(this,that)
+            | _ -> false
+
+        member x.IsNegative = let (Q(ap,_)) = x in sign ap < 0
+        member x.IsPositive = let (Q(ap,_)) = x in sign ap > 0
+
+        member x.Numerator = let (Q(p,_)) = x in p
+        member x.Denominator = let (Q(_,q)) = x in q
+        member x.Sign = (let (Q(p,_)) = x in sign p)
+
+        static member ToDouble (Q(p,q)) = 
+            ToDoubleI p / ToDoubleI q
+
+        static member Normalize (p:BigInteger,q:BigInteger) =
+            if q.IsZero then
+                raise (System.DivideByZeroException())  (* throw for any x/0 *)
+            elif q.IsOne then
+                Q(p,q)
+            else
+                let k = BigInteger.GreatestCommonDivisor(p,q)
+                let p = p / k 
+                let q = q / k 
+                if sign q < 0 then Q(-p,-q) else Q(p,q)
+
+        static member Rational  (p:int,q:int) = BigRationalLarge.Normalize (bigint p,bigint q)
+        static member RationalZ (p,q) = BigRationalLarge.Normalize (p,q)
+       
+        static member Parse (str:string) =
+          let len = str.Length 
+          if len=0 then invalidArg "str" "empty string";
+          let j = str.IndexOf '/' 
+          if j >= 0 then 
+              let p = BigInteger.Parse (str.Substring(0,j)) 
+              let q = BigInteger.Parse (str.Substring(j+1,len-j-1)) 
+              BigRationalLarge.RationalZ (p,q)
+          else
+              let p = BigInteger.Parse str 
+              BigRationalLarge.RationalZ (p,OneI)
+        
+        static member (~-) (Q(bp,bq))    = Q(-bp,bq)          // still coprime, bq >= 0 
+        static member (+) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize ((ap * bq) + (bp * aq),aq * bq)
+        static member (-) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize ((ap * bq) - (bp * aq),aq * bq)
+        static member (*) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize (ap * bp,aq * bq)
+        static member (/) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize (ap * bq,aq * bp)
+        static member ( ~+ )(n1:BigRationalLarge) = n1
+        
+ 
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module BigRationalLarge = 
+        open System.Numerics
+    
+        let inv    (Q(ap,aq)) = BigRationalLarge.Normalize(aq,ap)    
+
+        let pown (Q(p,q)) (n:int) = Q(BigInteger.Pow(p,n),BigInteger.Pow  (q,n)) // p,q powers still coprime
+        
+        let equal (Q(ap,aq)) (Q(bp,bq)) = ap=bp && aq=bq   // normal form, so structural equality 
+        let lt    a b = BigRationalLarge.LessThan(a,b)
+        let gt    a b = BigRationalLarge.LessThan(b,a)
+        let lte   (Q(ap,aq)) (Q(bp,bq)) = BigInteger.(<=) (ap * bq,bp * aq)
+        let gte   (Q(ap,aq)) (Q(bp,bq)) = BigInteger.(>=) (ap * bq,bp * aq)
+
+        let of_bigint   z = BigRationalLarge.RationalZ(z,OneI )
+        let of_int n = BigRationalLarge.Rational(n,1)
+       
+        // integer part
+        let integer (Q(p,q)) =
+            let mutable r = BigInteger(0)
+            let d = BigInteger.DivRem (p,q,&r)          // have p = d.q + r, |r| < |q| 
+            if r < ZeroI
+            then d - OneI                 // p = (d-1).q + (r+q) 
+            else d                             // p =     d.q + r       
+      
+        
+    //----------------------------------------------------------------------------
+    // BigRational
+    //--------------------------------------------------------------------------
+
+    [<CustomEquality; CustomComparison>]
+    [<StructuredFormatDisplay("{StructuredDisplayString}N")>]
+    type BigRational =
+        | Z of BigInteger
+        | Q of BigRationalLarge
+
+        static member ( + )(n1,n2) = 
+            match n1,n2 with
+            | Z z ,Z zz -> Z (z + zz)
+            | Q q ,Q qq -> Q (q + qq)
+            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z + qq)
+            | Q q ,Z zz -> Q (q  + BigRationalLarge.of_bigint zz)
+
+        static member ( * )(n1,n2) = 
+            match n1,n2 with
+            | Z z ,Z zz -> Z (z * zz)
+            | Q q ,Q qq -> Q (q * qq)
+            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z * qq)
+            | Q q ,Z zz -> Q (q  * BigRationalLarge.of_bigint zz)
+
+        static member ( - )(n1,n2) = 
+            match n1,n2 with
+            | Z z ,Z zz -> Z (z - zz)
+            | Q q ,Q qq -> Q (q - qq)
+            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z - qq)
+            | Q q ,Z zz -> Q (q  - BigRationalLarge.of_bigint zz)
+
+        static member ( / )(n1,n2) = 
+            match n1,n2 with
+            | Z z ,Z zz -> Q (BigRationalLarge.RationalZ(z,zz))
+            | Q q ,Q qq -> Q (q / qq)
+            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z / qq)
+            | Q q ,Z zz -> Q (q  / BigRationalLarge.of_bigint zz)
+
+        static member ( ~- )(n1) = 
+            match n1 with
+            | Z z -> Z (-z)
+            | Q q -> Q (-q)
+
+        static member ( ~+ )(n1:BigRational) = n1
+
+        // nb. Q and Z hash codes must match up - see notes above
+        override n.GetHashCode() = 
+            match n with 
+            | Z z -> z.GetHashCode()
+            | Q q -> q.GetHashCode() 
+
+        override this.Equals(obj:obj) = 
+            match obj with 
+            | :? BigRational as that -> BigRational.(=)(this, that)
+            | _ -> false
+
+        interface System.IComparable with 
+            member n1.CompareTo(obj:obj) = 
+                match obj with 
+                | :? BigRational as n2 -> 
+                      if BigRational.(<)(n1, n2) then -1 elif BigRational.(=)(n1, n2) then 0 else 1
+                | _ -> invalidArg "obj" "the objects are not comparable"
+
+        static member FromInt (x:int) = Z (bigint x)
+        static member FromBigInt x = Z x
+
+        static member Zero = BigRational.FromInt(0) 
+        static member One = BigRational.FromInt(1) 
+
+
+        static member PowN (n,i:int) =
+            match n with
+            | Z z -> Z (BigInteger.Pow (z,i))
+            | Q q -> Q (BigRationalLarge.pown q i)
+
+        static member op_Equality (n,nn) = 
+            match n,nn with
+            | Z z ,Z zz -> BigInteger.(=) (z,zz)
+            | Q q ,Q qq -> (BigRationalLarge.equal q qq)
+            | Z z ,Q qq -> (BigRationalLarge.equal (BigRationalLarge.of_bigint z) qq)
+            | Q q ,Z zz -> (BigRationalLarge.equal q (BigRationalLarge.of_bigint zz))
+        static member op_Inequality (n,nn) = not (BigRational.op_Equality(n,nn))
+    
+        static member op_LessThan (n,nn) = 
+            match n,nn with
+            | Z z ,Z zz -> BigInteger.(<) (z,zz)
+            | Q q ,Q qq -> (BigRationalLarge.lt q qq)
+            | Z z ,Q qq -> (BigRationalLarge.lt (BigRationalLarge.of_bigint z) qq)
+            | Q q ,Z zz -> (BigRationalLarge.lt q (BigRationalLarge.of_bigint zz))
+        static member op_GreaterThan (n,nn) = 
+            match n,nn with
+            | Z z ,Z zz -> BigInteger.(>) (z,zz)
+            | Q q ,Q qq -> (BigRationalLarge.gt q qq)
+            | Z z ,Q qq -> (BigRationalLarge.gt (BigRationalLarge.of_bigint z) qq)
+            | Q q ,Z zz -> (BigRationalLarge.gt q (BigRationalLarge.of_bigint zz))
+        static member op_LessThanOrEqual (n,nn) = 
+            match n,nn with
+            | Z z ,Z zz -> BigInteger.(<=) (z,zz)
+            | Q q ,Q qq -> (BigRationalLarge.lte q qq)
+            | Z z ,Q qq -> (BigRationalLarge.lte (BigRationalLarge.of_bigint z) qq)
+            | Q q ,Z zz -> (BigRationalLarge.lte q (BigRationalLarge.of_bigint zz))
+        static member op_GreaterThanOrEqual (n,nn) = 
+            match n,nn with
+            | Z z ,Z zz -> BigInteger.(>=) (z,zz)
+            | Q q ,Q qq -> (BigRationalLarge.gte q qq)
+            | Z z ,Q qq -> (BigRationalLarge.gte (BigRationalLarge.of_bigint z) qq)
+            | Q q ,Z zz -> (BigRationalLarge.gte q (BigRationalLarge.of_bigint zz))
+        
+
+        member n.IsNegative = 
+            match n with 
+            | Z z -> sign z < 0 
+            | Q q -> q.IsNegative
+
+        member n.IsPositive = 
+            match n with 
+            | Z z -> sign z > 0
+            | Q q -> q.IsPositive
+            
+        member n.Numerator = 
+            match n with 
+            | Z z -> z
+            | Q q -> q.Numerator
+
+        member n.Denominator = 
+            match n with 
+            | Z _ -> OneI
+            | Q q -> q.Denominator
+
+        member n.Sign = 
+            if n.IsNegative then -1 
+            elif n.IsPositive then  1 
+            else 0
+
+        static member Abs(n:BigRational) = 
+            if n.IsNegative then -n else n
+
+        static member ToDouble(n:BigRational) = 
+            match n with
+            | Z z -> ToDoubleI z
+            | Q q -> BigRationalLarge.ToDouble q
+
+        static member ToBigInt(n:BigRational) = 
+            match n with 
+            | Z z -> z
+            | Q q -> BigRationalLarge.integer q 
+
+        static member ToInt32(n:BigRational) = 
+            match n with 
+            | Z z -> ToInt32I(z)
+            | Q q -> ToInt32I(BigRationalLarge.integer q )
+
+        static member op_Explicit (n:BigRational) = BigRational.ToInt32 n
+        static member op_Explicit (n:BigRational) = BigRational.ToDouble n
+        static member op_Explicit (n:BigRational) = BigRational.ToBigInt n
+
+
+        override n.ToString() = 
+            match n with 
+            | Z z -> z.ToString()
+            | Q q -> q.ToString()
+
+        member x.StructuredDisplayString = x.ToString()
+                   
+        static member Parse(s:string) = Q (BigRationalLarge.Parse s)
+
+    type BigNum = BigRational
+    type bignum = BigNum
+
+    module NumericLiteralN = 
+        let FromZero () = BigRational.Zero 
+        let FromOne () = BigRational.One 
+        let FromInt32 i = BigRational.FromInt i
+        let FromInt64 (i64:int64) = BigRational.FromBigInt (new BigInteger(i64))
+        let FromString s = BigRational.Parse s
diff --git a/src/FSharp.PowerPack/math/q.fsi b/src/FSharp.PowerPack/math/q.fsi
new file mode 100755
index 0000000..4d75d1e
--- /dev/null
+++ b/src/FSharp.PowerPack/math/q.fsi
@@ -0,0 +1,92 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+    open System
+    open System.Numerics
+      
+    /// The type of arbitrary-sized rational numbers
+    [<Sealed>]
+    type BigRational =
+        /// Return the sum of two rational numbers
+        static member ( + ) : BigRational * BigRational -> BigRational
+        /// Return the product of two rational numbers
+        static member ( * ) : BigRational * BigRational -> BigRational
+        /// Return the difference of two rational numbers
+        static member ( - ) : BigRational * BigRational -> BigRational
+        /// Return the ratio of two rational numbers
+        static member ( / ) : BigRational * BigRational -> BigRational
+        /// Return the negation of a rational number
+        static member ( ~- ): BigRational          -> BigRational
+        /// Return the given rational number
+        static member ( ~+ ): BigRational          -> BigRational
+
+        override ToString: unit -> string
+        override GetHashCode: unit -> int
+        interface System.IComparable
+
+        /// Get zero as a rational number
+        static member Zero : BigRational  
+        /// Get one as a rational number
+        static member One : BigRational  
+        /// This operator is for use from other .NET languages
+        static member op_Equality : BigRational * BigRational -> bool
+        /// This operator is for use from other .NET languages
+        static member op_Inequality : BigRational * BigRational -> bool
+        /// This operator is for use from other .NET languages
+        static member op_LessThan: BigRational * BigRational -> bool 
+        /// This operator is for use from other .NET languages
+        static member op_GreaterThan: BigRational * BigRational -> bool 
+        /// This operator is for use from other .NET languages
+        static member op_LessThanOrEqual: BigRational * BigRational -> bool 
+        /// This operator is for use from other .NET languages
+        static member op_GreaterThanOrEqual: BigRational * BigRational -> bool
+        
+        /// Return a boolean indicating if this rational number is strictly negative
+        member IsNegative: bool 
+        /// Return a boolean indicating if this rational number is strictly positive
+        member IsPositive: bool 
+
+        /// Return the numerator of the normalized rational number
+        member Numerator: BigInteger
+        /// Return the denominator of the normalized rational number
+        member Denominator: BigInteger
+
+        member StructuredDisplayString : string
+
+        /// Return the absolute value of a rational number 
+        static member Abs : BigRational -> BigRational
+        /// Return the sign of a rational number; 0, +1 or -1
+        member Sign : int 
+        /// Return the result of raising the given rational number to the given power
+        static member PowN : BigRational * int -> BigRational
+        /// Return the result of converting the given integer to a rational number
+        static member FromInt : int         -> BigRational  
+        /// Return the result of converting the given big integer to a rational number
+        static member FromBigInt : BigInteger      -> BigRational  
+        /// Return the result of converting the given rational number to a floating point number
+        static member ToDouble: BigRational -> float 
+        /// Return the result of converting the given rational number to a big integer
+        static member ToBigInt: BigRational -> BigInteger
+        /// Return the result of converting the given rational number to an integer
+        static member ToInt32 : BigRational -> int
+        /// Return the result of converting the given rational number to a floating point number
+        static member op_Explicit : BigRational -> float 
+        /// Return the result of converting the given rational number to a big integer
+        static member op_Explicit : BigRational -> BigInteger
+        /// Return the result of converting the given rational number to an integer
+        static member op_Explicit : BigRational -> int
+        /// Return the result of converting the string to a rational number 
+        static member Parse: string -> BigRational
+
+    type BigNum = BigRational
+
+    type bignum = BigRational
+
+    [<RequireQualifiedAccess>]
+    module NumericLiteralN = 
+        val FromZero : unit -> BigRational
+        val FromOne : unit -> BigRational
+        val FromInt32 : int32 -> BigRational
+        val FromInt64 : int64 -> BigRational
+        val FromString : string -> BigRational
\ No newline at end of file
diff --git a/src/FSharpPowerPackSource.Settings.targets b/src/FSharpPowerPackSource.Settings.targets
new file mode 100755
index 0000000..ca5a891
--- /dev/null
+++ b/src/FSharpPowerPackSource.Settings.targets
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <PropertyGroup>
+    <!-- Standard defaults for configuration and platform  -->
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+  </PropertyGroup>
+  <PropertyGroup>
+    <!-- Standard defaults for warning level -->
+    <WarningLevel Condition=" '$(WarningLevel)' == '' ">3</WarningLevel>
+  </PropertyGroup>
+  <!-- Standard interpretations of Debug and Release configurations -->
+  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <DebugType Condition=" '$(DebugType)' == '' ">full</DebugType>
+    <Optimize Condition=" '$(Optimize)' == '' ">false</Optimize>
+    <DefineConstants Condition=" '$(DefineConstants)' == '' ">DEBUG;TRACE</DefineConstants>
+    <ErrorReport Condition=" '$(ErrorReport)' == '' ">prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+    <DebugType Condition=" '$(DebugType)' == '' ">pdbonly</DebugType>
+    <Optimize Condition=" '$(Optimize)' == '' ">true</Optimize>
+    <DefineConstants Condition=" '$(DefineConstants)' == '' ">TRACE</DefineConstants>
+    <ErrorReport Condition=" '$(ErrorReport)' == '' ">prompt</ErrorReport>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/src/FSharpPowerPackSource.targets b/src/FSharpPowerPackSource.targets
new file mode 100755
index 0000000..d3a4ad2
--- /dev/null
+++ b/src/FSharpPowerPackSource.targets
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(TargetFramework)' == 'Silverlight'">
+    <SilverlightVersion Condition="'$(SilverlightVersion)' == ''">v3.0</SilverlightVersion>
+  </PropertyGroup>
+  <PropertyGroup>
+    <LkgVersion>1.9.7.7</LkgVersion>
+    <FsLexUnicode>true</FsLexUnicode>
+    <OutputPath Condition="'$(TargetFramework)' == ''">$(FSharpPowerPackSourcesRoot)\..\$(Configuration)\bin</OutputPath>
+    <OutputPath Condition="'$(TargetFramework)' == 'Silverlight'">$(FSharpPowerPackSourcesRoot)\..\$(TargetFramework)\$(SilverlightVersion)\$(Configuration)\bin</OutputPath>
+    <IntermediateOutputPath Condition="'$(TargetFramework)' == ''">obj\$(Configuration)</IntermediateOutputPath>    
+    <IntermediateOutputPath Condition="'$(TargetFramework)' == 'Silverlight'">obj\$(TargetFramework)\$(SilverlightVersion)\$(Configuration)</IntermediateOutputPath>
+    <FsLexToolPath>$(FSharpPowerPackSourcesRoot)\..\lkg\FSharp.PowerPack-$(LkgVersion)\bin</FsLexToolPath>
+    <FsLexToolExe>FsLex.exe</FsLexToolExe>
+    <FsYaccToolPath>$(FSharpPowerPackSourcesRoot)\..\lkg\FSharp.PowerPack-$(LkgVersion)\bin</FsYaccToolPath>
+    <FsYaccToolExe>FsYacc.exe</FsYaccToolExe>
+    
+  </PropertyGroup>
+
+  <!-- Selecting the correct key pair -->
+
+  <PropertyGroup Condition=" '$(TargetFramework)' != 'Silverlight' AND '$(StrongName)' != 'false'">
+    <OtherFlags Condition="Exists('$(FSharpPowerPackSourcesRoot)\fs.snk')">/keyfile:$(FSharpPowerPackSourcesRoot)\fs.snk $(OtherFlags)</OtherFlags>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(TargetFramework)' == 'Silverlight'  ">  
+    <OtherFlags Condition="Exists('$(FSharpPowerPackSourcesRoot)\fsSilverlight.snk') AND '$(StrongName)' != 'false'">/keyfile:$(FSharpPowerPackSourcesRoot)\fsSilverlight.snk $(OtherFlags)</OtherFlags>
+    <DefineConstants>$(DefineConstants);SILVERLIGHT;FX_NO_COMMAND_LINE_ARGS;FX_NO_CULTURE_INFO_ARGS;FX_NO_FILE_OPTIONS;FX_NO_FILESTREAM_ISASYNC;FX_NO_UTF32ENCODING;FX_NO_EXIT;FX_NO_DEFAULT_DEPENDENCY_TYPE;FX_NO_TO_LOWER_INVARIANT;FX_NO_DOUBLE_BIT_CONVERTER;FX_NO_TRUNCATE;FX_NO_ENVIRONMENT;FX_NO_PROCESS_START;FX_NO_PROCESS_DIAGNOSTICS;FX_NO_APP_DOMAINS;FX_NO_DEFAULT_ENCODING;FX_NO_NONBLOCK_IO;FX_NO_BINARY_SERIALIZATION;FX_NO_ASCII_ENCODING;FX_NO_FILEWRITEALL;FX_NO_WINDOWSFORMS;FX_NO_DEFAU [...]
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Reference Condition="'$(TargetFramework)' == ''" Include="FSharp.Core" />
+    <Reference Condition="'$(TargetFramework)' == 'Silverlight' AND '$(SilverlightVersion)' == 'v4.0'" Include="System.Core" />
+    <Reference Condition="'$(TargetFramework)' == 'Silverlight'" Include="$(MSBuildExtensionsPath32)\..\Microsoft F#\Silverlight\Libraries\Client\$(SilverlightVersion)\FSharp.Core.dll"/>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/src/FsHtmlDoc/FsHtmlDoc.fs b/src/FsHtmlDoc/FsHtmlDoc.fs
new file mode 100755
index 0000000..9f3fe4b
--- /dev/null
+++ b/src/FsHtmlDoc/FsHtmlDoc.fs
@@ -0,0 +1,1291 @@
+
+// TODO: print nice type variable names for inferred type variables
+
+// Post beta2:
+
+// TODO: layout events
+// TODO: accessibility
+// TODO: full member constraints 
+// TODO: isOverGenerics
+// TODO: layout base type in some way
+
+#nowarn "62"
+
+open System
+open System.IO
+open System.Collections.Generic
+open System.Collections.ObjectModel
+open System.Xml
+open Microsoft.FSharp.Metadata
+open Microsoft.FSharp.Text.StructuredFormat
+open Microsoft.FSharp.Text.StructuredFormat.LayoutOps
+open Microsoft.FSharp.Text.StructuredFormat.Display
+
+let showObsoleteMembers = false
+let shortConstraints = true
+let showConstraintTyparAnnotations = false
+
+module String = 
+    let uncapitalize (s:string) =
+        if s.Length = 0 then  ""
+        else s.[0..0].ToLowerInvariant() + s.[1..s.Length-1]
+
+module ListSet =
+    let rec contains f x l = 
+        match l with 
+        | [] -> false
+        | x'::t -> f x x' || contains f x t
+
+    let insert f x l = if contains f x l then l else x::l
+    let setify f l = List.foldBack (insert f) (List.rev l) [] |> List.rev
+
+module LibUtilities =
+
+
+    let orderOn p pxOrder x xx = pxOrder (p x) (p xx)
+
+    let tryDropSuffix (s:string) (t:string) = 
+        if s.EndsWith(t) then
+            Some s.[0..s.Length - t.Length - 1]
+        else
+            None
+
+    let dropSuffix s t = 
+        match tryDropSuffix s t with 
+        | Some(res) -> res 
+        | None -> failwith "dropSuffix"
+
+    // Concatenate for HTML links
+    let hrefConcat a b = a+"/"+b
+
+    let rec split (c:char) (str:string) =
+        let i = str.IndexOf c
+        if i <> -1 then 
+            str.[0..i-1] :: split c str.[i+1 .. str.Length-1]
+        else
+            [str]
+
+    let isAllLower (s:string) = (s.ToLowerInvariant() = s)    
+
+    let underscoreLowercase s =
+      if isAllLower s then "_"+s else s
+
+    let allButLast (xs: list<_>) = 
+        if xs.IsEmpty then failwith "allButLast"
+        List.rev (List.tail (List.rev xs)) //  xs.[0..xs.Length-2]
+
+    let last (xs: list<_>) = 
+        if xs.IsEmpty then failwith "last"
+        xs.[xs.Length-1]
+
+module LayoutUtilities =
+    type Renderer<'T,'State> =
+        (* exists 'State.
+           -- could use object type to get "exists 'State" on private state,
+        *)
+        abstract Start    : unit -> 'State;
+        abstract AddText  : 'State -> string -> 'State;
+        abstract AddBreak : 'State -> int -> 'State;
+        abstract AddTag   : 'State -> string * (string * string) list * bool -> 'State;
+        abstract Finish   : 'State -> 'T
+          
+    let renderL (rr: Renderer<_,_>) layout =
+        let rec addL z pos i = function
+            (* pos is tab level *)
+          | Leaf (jl,text,jr)                 -> 
+              rr.AddText z (unbox text),i + (unbox<string> text).Length
+          | Node (jl,l,jm,r,jr,Broken indent) -> 
+              let z,i = addL z pos i l 
+              let z,i = rr.AddBreak z (pos+indent),(pos+indent) 
+              let z,i = addL z (pos+indent) i r 
+              z,i
+          | Node (jl,l,jm,r,jr,_)             -> 
+              let z,i = addL z pos i l 
+              let z,i = if jm then z,i else rr.AddText z " ",i+1 
+              let pos = i 
+              let z,i = addL z pos i r 
+              z,i
+          | Attr (tag,attrs,l)                -> 
+              let z   = rr.AddTag z (tag,attrs,true) 
+              let z,i = addL z pos i l 
+              let z   = rr.AddTag z (tag,attrs,false) 
+              z,i
+        let pos = 0 
+        let z,i = rr.Start(),0 
+        let z,i = addL z pos i layout 
+        rr.Finish z
+
+    let spaces n = String.replicate n " "
+
+    /// string render 
+    let stringR =
+      { new Renderer<string,string list> with 
+          member x.Start () = []
+          member x.AddText rstrs text = text::rstrs
+          member x.AddBreak rstrs n = (spaces n) :: "\n" ::  rstrs 
+          member x.AddTag z (_,_,_) = z
+          member x.Finish rstrs = String.Join("",Array.ofList (List.rev rstrs)) }
+
+    /// html render - wraps HTML encoding (REVIEW) and hyperlinks
+    let htmlR (baseR : Renderer<'Res,'State>) =
+      { new Renderer<'Res,'State> with 
+          member r.Start () = baseR.Start()
+          member r.AddText z s = baseR.AddText z s;  (* REVIEW: escape HTML chars *)
+          member r.AddBreak z n = baseR.AddBreak z n
+          member r.AddTag z (tag,attrs,start) =
+             match tag,attrs with 
+             | "html:a",[("href",link)] ->
+                if start
+                then baseR.AddText z (sprintf "<a href='%s'>" link)
+                else baseR.AddText z (sprintf "</a>")
+             | _ -> z
+          member r.Finish z = baseR.Finish z }
+
+
+
+module FSharpMetadataUtilities =
+
+    open LibUtilities
+
+    let isAttrib<'T> (attrib: FSharpAttribute)  =
+        attrib.ReflectionType = typeof<'T> 
+
+    let tryFindAttrib<'T> (attribs: ReadOnlyCollection<FSharpAttribute>)  =
+        attribs |> Seq.tryPick (fun a -> if isAttrib<'T>(a) then Some (a.Value :?> 'T) else None)
+
+    let hasAttrib<'T> (attribs: ReadOnlyCollection<FSharpAttribute>)  = tryFindAttrib<'T>(attribs).IsSome
+
+    let getDocFromSig (xmlDocSig : string) (xmlDocMemberMap : Map<string,string>) =
+        match xmlDocMemberMap.TryFind(xmlDocSig) with
+        | Some(docstring) -> docstring.Replace("<c>","<tt>").Replace("</c>","</tt>")
+        | None -> ""
+    
+
+    let indexedConstraints (tps : seq<FSharpGenericParameter>) = 
+        tps |> Seq.map (fun gp -> (gp, (gp.Constraints |> Seq.toList))) |> Seq.toList
+
+
+[<NoEquality; NoComparison>]
+type DisplayEnv = 
+  { thisAssembly : FSharpAssembly;
+    html: bool;
+    htmlHideRedundantKeywords: bool;
+    htmlAssemMap: Map<string,string>; // where can the docs for f# assemblies be found? 
+    showObsoleteMembers: bool; 
+    showTyparBinding: bool; 
+    suppressInlineKeyword: bool;
+    showMemberContainers:bool;
+    shortConstraints:bool;
+    showAttributes:bool;
+    showOverrides:bool;
+    showConstraintTyparAnnotations: bool;
+    abbreviateAdditionalConstraints: bool;
+    showTyparDefaultConstraints : bool;
+    contextAccessibility: FSharpAccessibility }
+
+module FSharpMetadataPrintUtilities = 
+
+    open LibUtilities
+    open LayoutUtilities
+    open FSharpMetadataUtilities
+
+    let dummy = 1
+
+    
+    let bracketIfL x lyt = if x then bracketL lyt else lyt
+    let squareAngleL denv x = 
+        if denv.html then 
+            leftL "[<" ^^ x ^^ rightL ">]"
+        else
+            leftL "[<" ^^ x ^^ rightL ">]"
+        
+    let angleL denv x = 
+        if denv.html then 
+            sepL "<" ^^ x ^^ rightL ">"  
+        else
+            sepL "<" ^^ x ^^ rightL ">"  
+
+    let squareAngleSepListAboveL denv xs body = squareAngleL denv (sepListL (rightL ";") xs) @@ body 
+    let linkL str ly = tagAttrL "html:a" [("href",str)] ly
+    let hlinkL (url:string) l = linkL url l
+    //let tagAttrL str attrs ly = Attr (str,attrs,ly)
+
+    let layoutAccessibility (denv:DisplayEnv) accessibility itemL =   
+        itemL
+
+#if TODO
+ // accessibility 
+        let isInternalCompPath x = 
+            match x with 
+            | CompPath(ScopeRef_local,[]) -> true 
+            | _ -> false
+        let (|Public|Internal|Private|) (TAccess p) = 
+            match p with 
+            | [] -> Public 
+            | _ when List.forall isInternalCompPath p  -> Internal 
+            | _ -> Private
+        match denv.contextAccessibility,accessibility with
+        | Public,Internal  -> wordL "internal" ++ itemL    // print modifier, since more specific than context
+        | Public,Private   -> wordL "private" ++ itemL     // print modifier, since more specific than context
+        | Internal,Private -> wordL "private" ++ itemL     // print modifier, since more specific than context
+        | _ -> itemL
+#endif
+
+
+
+        
+    let trimPathByDisplayEnv (denv:DisplayEnv) p = p
+    
+    /// Layout a reference to a type or value, perhaps emitting a HTML hyperlink 
+    let layoutTyconRef denv (tcref:FSharpEntity) = 
+      let path = tcref.Namespace
+      let basicText = tcref.DisplayName
+      let shortNameL = wordL basicText
+      let longNameL = 
+          let pathText = trimPathByDisplayEnv denv path
+          (if pathText = "" then shortNameL else leftL (pathText+".") ^^ shortNameL)        
+      try
+        
+        if tcref.IsExternal then
+            if denv.html then 
+                try 
+                    if tcref.ReflectionType.Assembly.GetName().GetPublicKeyToken().[0..4] = [| 0xB7uy; 0x7Auy; 0x5Cuy; 0x56uy; 0x19uy |] then
+                        // cross link to the MSDN 2.0 documentation.  
+                        // Generic types don't seem to have stable names, so just shell out to a search engine
+                        if tcref.GenericParameters.Count = 0 then 
+                            hlinkL (sprintf "http://msdn2.microsoft.com/en-us/library/%s.aspx" tcref.ReflectionType.FullName) shortNameL
+                        else 
+                            hlinkL (sprintf "http://www.bing.com/search?q=%s" tcref.ReflectionType.FullName) shortNameL
+                    else
+                        longNameL
+                with _ -> 
+                    longNameL
+            else
+                longNameL
+        else 
+            let arity = tcref.GenericParameters.Count
+            let aritySuffix = if arity=0 then "" else "-" + string arity
+            let kindPrefix = if tcref.IsModule then "" else "type_"
+            if denv.html then 
+                let nm = path + "." + kindPrefix + underscoreLowercase basicText + aritySuffix
+                let assemName = tcref.ReflectionAssembly.GetName().Name
+                match denv.htmlAssemMap.TryFind  assemName with 
+                | Some root -> 
+                    hlinkL (sprintf "%s/%s.html" root nm) shortNameL
+                // otherwise assume it is installed parallel to this tree 
+                | None -> 
+                    if assemName = denv.thisAssembly.ReflectionAssembly.GetName().Name then 
+                        hlinkL (sprintf "%s.html" nm)  shortNameL
+                    else
+                        hlinkL (sprintf "../%s/%s.html" assemName nm) shortNameL
+            else
+                longNameL
+      with e -> 
+          eprintfn "failed to reference to type '%s' -  '%s" basicText e.Message
+          if System.Diagnostics.Debugger.IsAttached then 
+               System.Diagnostics.Debugger.Break()
+          longNameL
+
+    let layoutAttribute denv (attrib:FSharpAttribute) = 
+        wordL "(attribute)"
+
+
+    /// Layout '[<attribs>]' above another block 
+    let layoutAttribs denv (attrs: ReadOnlyCollection<FSharpAttribute>) restL = 
+        let attrs = List.ofSeq attrs
+        if denv.showAttributes then
+            (* Don't display DllImport attributes in generated signatures and/or html *)
+            let attrs = if denv.html then attrs |> List.filter (isAttrib<ClassAttribute> >> not) else attrs
+            let attrs = if denv.html then attrs |> List.filter (isAttrib<StructAttribute> >> not) else attrs
+            let attrs = if denv.html then attrs |> List.filter (isAttrib<InterfaceAttribute> >> not) else attrs
+            let attrs = attrs |> List.filter (isAttrib<System.Runtime.InteropServices.DllImportAttribute> >> not)
+            let attrs = attrs |> List.filter (isAttrib<CompiledNameAttribute> >> not)
+            let attrs = attrs |> List.filter (isAttrib<ContextStaticAttribute> >> not)
+            let attrs = attrs |> List.filter (isAttrib<ThreadStaticAttribute> >> not)
+            let attrs = attrs |> List.filter (isAttrib<CompilerMessageAttribute> >> not)
+            let attrs = attrs |> List.filter (isAttrib<EntryPointAttribute> >> not)
+            let attrs = attrs |> List.filter (isAttrib<RequiresExplicitTypeArgumentsAttribute> >> not)
+            let attrs = attrs |> List.filter (isAttrib<System.Runtime.InteropServices.MarshalAsAttribute> >> not)
+            let attrs = attrs |> List.filter (isAttrib<ReflectedDefinitionAttribute> >> not)
+            let attrs = attrs |> List.filter (isAttrib<System.Runtime.InteropServices.StructLayoutAttribute> >> not)
+            let attrs = attrs |> List.filter (isAttrib<AutoSerializableAttribute> >> not)
+            match attrs.Length with
+            | 0 -> restL 
+            | _ -> restL
+        else
+            restL
+
+    let rec layoutTyparAttribs denv (typar:FSharpGenericParameter) restL =         
+        let attrs = typar.Attributes |> List.ofSeq
+        match attrs.Length, typar.IsMeasure with
+        | 0, false -> restL 
+        | _  -> squareAngleSepListAboveL denv ((if typar.IsMeasure then [wordL "Measure"] else []) @ List.map (layoutAttribute denv) attrs) restL
+
+    and layoutTyparRef denv env (typar:FSharpGenericParameter) =
+          wordL (sprintf "%s%s"
+                   (if denv.showConstraintTyparAnnotations && typar.IsSolveAtCompileTime then "^" else "'")
+                   typar.Name)
+
+    and layoutTyparAux denv env (typar:FSharpGenericParameter) =
+        let varL = layoutTyparRef denv env typar
+        //let varL = layoutTyparAttribs denv typar varL
+        varL
+
+      
+    /// Layout type parameter constraints, taking TypeSimplificationInfo into account  
+    and layoutConstraints denv env (cxs: list<_ * list<FSharpGenericParameterConstraint>>) = 
+
+        
+        // Internally member constraints get attached to each type variable in their support. 
+        // This means we get too many constraints being printed. 
+        // So we normalize the constraints to eliminate duplicate member constraints 
+
+        let cxs = 
+           [ for (tp, tpcs) in cxs  do
+               for tpc in tpcs do
+                   yield (tp,tpc) ]
+
+        // Merge trait constraints referring to the same member (when using short constraints)
+        let cxs = 
+            cxs  
+            |> ListSet.setify (fun (tp1,cx1) (tp2,cx2) ->
+                     (cx1.IsMemberConstraint && 
+                      cx2.IsMemberConstraint && 
+                      denv.shortConstraints && 
+                      cx1.MemberName = cx2.MemberName))
+                     
+        let cxsL = 
+           [ for (tp, tpc) in cxs  do
+                yield! layoutConstraint denv env (tp,tpc) ]
+
+        match cxsL with 
+        | [] -> None
+        | _ -> 
+            if denv.abbreviateAdditionalConstraints then 
+                Some (wordL "when <constraints>")
+            elif denv.shortConstraints then 
+                Some (leftL "(" ^^ wordL "requires" ^^ sepListL (wordL "and") cxsL ^^ rightL ")")
+            else
+                Some (wordL "when" ^^ sepListL (wordL "and") cxsL)
+
+    and layoutConstraintsAfter denv env coreL cxs = 
+        match layoutConstraints denv env cxs with 
+        | None -> coreL
+        | Some cxsL -> coreL --- cxsL
+
+    /// Layout constraints, taking TypeSimplificationInfo into account  
+    and layoutConstraint denv env (tp,tpc: FSharpGenericParameterConstraint) =
+        if tpc.IsCoercesToConstraint then 
+            [layoutTyparAux denv env tp ^^ wordL ":>" --- layoutTypeAux denv env tpc.CoercesToTarget ]
+
+        elif tpc.IsMemberConstraint then 
+            if denv.shortConstraints then 
+               [ layoutTyparAux denv env tp ^^ wordL "has" ^^ wordL tpc.MemberName ]
+            else
+               // TODO: full member constraints 
+               [ layoutTyparAux denv env tp ^^ wordL "has" ^^ wordL tpc.MemberName ]
+
+        elif tpc.IsDefaultsToConstraint then 
+           if denv.showTyparDefaultConstraints then 
+               [wordL "default" ^^ layoutTyparAux denv env tp ^^ wordL " :" ^^ layoutTypeAux denv env tpc.DefaultsToTarget]
+           else 
+               []
+
+        elif tpc.IsEnumConstraint then 
+            if denv.shortConstraints then 
+               [wordL "enum"]
+            else
+               [layoutTyparAux denv env tp ^^ wordL ":" ^^ layoutTypeApplication denv env (wordL "enum") 2 true [tpc.EnumConstraintTarget ]]
+
+        elif tpc.IsDelegateConstraint then 
+            if denv.shortConstraints then 
+               [wordL "delegate"]
+            else
+               [layoutTyparAux denv env tp ^^ wordL ":" ^^ layoutTypeApplication denv env (wordL "delegate") 2 true [tpc.DelegateTupledArgumentType ; tpc.DelegateReturnType]]
+
+        elif tpc.IsSupportsNullConstraint then 
+           [layoutTyparAux denv env tp ^^ wordL ":" ^^ wordL "null" ]
+
+        elif tpc.IsComparisonConstraint then 
+           [layoutTyparAux denv env tp ^^ wordL ":" ^^ wordL "comparison" ]
+
+        elif tpc.IsEqualityConstraint then 
+           [layoutTyparAux denv env tp ^^ wordL ":" ^^ wordL "equality" ]
+
+        elif tpc.IsNonNullableValueTypeConstraint then 
+            if denv.shortConstraints then 
+               [wordL "value type"]
+            else
+               [layoutTyparAux denv env tp ^^ wordL ":" ^^ wordL "struct" ]
+
+        elif tpc.IsReferenceTypeConstraint then 
+            if denv.shortConstraints then 
+               [wordL "reference type"]
+            else
+               [layoutTyparAux denv env tp ^^ wordL ":" ^^ wordL "not struct" ]
+
+        elif tpc.IsSimpleChoiceConstraint then 
+           [layoutTyparAux denv env tp ^^ wordL ":" ^^ bracketL (sepListL (sepL "|") (List.map (layoutTypeAux denv env) (Seq.toList tpc.SimpleChoices))) ]
+
+        elif tpc.IsRequiresDefaultConstructorConstraint then 
+            if denv.shortConstraints then 
+               [wordL "default constructor"]
+            else
+               [layoutTyparAux denv env tp ^^ wordL ":" ^^ bracketL (wordL "new : unit -> " ^^ (layoutTyparAux denv env tp))]
+        else 
+            [wordL "unknown"]
+
+    /// Layout type arguments, either NAME<ty,...,ty> or (ty,...,ty) NAME 
+    and layoutTypeApplication denv env tcL prec prefix args =
+        if prefix then 
+            match args with
+            | [] -> tcL
+            | [arg] -> tcL ^^ angleL denv (layoutTypeWithPrec denv env 4 arg)
+            | args -> bracketIfL (prec <= 1) (tcL ^^ angleL denv (layoutTypesWithPrec denv env 2 (sepL ",") args))
+        else
+            match args with
+            | [] -> tcL
+            | [arg] -> layoutTypeWithPrec denv env 2 arg ^^ tcL 
+            | args -> bracketIfL (prec <= 1) (bracketL (layoutTypesWithPrec denv env 2 (sepL ",") args) ^^ tcL)
+
+    and (|MeasureProd|_|) (typ : FSharpType) = 
+        if typ.IsNamed && typ.NamedEntity.LogicalName = "*" && typ.GenericArguments.Count = 2 then Some (typ.GenericArguments.[0], typ.GenericArguments.[1])
+        else None
+
+    and (|MeasureInv|_|) (typ : FSharpType) = 
+        if typ.IsNamed && typ.NamedEntity.LogicalName = "/" && typ.GenericArguments.Count = 1 then Some typ.GenericArguments.[0]
+        else None
+
+    and (|MeasureOne|_|) (typ : FSharpType) = 
+        if typ.IsNamed && typ.NamedEntity.LogicalName = "1" && typ.GenericArguments.Count = 0 then  Some ()
+        else None
+
+    /// Layout a type, taking precedence into account to insert brackets where needed 
+    and layoutTypeWithPrec denv env prec (typ:FSharpType) =
+
+        // Measure types are stored as named types with 'fake' constructors for products, "1" and inverses
+        // of measures in a normalized form (see Andrew Kennedy technical reports). Here we detect this 
+        // embedding and use an approximate set of rules for layout out normalized measures in a nice way. 
+        
+        match typ with 
+        | MeasureProd (ty,MeasureOne) 
+        | MeasureProd (MeasureOne, ty) -> layoutTypeWithPrec denv env prec ty
+        | MeasureProd (ty1, MeasureInv ty2) 
+        | MeasureProd (ty1, MeasureProd (MeasureInv ty2, MeasureOne)) -> layoutTypeWithPrec denv env 2 ty1 ^^ wordL "/" ^^ layoutTypeWithPrec denv env 2 ty2
+        | MeasureProd (ty1,MeasureProd(ty2,MeasureOne)) 
+        | MeasureProd (ty1,ty2) -> layoutTypeWithPrec denv env 2 ty1 ^^ wordL "*" ^^ layoutTypeWithPrec denv env 2 ty2
+        | MeasureInv ty -> wordL "/" ^^ layoutTypeWithPrec denv env 1 ty
+        | MeasureOne  -> wordL "1" 
+        | _ -> 
+        if typ.IsNamed then 
+            let tcref = typ.NamedEntity 
+            let tyargs = typ.GenericArguments |> Seq.toList
+            // layout postfix array types
+            layoutTypeApplication denv env (layoutTyconRef denv tcref) prec tcref.UsesPrefixDisplay tyargs 
+            
+        elif typ.IsTuple then 
+            let tyargs = typ.GenericArguments |> Seq.toList
+            bracketIfL (prec <= 2) (layoutTypesWithPrec denv env 2 (wordL "*") tyargs)
+
+        elif typ.IsFunction then 
+            let rec loop soFarL (typ:FSharpType) = 
+              if typ.IsFunction then 
+                  let domainTyp,retType = typ.GenericArguments.[0], typ.GenericArguments.[1]
+                  loop (soFarL --- (layoutTypeWithPrec denv env 4 typ.GenericArguments.[0] ^^ wordL "->")) retType
+              else 
+                  soFarL --- layoutTypeWithPrec denv env 5 typ
+            bracketIfL (prec <= 4) (loop emptyL typ)
+
+        elif typ.IsGenericParameter then 
+            layoutTyparAux denv env typ.GenericParameter
+
+        else 
+            wordL "(type)" 
+            //typ.IsMeasure then 
+            // | TType_measure unt -> layoutMeasureAux denv env 4 unt
+
+    /// Layout a list of types, separated with the given separator, either '*' or ',' 
+    and layoutTypesWithPrec denv env prec sep typl = 
+        sepListL sep (List.map (layoutTypeWithPrec denv env prec) typl)
+
+    /// Layout a single type
+    and layoutTypeAux denv env typ = 
+        layoutTypeWithPrec denv env 5 typ
+
+    and layoutType denv typ  = 
+        layoutTypeAux denv () typ
+
+
+    
+    /// Layout type parameters
+    let layoutTyparDeclsAfter denv includeConstraints nmL (typars : seq<FSharpGenericParameter>) =
+        let tpcs = if includeConstraints then indexedConstraints typars else []
+        let typars = typars |> List.ofSeq 
+        
+        match typars with 
+        | []  -> 
+            nmL
+        | _ -> 
+            let coreL = sepListL (sepL ",") (List.map (layoutTyparAux denv ()) typars)
+            let coreL = layoutConstraintsAfter denv () coreL tpcs
+            nmL ^^ angleL denv coreL 
+
+
+    let layoutMemberOrVal denv (v:FSharpMemberOrVal) = 
+        let isCtor = (v.LogicalName = ".ctor")
+        let isItemIndexer = (v.IsInstanceMember && v.DisplayName = "Item")
+
+        let nameL = 
+            let tyname = v.LogicalEnclosingEntity.DisplayName
+            if isCtor then 
+                wordL ("new " + tyname)
+            elif v.IsInstanceMember  then 
+                if isItemIndexer then 
+                    wordL (String.uncapitalize tyname + ".[") 
+                else
+                    wordL (String.uncapitalize tyname + "." + v.DisplayName) 
+                
+            elif not v.IsMember && 
+                 not (hasAttrib<RequireQualifiedAccessAttribute> v.LogicalEnclosingEntity.Attributes) && 
+                 // Beta2 workaround: in FSharp.Core, option was not marked with RequireQualifiedAccess in beta2
+                 (let compilingFslib = (denv.thisAssembly.ReflectionAssembly.GetName().Name = "FSharp.Core")
+                  not (compilingFslib && v.LogicalEnclosingEntity.DisplayName = "Option")) then 
+                // In FSharp.Core.dll filter out the attributes
+                wordL v.DisplayName
+            else 
+                wordL (tyname + "." + v.DisplayName)
+
+        //let nameL = if denv.htmlHideRedundantKeywords || v.IsInstanceMember || isCtor || not v.IsMember then kwL else wordL "static" ++ kwL
+        //let nameL = if v.IsMutable then wordL "mutable" ++ nameL else nameL
+        let nameL = layoutAccessibility denv v.Accessibility nameL
+        let nameL = if denv.htmlHideRedundantKeywords || not  v.IsDispatchSlot then nameL else wordL "abstract" ++ nameL
+        let nameL = 
+            if not denv.html && v.InlineAnnotation = FSharpInlineAnnotation.AlwaysInline && not denv.suppressInlineKeyword then 
+                wordL "inline" ++ nameL 
+            else 
+                nameL
+
+        (* Drop the names from value arguments when printing them *)
+        let argInfos = v.CurriedParameterGroups |> Seq.map Seq.toList |> Seq.toList 
+        let retType = v.ReturnParameter.Type
+        let argInfos, retType = 
+            if v.IsGetterMethod then 
+                match argInfos with 
+                | [[]] -> [], Some retType
+                | _ -> argInfos, Some retType
+            elif v.IsSetterMethod then 
+                match argInfos with 
+                | [ args ] -> [ allButLast args ], Some (last args).Type
+                | _ -> argInfos, None
+            else 
+                argInfos,Some retType
+
+        let isOverGeneric = false 
+#if TODO
+        // TODO: 
+        // let isOverGeneric = List.length (Zset.elements (free_in_type CollectTyparsNoCaching tau).FreeTypars) < List.length tps (* Bug: 1143 *)
+#endif
+        
+        // Extension members can have apparent parents whcih are not F# types.
+        // Hence getting the generic argument count if this is a little trickier
+        let numGenericParamsOfApparentParent = 
+            let pty = v.LogicalEnclosingEntity 
+            if pty.IsExternal then 
+                let ty = v.LogicalEnclosingEntity.ReflectionType 
+                if ty.IsGenericType then ty.GetGenericArguments().Length 
+                else 0 
+            else 
+                pty.GenericParameters.Count
+
+        let tps = v.GenericParameters |> Seq.skip numGenericParamsOfApparentParent
+
+        let usageL = 
+            if v.IsTypeFunction || isOverGeneric || denv.showTyparBinding then 
+                layoutTyparDeclsAfter denv false nameL tps
+            else 
+                nameL
+
+        let cxs  = indexedConstraints v.GenericParameters 
+
+        // Parenthesize the return type to match the topValInfo 
+        let retTypeL  = 
+            match retType with 
+            | None -> wordL "unit"
+            | Some ty -> layoutTypeWithPrec denv () 4 ty
+        let retTypeL = wordL ":" --- retTypeL
+
+        // Format each argument, including its name and type 
+        let layoutArgUsage doc i (arg: FSharpParameter) = 
+           
+            // Detect an optional argument 
+            let isOptionalArg = hasAttrib<OptionalArgumentAttribute> arg.Attributes
+            let nm = match arg.Name with null -> "arg" + string i | nm -> nm
+            let argName = if isOptionalArg then "?" + nm else nm
+            if doc then leftL argName ^^ rightL ":" ^^ layoutTypeWithPrec denv () 2 arg.Type
+            else wordL argName
+
+        let usageL = 
+            match argInfos with
+            | [] -> 
+                usageL ++ retTypeL 
+            | _  -> 
+
+               let argNumber = ref 0 
+               let allArgsUsageL = 
+                   argInfos 
+                   |> List.map (fun xs  -> xs |> List.map (fun x -> incr argNumber; layoutArgUsage false !argNumber x))
+                   |> List.map (function [] -> wordL "()" 
+                                       | [arg] when not v.IsMember || isItemIndexer -> arg 
+                                       | args when isItemIndexer -> sepListL (sepL ", ") args
+                                       | args -> bracketL (sepListL (sepL ", ") args))
+
+               let usageL = List.fold (---) usageL allArgsUsageL 
+               let usageL = 
+                   if isItemIndexer then usageL ++ wordL "]" 
+                   else usageL
+               usageL
+
+
+        let docL = 
+            let afterDocs = 
+                [ let argCount = ref 0 
+                  for xs in argInfos do 
+                    for x in xs do 
+                       incr argCount
+                       yield layoutArgUsage true !argCount x
+
+                  if not v.IsGetterMethod && not v.IsSetterMethod && retType.IsSome then 
+                      yield wordL "returns" ++ retTypeL
+                  match layoutConstraints denv () cxs with 
+                  | None ->  ()
+                  | Some cxsL -> yield cxsL ]
+            match afterDocs with
+            | [] -> emptyL
+            | _ -> (List.reduce (@@) [ yield wordL ""; yield! afterDocs ])
+
+        let noteL = 
+            let noteDocs = 
+                [ if cxs |> List.exists (snd >> List.exists (fun cx -> cx.IsMemberConstraint)) then
+                     yield (wordL "Note: this operator is overloaded")  ]
+            match noteDocs with
+            | [] -> emptyL
+            | _ -> (List.reduce (@@) [ yield wordL ""; yield! noteDocs ])
+                
+        let usageL = if v.IsSetterMethod then usageL --- wordL "<- v" else usageL
+        
+        //layoutAttribs denv v.Attributes 
+        usageL  , docL, noteL
+    
+
+    /// Layout type definition "Type Description" section (doesn't include constructors and members)
+    let layoutTypeDefn denv (tycon:FSharpEntity) =
+        let typeWordL = 
+            (if tycon.IsMeasure then wordL "[<Measure>] type" else wordL "type") 
+        let lhsL =
+            let tps = tycon.GenericParameters
+            
+            let tpsL = layoutTyparDeclsAfter denv false (wordL tycon.DisplayName) tycon.GenericParameters
+            typeWordL ^^ tpsL
+        let adhoc = 
+            tycon.MembersOrValues
+            |> Seq.toList 
+            |> List.sortBy (fun m -> m.DisplayName, (m.CurriedParameterGroups |> Seq.map Seq.length |> Seq.toList))
+#if TODO
+            |> List.filter (fun v -> 
+                                match v.MemberInfo.Value.ImplementedSlotSigs with 
+                                | TSlotSig(_,oty,_,_,_,_) :: _ -> 
+                                    // Don't print overrides in HTML docs
+                                    denv.showOverrides && 
+                                    // Don't print individual methods forming interface implementations - these are currently never exported 
+                                    not (is_interface_typ denv.g oty)
+                                | [] -> true)
+#endif
+            |> List.filter (fun v -> denv.showObsoleteMembers || 
+                                     tycon.Attributes |> Seq.exists (fun attrib -> attrib.ReflectionType = typeof<System.ObsoleteAttribute>))
+
+        if tycon.IsRecord then 
+           (lhsL ^^ wordL "=") --- 
+           (tycon.RecordFields 
+               |> Seq.toList
+               |> List.map (fun fld -> 
+                      let lhs = wordL fld.Name 
+                      let lhs = if fld.IsMutable then wordL "mutable" --- lhs else lhs
+                      (lhs ^^ rightL ":") --- layoutType denv fld.Type)
+               |> aboveListL |> braceL)
+#if TODO
+                let addReprAccessL l = accessibilityL denv tycon.TypeReprAccessibility l 
+                let denv = denv_scope_access tycon.TypeReprAccessibility denv  
+#endif
+         elif tycon.IsAbbreviation then 
+             (lhsL ^^ wordL "=") --- (layoutType denv tycon.AbbreviatedType)
+
+         //elif tycon.IsDelegate then    
+         //    let rty = GetFSharpViewOfReturnType denv.g rty
+         //    (lhsL ^^ wordL "=") --- wordL "delegate of" --- topTypeL denv SimplifyTypes.typeSimplificationInfo0 (paraml |> List.mapSquared (fun sp -> (sp.Type, TopValInfo.unnamedTopArg1))) rty [])
+         elif tycon.IsUnion then    
+              (tycon.UnionCases 
+                 |> Seq.toList
+                 |> List.map (fun ucase ->
+                      let nmL = wordL ucase.Name
+                      match ucase.Fields |> Seq.toList |> List.map (fun rfld -> rfld.Type) with
+                      | []     -> wordL "|" ^^ nmL
+                      | argtys -> (wordL "|" ^^ nmL ^^ wordL "of") --- 
+                                  sepListL (wordL "*") (List.map (layoutType denv) argtys))
+
+                 |> aboveListL)
+
+         elif (not tycon.IsAbbreviation && not tycon.HasAssemblyCodeRepresentation && tycon.ReflectionType.IsEnum) then    
+              (lhsL ^^ wordL "=") --- 
+              (tycon.ReflectionType.GetFields(System.Reflection.BindingFlags.Public ||| System.Reflection.BindingFlags.NonPublic ||| System.Reflection.BindingFlags.Static)
+               |> Seq.toList
+               |> List.filter (fun f -> f.IsLiteral)
+               |> List.map (fun f -> wordL "| " ^^ wordL f.Name  ^^ wordL " = " ^^ wordL (sprintf "%A" (f.GetRawConstantValue())) )
+               |> aboveListL)
+         else lhsL 
+
+    let layoutExceptionDefn denv (exnc:FSharpEntity) =
+        let exnL = wordL "exception" ^^ layoutAccessibility denv exnc.Accessibility (wordL exnc.DisplayName) 
+        if exnc.IsAbbreviation then 
+            exnL ^^ wordL "=" --- layoutType denv exnc.AbbreviatedType
+        else
+            match exnc.RecordFields |> Seq.toList |> List.map (fun rfld -> rfld.Type) with
+             | []     -> exnL 
+             | argtys -> exnL ^^ wordL "of" --- sepListL (wordL "*") (List.map (layoutType denv) argtys)
+
+
+
+
+module HtmlDocWriter =
+    open LayoutUtilities
+    open LibUtilities
+    open FSharpMetadataUtilities
+    open FSharpMetadataPrintUtilities
+    
+    // bug://1813. 
+    // The generated HTML docs contain these embedded URLs.
+    let urlForFSharp                = "http://www.fsharp.net"
+    // These manual links should be links to reference copies of the library documentation directory (without the /-slash)
+    let urlForFSharpCoreManual      = "http://research.microsoft.com/fsharp/manual/FSharp.Core" (* appended with "/Microsoft.FSharp.Collections.List.html" etc... *)
+    let urlForFSharpPowerPackManual = "http://research.microsoft.com/fsharp/manual/FSharp.PowerPack" (* appended with "/Microsoft.FSharp.Collections.List.html" etc... *)
+
+    let pseudoCaseInsensitive (a:string) (b:string) = 
+        let c1 = compare (a.ToLowerInvariant()) (b.ToLowerInvariant())
+        if c1 <> 0 then c1 else 
+        compare a b
+
+    let widthVal  = 80
+    let widthType = 80
+    let widthException  = 80
+
+
+    /// String for layout squashed to a given width.
+    /// HTML translation and markup for TYPE and VAL syntax.
+    /// Assumes in <pre> context (since no explicit <br> linebreaks).
+    let outputL width layout =
+        let baseR = htmlR stringR
+        let render = 
+            { new Renderer<_,_> with 
+                 member r.Start () = baseR.Start()
+                 member r.AddText z s = baseR.AddText z s;  (* REVIEW: escape HTML chars *)
+                 member r.AddBreak z n = baseR.AddBreak z n
+                 member r.Finish z = baseR.Finish z 
+                 member x.AddTag z (tag,attrs,start) =
+                          match tag,start with
+                          | "TYPE",_     -> z
+                          | "VAL" ,true  -> baseR.AddText z "<B>"
+                          | "VAL" ,false -> baseR.AddText z "</B>"
+                          | _     ,start -> baseR.AddTag z (tag,attrs,start)}
+        renderL render (Display.squash_layout { FormatOptions.Default with PrintWidth=width } layout)
+
+    type kind = PathK | TypeK of int (* int is typar arity *)
+
+    let WriteHTMLDoc (assem: Microsoft.FSharp.Metadata.FSharpAssembly, outputDir, append, cssFile, namespaceFile, htmlDocLocalLinks, xmlFile : string) =
+        let assemblyName = assem.ReflectionAssembly.GetName().Name
+        let namespaceFileFullPath = Path.Combine(outputDir,namespaceFile)
+        /// The name to use to link up to the namespace file 
+        let namespaceFileUpOne = (hrefConcat ".." namespaceFile)
+        let wrap (oc:TextWriter) (a:string) (b:string) f = 
+            oc.WriteLine a;
+            f ();
+            oc.WriteLine b
+
+        // Read in the supplied XML file, map its name attributes to document text 
+        let settings = XmlReaderSettings()   
+        let reader = XmlReader.Create(xmlFile,settings)
+        let doc = XmlDocument()
+        doc.Load(reader)
+        let elemList = doc.GetElementsByTagName("member")
+        let xmlMemberMap = [for e in elemList do yield (e.Attributes.[0].Value,e.InnerXml)]  |> Map.ofList
+
+        let newExplicitFile append fullname bfilename title cssFile f = 
+            use oc = 
+                if append && File.Exists fullname then 
+                    System.IO.File.AppendText fullname
+                else 
+                    System.IO.File.CreateText fullname
+
+            fprintfn oc "<HTML><HEAD><TITLE>%s</TITLE><link rel=\"stylesheet\" type=\"text/css\"href=\"%s\"></link></HEAD><BODY>" title cssFile;
+            let backlink = (bfilename,title)
+            f backlink oc;
+            let ver = assem.ReflectionAssembly.GetName().Version.ToString()
+            fprintfn oc "<br /> <br/><p><i>Documentation for assembly %s, version %s, generated using the <a href='%s'>F# Programming Power Pack</a></i></p>" assemblyName ver urlForFSharp;
+            fprintfn oc "</BODY></HTML>";
+
+        let newFile fdir fileName title f =
+            let dir = Path.Combine(outputDir, fdir)
+            System.IO.Directory.CreateDirectory(dir) |> ignore
+            let fullname = Path.Combine(dir, fileName)
+            newExplicitFile false fullname fileName title (hrefConcat ".." cssFile) f
+
+        let hlink url text = sprintf "<a href='%s'>%s</a>" url text
+       
+        (* Path *)
+        let path0        = []
+        let path1 x kind = [(x,kind)]
+        let pathExtend xs x kind = xs @ [x,kind] in (* short shallow lists *)
+        let pathText     xs = String.concat "." (List.map fst xs)
+        let pathFilename xs =
+            let encode = function
+              | x,PathK   -> x
+              | x,TypeK w ->
+                  // Mangle to avoid colliding upper/lower names, 'complex' and 'Complex', to different filenames 
+                  // See also tastops.fs which prints type hrefs 
+                  "type_" + (underscoreLowercase x) + (if w=0 then "" else "-" + string w)
+            String.concat "." (List.map encode xs) + ".html"
+
+        let collapseStrings xs = String.concat "." xs
+        let pathWrt (knownNamespaces:Set<string>) x =
+            let xs = split '.' x
+            let rec collapse front back = 
+              match back with 
+              | [] -> (if front = [] then [] else [collapseStrings front]) @ back
+              | mid::back -> 
+                  if knownNamespaces.Contains (collapseStrings (front@[mid]))  
+                  then [collapseStrings (front@[mid])] @ back
+                  else collapse (front@[mid]) back
+            List.map (fun x -> (x,PathK)) (collapse [] xs)
+
+        let nestBlock hFile f =
+            wrap hFile "<br><dl>" "</dl>"
+               (fun () -> f())
+
+        let nestItem hFile f =
+            wrap hFile "<dt></dt><dd>" "</dd>"
+               (fun () -> f())
+          
+        (* TopNav - from paths *)
+        let newPathTrail hFile kind path =
+            let rec writer prior = function
+              | []         -> ()
+              | [x,k]      -> fprintf hFile "%s " x
+              | (x,k)::xks -> let prior = pathExtend prior x k
+                              let url   = pathFilename prior
+                              let sep   = if xks=[] then "" else "."
+                              let item  = hlink url x
+                              fprintf hFile "%s%s" item sep;
+                              writer prior xks
+            let uplink = sprintf "[<a href='%s'>Home</a>] " namespaceFileUpOne
+            nestItem hFile (fun () ->
+              fprintf hFile "<h1>%s%s " uplink kind;
+              writer path0 path;
+              fprintf hFile "</h1>";
+              fprintf hFile "<br>\n")
+
+        let newPartitions hFile f =
+            nestItem hFile (fun () ->
+              wrap hFile "<table>" "</table>" (fun () -> 
+                f()))
+        
+        let newPartition hFile desc f =
+            wrap hFile (sprintf "  <tr valign='top'><td>%s" desc) (sprintf "  </td></tr>") (fun () -> 
+              f())
+
+        let newSectionInPartition hFile title f =
+            wrap hFile (sprintf "  <dt><h3>%s</h3></dt><dd>" title) (sprintf "  </dd>") (fun () -> 
+              f())
+
+        let newPartitionsWithSeeAlsoBacklink hFile (bfilename,btitle) f = 
+            newPartitions hFile (fun () ->
+              f();
+              newPartition hFile "" (fun () -> 
+                newSectionInPartition hFile "See Also" (fun () -> 
+                  fprintf hFile "<a href=\"%s\">%s</a>" bfilename btitle)))
+
+        let newTable0 hFile title f = 
+            newSectionInPartition hFile title (fun () -> 
+              wrap hFile "<table width=\"100%%\">" "</table>" (fun () -> 
+                f()))
+
+        let newTable1 hFile title width1 h1 f = 
+            newTable0 hFile title (fun () -> 
+              wrap hFile (sprintf "<tr><th width=%d%%>%s</th></tr>" width1 h1) "" (fun () -> 
+                f()))
+        
+        let newTable2 hFile title width1 h1 h2 f = 
+            newTable0 hFile title (fun () -> 
+              wrap hFile (sprintf "<tr><th width=%d%%>%s</th><th>%s</th></tr>" width1 h1 h2) "" (fun () -> 
+                f()))
+        
+        let newNamespaceEntry hFile fdir path (allModules:FSharpEntity list) typeDefns =
+            let fileName = pathFilename path
+            let title = pathText path
+            let url = fdir + "/" + fileName
+            fprintf hFile "<tr valign='top'><td width='50%%'><a href='%s'>%s</a>\n" url title;
+
+            // Sort sub-modules into alphabetical order 
+            let allModules = 
+                allModules 
+                |> List.filter (fun x -> x.IsModule)
+                |> List.sortBy (fun x -> x.DisplayName)
+
+            // Make them hyperlink to fdir/<path>.html 
+            let typeLinks = 
+                typeDefns
+                |> List.map (fun (tycon:FSharpEntity) ->
+                               let path = pathExtend path tycon.DisplayName (TypeK tycon.GenericParameters.Count)
+                               let url   = fdir + "/" + pathFilename path
+                               //hlink url (sprintf "[%s]" (tycon.DisplayNameWithUnderscoreTypars.Replace("<","<").Replace(">",">")))) 
+                               let nm = 
+                                   if (typeDefns |> List.filter (fun tycon2 -> tycon.DisplayName = tycon2.DisplayName) |> List.length) > 1 then 
+                                      tycon.DisplayName + (if tycon.GenericParameters.Count > 0 then "`" + string tycon.GenericParameters.Count else "")
+                                   else
+                                      tycon.DisplayName
+                               
+                               hlink url (sprintf "[%s]" nm)) 
+                |> String.concat ", "
+            let moduleLinks = 
+                allModules
+                |> List.map (fun modul ->
+                               let path = pathExtend path modul.DisplayName PathK
+                               let url   = fdir + "/" + pathFilename path
+                               hlink url (sprintf "[%s]" modul.DisplayName)) 
+                |> String.concat ", "
+            fprintfn hFile "</td>" ;
+            fprintfn hFile  
+                "<td>%s%s</td>" 
+                (if not typeDefns.IsEmpty then sprintf "Types: %s" typeLinks else "")
+                (if not allModules.IsEmpty then sprintf "<br><br>Modules: %s<br>" moduleLinks else "");    
+            fprintfn hFile "</tr>" ;
+            ()
+
+        let newEntry1 hFile0 title = 
+            fprintfn hFile0 "<tr valign=\"top\"><td>%s</td></tr>" title 
+
+        let newEntry2     hFile0 title desc = 
+            fprintfn hFile0 "<tr valign=\"top\"><td>%s</td><td>%s</td></tr>" title desc
+
+        let initialDisplayEnv = 
+            let denv = 
+                { thisAssembly = assem;
+                  html=true;
+                  htmlHideRedundantKeywords=false;
+                  htmlAssemMap=
+                       Map.ofList 
+                         (if htmlDocLocalLinks
+                          then []
+                          else [("FSharp.Core",urlForFSharpCoreManual);
+                                ("FSharp.PowerPack",urlForFSharpPowerPackManual)])
+                  showObsoleteMembers=showObsoleteMembers;
+                  showTyparBinding = false;
+                  suppressInlineKeyword=true;
+                  showMemberContainers=false;
+                  showAttributes=true;
+                  showOverrides=false;
+                  showConstraintTyparAnnotations=showConstraintTyparAnnotations;
+                  abbreviateAdditionalConstraints=false;
+                  showTyparDefaultConstraints=false;
+                  shortConstraints=shortConstraints;
+                  contextAccessibility = Unchecked.defaultof<FSharpAccessibility> ;
+                }
+
+            denv
+
+        newExplicitFile append namespaceFileFullPath namespaceFileUpOne "Namespaces" cssFile (fun blinkNamespacesFile hNamespacesFile -> 
+
+          wrap hNamespacesFile (sprintf "<dl><dt><br/></dt><dd><table><tr><th>Namespaces in assembly %s</th><th>Description</th></tr>" assemblyName)
+                               (        "</table></dl>") (fun () ->
+
+            let obsoleteText (attribs: ReadOnlyCollection<FSharpAttribute>) = 
+                match tryFindAttrib<System.ObsoleteAttribute> attribs with
+                | Some(attr) -> sprintf "<p><b>Note</b>: %s</p>" attr.Message
+                | _ -> ""
+
+            let isObsolete attribs = hasAttrib<System.ObsoleteAttribute> attribs 
+
+            let isUnseenVal (v:FSharpMemberOrVal) = 
+                // not (IsValAccessible Infos.AccessibleFromEverywhere (mk_local_vref v)) ||
+                v.IsCompilerGenerated ||
+                (not initialDisplayEnv.showObsoleteMembers &&  isObsolete v.Attributes) 
+
+            let isUnseenEntity (e:FSharpEntity) = 
+                // not (IsEntityAccessible Infos.AccessibleFromEverywhere (mk_local_tcref e)) ||
+                (not initialDisplayEnv.showObsoleteMembers &&  isObsolete e.Attributes) 
+
+            let rec doValue denv fdir hFile path (v:FSharpMemberOrVal) = 
+                let denv = { denv with htmlHideRedundantKeywords=true }
+                let usageL, docL, noteL = FSharpMetadataPrintUtilities.layoutMemberOrVal denv v
+                newEntry2 hFile ("<pre>"+outputL widthVal usageL+"</pre>") (obsoleteText v.Attributes + getDocFromSig v.XmlDocSig xmlMemberMap + "<pre>" + outputL widthVal docL + "</pre>" + "<p>" + outputL widthVal noteL + "</p>")
+
+            let rec doValues denv fdir hFile path title item (vals:FSharpMemberOrVal list) = 
+                let vals = vals |> List.filter (fun v -> not v.IsCompilerGenerated)
+                let vals = vals |> List.sortBy (fun v -> v.DisplayName) 
+                if not vals.IsEmpty then 
+                  newTable2 hFile title 40 item  "Description" (fun () -> 
+                    vals |> List.iter (doValue denv fdir hFile path))
+
+            let rec doTypeDefn denv fdir hFile path (tycon:FSharpEntity) = 
+                newSectionInPartition hFile "Type Description" (fun () ->
+                  fprintf hFile "<pre>%s</pre>" (outputL widthType (FSharpMetadataPrintUtilities.layoutTypeDefn denv  tycon))) ;
+                let vals = 
+                    tycon.MembersOrValues 
+                    |> List.ofSeq
+                    |> List.filter (isUnseenVal >> not)
+
+                let ivals,svals = vals |> List.partition (fun v -> v.IsInstanceMember)
+                let cvals,svals = svals |> List.partition (fun v -> v.CompiledName = ".ctor")
+
+                let iimpls = if (not tycon.IsAbbreviation && not tycon.HasAssemblyCodeRepresentation && tycon.ReflectionType.IsInterface) then [] else tycon.Implements |> Seq.toList 
+
+                // TODO: layout base type in some way
+                if not iimpls.IsEmpty then 
+                  newTable1 hFile "Interfaces" 40 "Type"  (fun () -> 
+                    iimpls |> List.iter (fun i -> 
+                        newEntry1 hFile ("<pre>"+outputL widthVal (layoutType denv i)+"</pre>"))) 
+                // TODO: layout union cases as a table, with documentation
+                // TODO: layout record fields as a table, with documentation
+                doValues denv fdir hFile path "Constructors" "Member" cvals;
+                doValues denv fdir hFile path "Instance Members" "Member" ivals;
+                doValues denv fdir hFile path "Static Members" "Member"   svals;
+                //doValues denv fdir hFile path "Deprecated Members" "Member" dvals;
+
+                // TODO: layout events
+                // TODO: layout extension members
+
+                // mailboxProcessor.add_Error (null)
+                   
+            let rec doTypeDefns denv fdir blinkFile hFile path title (typeDefns:FSharpEntity list) = 
+                if typeDefns <> [] then  
+                  newTable2 hFile title 30 "Type" "Description" (fun () -> 
+                    let typeDefns = typeDefns |> List.sortBy (fun tc -> tc.CompiledName) 
+                    typeDefns |> List.iter (fun tycon ->
+                      let tyname = tycon.DisplayName
+                      let path  = pathExtend path tyname (TypeK tycon.GenericParameters.Count)
+                      let fileName  = pathFilename path
+                      let title  = pathText path    (* used as html page title *)
+                      let text = obsoleteText tycon.Attributes
+                      let text = text + (getDocFromSig tycon.XmlDocSig xmlMemberMap)
+                      let text = 
+                        if tycon.IsAbbreviation then 
+                            text + "</p> <p> Note: an abbreviation for "+("<tt>"+outputL widthType (FSharpMetadataPrintUtilities.layoutType denv tycon.AbbreviatedType)+"</tt>")
+                        else 
+                            text
+                      let tytext = outputL widthType (layoutTyparDeclsAfter denv false (wordL tycon.DisplayName) tycon.GenericParameters)
+                      
+                      newEntry2 hFile ("type " + hlink fileName tytext) text;
+
+                      newFile fdir fileName title (fun blinkFile2 hFile2 ->
+                        nestBlock hFile2 (fun () ->
+                          newPathTrail hFile2 "Type" path;
+                          newPartitionsWithSeeAlsoBacklink hFile2 blinkFile  (fun () -> 
+                            newPartition hFile2 text (fun () ->
+                              doTypeDefn denv fdir hFile2 path tycon))))))
+            
+            let rec doExceptionDefn denv fdir hFile path (exnc: FSharpEntity) = 
+                newSectionInPartition hFile "Description" (fun () ->
+                  let doc = getDocFromSig exnc.XmlDocSig xmlMemberMap
+                  fprintf hFile "<pre>%s</pre><p>%s</p>" (outputL widthException (FSharpMetadataPrintUtilities.layoutExceptionDefn denv exnc)) doc)
+
+            let rec doExceptionDefns denv fdir blinkFile hFile path (exceptionDefns:FSharpEntity list) = 
+                if not exceptionDefns.IsEmpty then  
+                    newTable2 hFile "Exceptions" 40 "Exception" "Description" (fun () -> 
+                        let exceptionDefns = exceptionDefns |> List.sortBy (fun exnc -> exnc.DisplayName) 
+                        exceptionDefns |> List.iter (fun exnc ->
+                            let path  = pathExtend path exnc.DisplayName (TypeK exnc.GenericParameters.Count)
+                            let fileName  = pathFilename path
+                            let exname = exnc.DisplayName
+                            let title  = pathText path   (* used as html page title *)
+                            let text = obsoleteText exnc.Attributes
+                            let text = text + (getDocFromSig exnc.XmlDocSig xmlMemberMap)
+                            let text = 
+                              if exnc.IsAbbreviation then 
+                                  text+"</p> <p> Note: an abbreviation for "+("<tt>"+outputL widthException (FSharpMetadataPrintUtilities.layoutType denv exnc.AbbreviatedType)+"</tt>")
+                              else 
+                                  text
+                            newEntry2 hFile ("exception " + hlink fileName exname) text;
+                            newFile fdir fileName title (fun blinkFile2 hFile2 ->
+                              nestBlock hFile2 (fun () ->
+                                newPathTrail hFile2 "Exception" path;
+                                newPartitionsWithSeeAlsoBacklink hFile2 blinkFile  (fun () -> 
+                                  newPartition hFile2 text (fun () ->
+                                    doExceptionDefn denv fdir hFile2 path exnc))))))
+            
+            let rec doModule denv fdir path blinkFile hFile (modul:FSharpEntity) = 
+
+                let modules = 
+                    modul.NestedEntities
+                    |> List.ofSeq
+                    |> List.filter (fun x -> x.IsModule)
+                    |> List.sortBy (fun x -> x.DisplayName) 
+                    |> List.filter (isUnseenEntity >> not)
+
+                let typeDefns = 
+                    modul.NestedEntities
+                    |> List.ofSeq
+                    |> List.filter (fun x -> not x.IsModule)
+                    |> List.filter (fun x -> not x.IsExceptionDeclaration)
+                    |> List.filter (isUnseenEntity >> not)
+
+                let exceptionDefns = 
+                    modul.NestedEntities
+                    |> List.ofSeq
+                    |> List.filter (fun x -> x.IsExceptionDeclaration)
+                    |> List.filter (isUnseenEntity >> not)
+
+                let vals = 
+                    modul.MembersOrValues
+                        |> Seq.toList
+                        |> List.filter (fun x -> not x.IsMember)
+                        |> List.filter (isUnseenVal >> not)
+
+                let extensionMembers = 
+                    modul.MembersOrValues
+                        |> Seq.toList
+                        |> List.filter (fun x -> x.IsExtensionMember)
+                        |> List.filter (isUnseenVal >> not)
+
+                let apvals,vals = 
+                    vals 
+                        |> List.partition (fun x -> x.IsActivePattern)
+
+                doModules denv fdir blinkFile hFile path modules; 
+                doTypeDefns denv fdir blinkFile hFile path "Type Definitions" typeDefns;
+                doExceptionDefns denv fdir blinkFile hFile path exceptionDefns;
+                doValues denv fdir hFile path "Values" "Value" vals; 
+                doValues denv fdir hFile path "Active Patterns" "Active Pattern" apvals; 
+                doValues denv fdir hFile path "Extension Members" "Extension Member" extensionMembers; 
+                //doTypeDefns denv fdir blinkFile hFile path "Deprecated/Unsafe Type Definitions" dtycons;
+                //doValues denv fdir hFile path "Deprecated Values" "Value" dvals 
+
+            and doModules denv fdir blinkFile hFile path (modules:FSharpEntity list) = 
+                if modules <> [] then  
+                  newTable2 hFile (sprintf "Modules (as contributed by assembly '%s')" assemblyName) 30 "Module" "Description" (fun () -> 
+                    let modules = modules |> List.sortBy (fun x -> x.DisplayName) 
+                    modules |> List.iter (fun modul -> 
+                      let path = pathExtend path modul.DisplayName PathK
+                      let fileName = pathFilename path
+                      let title = pathText path
+                      let text = obsoleteText modul.Attributes
+                      let text  = getDocFromSig modul.XmlDocSig xmlMemberMap
+                      newEntry2 hFile (hlink fileName title) text;
+                      newFile fdir fileName title (fun blinkFile2 hFile2 ->
+                        nestBlock hFile2 (fun () ->
+                          newPathTrail hFile2 "Module" path;
+                          newPartitionsWithSeeAlsoBacklink hFile2 blinkFile  (fun () -> 
+                            newPartition hFile2 text (fun () ->
+                              doModule denv fdir path blinkFile2 hFile2 modul))))))
+
+            let doEntities denv fdir path knownNamespaces (entities:FSharpEntity list) = 
+
+(*
+                let path = 
+                    /// skip the first item in the path which is the assembly name 
+                    match path with 
+                    | None    -> Some ""
+                    | Some "" -> Some modul.DisplayName
+                    | Some p  -> Some (p+"."+ modul.DisplayName)
+*)
+                let path = 
+                    match path with
+                    | None   -> path0
+                    | Some t -> pathWrt knownNamespaces t
+
+                let allModules = 
+                    entities
+                    |> List.filter (fun x -> x.IsModule)
+                    |> List.sortBy (fun x -> x.DisplayName) 
+                    |> List.filter (isUnseenEntity >> not)
+                    |> List.filter (fun m -> m.IsModule) 
+
+                let exceptionDefns = 
+                    entities
+                    |> List.filter (fun x -> x.IsExceptionDeclaration)
+                    |> List.filter (isUnseenEntity >> not)
+
+                let typeDefns = 
+                    entities
+                    |> List.filter (fun x -> not x.IsModule)
+                    |> List.sortBy (fun x -> x.CompiledName) 
+                    |> List.filter (fun x -> not x.IsExceptionDeclaration)
+                    |> List.filter (isUnseenEntity >> not)
+
+                // In FSharp.Core.dll filter out the attributes
+                let compilingFslib = (assemblyName = "FSharp.Core")
+
+                let typeDefns = 
+                   if compilingFslib then 
+                       typeDefns |> List.filter (fun tycon -> 
+                           // Filter out some things in FSharp.Core.dll docs
+                           not (tycon.DisplayName = "PrintfFormat") && 
+                           not (tycon.DisplayName = "FSharpTypeFunc") && 
+                           not (tycon.DisplayName = "FSharpFunc") && 
+                           not (tycon.DisplayName.StartsWith("Tuple",System.StringComparison.Ordinal)) && 
+                           // In FSharp.Core.dll filter out the attributes
+                           not (tycon.DisplayName.EndsWith("Attribute",System.StringComparison.Ordinal))
+                           )
+                   else
+                       typeDefns 
+
+
+                let fileName = pathFilename path
+                let title = pathText path
+                newFile fdir fileName title (fun blinkFile hFile ->
+                    newNamespaceEntry hNamespacesFile fdir path allModules typeDefns;
+                    doModules denv fdir blinkFile hFile path allModules;
+                    doTypeDefns denv fdir blinkFile hFile path "Type Definitions" typeDefns;
+                    doExceptionDefns denv fdir blinkFile hFile path exceptionDefns);
+                 
+
+            let allTopEntityGroups = 
+                assem.Entities |> Seq.groupBy (fun e -> e.Namespace)  |> Seq.sortBy (fun (nsp,_) -> nsp)
+
+            //let doEntities denv fdir path knownNamespaces (entities:FSharpEntity list) = 
+            for (groupNameSpace,entityGroup) in allTopEntityGroups do 
+                let knownNamespaces = set [groupNameSpace]
+                doEntities initialDisplayEnv assemblyName (Some groupNameSpace) knownNamespaces (Seq.toList entityGroup)))
+
+let mutable infiles = []
+let mutable outputDir = "."
+let mutable cssFile = "msdn.css"
+let mutable namespaceFile = "namespaces.html"
+let mutable htmlDocLocalLinks = false
+
+ArgParser.Parse(
+    [ ArgInfo("--outdir", ArgType.String (fun s -> outputDir <- s), "output directory");
+      ArgInfo("--cssfile", ArgType.String (fun s -> cssFile <- s), "name of CSS file (defaults to msdn.css)");
+      ArgInfo("--namespacefile", ArgType.String (fun s -> namespaceFile <- s), "name of the file in the output directory shared between multiple assemblies"); 
+      ArgInfo("--locallinks", ArgType.Unit (fun () -> htmlDocLocalLinks <- true), "<internal use only>");
+    ],
+    (fun s -> infiles <- infiles @ [s]) ,
+    "fshtmldoc.exe")
+
+try 
+    let mutable count = 0
+    if infiles.Length <= 0 then 
+       eprintfn "expected at least one DLL as input"
+       exit 1;
+    if not (System.IO.Directory.Exists outputDir) then 
+        System.IO.Directory.CreateDirectory outputDir |> ignore;
+    for infile in infiles do 
+        let append = (count > 0 )
+        count <- count + 1 
+        printfn "Processing '%s'..." infile
+        let xmlFile = System.IO.Path.ChangeExtension(infile, ".xml")
+        if not (System.IO.File.Exists xmlFile) then 
+             eprintfn "expected to find XML file at '%s'" xmlFile;
+             exit 1;
+           
+        HtmlDocWriter.WriteHTMLDoc (FSharpAssembly.FromFile infile, outputDir, append, cssFile, namespaceFile, htmlDocLocalLinks, xmlFile);
+    printfn "Done, docs written to directory '%s', namespace file is '%s' " outputDir namespaceFile
+with e -> 
+    printfn "Unexpected failure while writing HTML docs: %s" e.Message
+
diff --git a/src/FsHtmlDoc/FsHtmlDoc.fsproj b/src/FsHtmlDoc/FsHtmlDoc.fsproj
new file mode 100755
index 0000000..b5dc480
--- /dev/null
+++ b/src/FsHtmlDoc/FsHtmlDoc.fsproj
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <ProjectGuid>{09c71c41-9a24-4842-96f7-9ed5d5e0df3c}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AssemblyName>fshtmldoc</AssemblyName>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="assemblyinfo.fshtmldoc.exe.fs" />
+    <Compile Include="FsHtmlDoc.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="FSharp.Core" />
+    <ProjectReference Include="$(FSharpPowerPackSourcesRoot)\FSharp.PowerPack\FSharp.PowerPack.fsproj" Condition="Exists( '$(FSharpPowerPackSourcesRoot)\FSharp.PowerPack\FSharp.PowerPack.fsproj' )">
+      <Project>{649FA588-F02E-457C-9FCF-87E46407481F}</Project>
+      <Name>FSharp.PowerPack</Name>
+    </ProjectReference>
+    <ProjectReference Include="$(FSharpPowerPackSourcesRoot)\FSharp.PowerPack.Metadata\FSharp.PowerPack.Metadata.fsproj" Condition="Exists( '$(FSharpPowerPackSourcesRoot)\FSharp.PowerPack.Metadata\FSharp.PowerPack.Metadata.fsproj' )">
+      <Project>{816cb737-0648-4889-8662-54484d42824d}</Project>
+      <Name>FSharp.PowerPack.Metadata</Name>
+    </ProjectReference>
+    <Reference Include="System" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/src/FsHtmlDoc/FsHtmlDoc.fsproj.vspscc b/src/FsHtmlDoc/FsHtmlDoc.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FsHtmlDoc/FsHtmlDoc.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FsHtmlDoc/assemblyinfo.fshtmldoc.exe.fs b/src/FsHtmlDoc/assemblyinfo.fshtmldoc.exe.fs
new file mode 100755
index 0000000..2117ffb
--- /dev/null
+++ b/src/FsHtmlDoc/assemblyinfo.fshtmldoc.exe.fs
@@ -0,0 +1,8 @@
+
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("fshtmldoc.exe")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("fshtmldoc.exe")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
diff --git a/src/FsHtmlDoc/msdn.css b/src/FsHtmlDoc/msdn.css
new file mode 100755
index 0000000..7e8ea7f
--- /dev/null
+++ b/src/FsHtmlDoc/msdn.css
@@ -0,0 +1,229 @@
+body
+{
+	width: 100%;
+	margin: 0px 0px 0px 0px;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 70%;
+}
+
+h1, h3, h4
+{
+	margin-bottom: .4em;
+	margin-top: 1em;
+}
+
+h1
+{
+	font-size: 120%;
+	margin-top: 0em;
+}
+
+h3
+{
+	font-size: 115%;
+}
+
+h4
+{
+	font-size: 100%;
+}
+
+div.table
+{
+	text-align: center;
+}
+
+table
+{
+	font-size: 100%;
+	border-collapse: collapse;
+	width: 93%;
+}
+
+th
+{
+	background-color: #cccccc;
+	color: #000000;
+	font-weight: bolder;
+	padding: 5px;
+	border: 1px solid #999999;
+}
+
+tr
+{
+	background-color: #ffffff;
+	padding: 5px;
+	text-align: left;
+	border: 1px solid #999999;
+}
+
+td
+{
+	border: 1px solid #999999;
+	padding: 5px;
+}
+
+p
+{
+	margin: .5em 0em .5em 0em;
+}
+
+pre
+{
+	margin-top: .5em;
+	margin-bottom: .5em;
+}
+
+pre.code
+{
+    font: Monospace, Courier New, Courier;
+    color: #000066;
+    font-size: 100%;
+	margin-left: 20px;
+}
+
+.syntax
+{
+	font: Monospace, Courier New, Courier;
+	letter-spacing: .1em;
+	background-color: #cccccc;
+	color: #000000;
+	font-size: 100%;
+	font-weight: bolder;
+	padding: 5px;
+	border: 1px solid #999999;
+	margin-left: 20px;
+	padding: 4px 8px;
+	margin-top: 1em;
+	margin-bottom: 1em;
+	width: 96%;
+}
+.comment
+{
+	color:Green;
+	font-weight:lighter;	
+}
+.i1
+{
+	margin-left: 20px;
+}
+
+.i2
+{
+	margin-left: 40px;
+}
+
+.i3
+{
+	margin-left: 60px;
+}
+
+.missing
+{
+	color: Red;
+}
+
+div#banner
+{
+	width: 100%;
+	margin: 0px 0px 0px 0px;
+	border-width: 0px;
+	border-bottom: 1px solid #999999;
+	padding: 0px 0px 0px 0px;
+	background-color: #99ccff;
+}
+
+div#header
+{
+	margin: 0px 0px 0px 0px;
+	border-width: 0px;
+	padding: .4em .4em 0 .4em;
+	background-color: #99ccff;
+	font-style: italic;
+}
+
+div#footer
+{
+	font-size: 100%;
+	font-style:italic;
+	border-top: 1px solid #999999;
+	margin-left: 20px;
+	margin-top: 1em;
+	margin-bottom: 1em;
+	width: 96%;
+}
+
+div#banner h1
+{
+	margin: 0px 0px 0px 0px;
+	border-width: 0px;
+	padding: 0 .4em .3em .4em;
+	background-color: #99ccff;
+}
+
+div#content
+{
+	margin: 0px 0px 0px 0px;
+	padding: 4px 4px 4px 4px;
+}
+
+code.ce
+{
+	font-style: italic;
+}
+
+pre.syntax span.lang
+{
+	margin: 0;
+	font-weight: normal;
+}
+
+pre.syntax span.meta
+{
+	margin: 0;
+	font-weight: normal;
+	font-style: italic;
+}
+
+.permissions
+{
+	margin-top: 6px;
+}
+
+blockquote.dtBlock
+{
+	margin: .5em 1.5em .5em 1.5em;
+}
+
+a:link
+{
+	color: #0000ff;
+}
+
+a:visited
+{
+	color: #0000ff;
+}
+
+a:hover
+{
+	color: #3366ff;
+}
+
+a.typeLink
+{
+	text-decoration:none;
+}
+a:link.typeLink
+{
+	text-decoration:none;
+}
+a:visited.typeLink;
+{
+	text-decoration:none;
+}
+a:hover.typeLink
+{
+	font-style:italic;
+	text-decoration:underline;
+}
diff --git a/src/FsLex/FsLex.fsproj b/src/FsLex/FsLex.fsproj
new file mode 100755
index 0000000..0d5def9
--- /dev/null
+++ b/src/FsLex/FsLex.fsproj
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <!-- Always use x86 emulation for this binary... -->
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProjectGuid>{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}</ProjectGuid>
+    <TreatWarningsAsErrors>
+    </TreatWarningsAsErrors>
+    <!-- 5310 tracks reenabling -->
+    <OutputType>Exe</OutputType>
+    <AssemblyName>FsLex</AssemblyName>
+    <DefineConstants>INTERNALIZED_POWER_PACK;$(DefineConstants)</DefineConstants>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <FsLex Include="fslexlex.fsl">
+      <OtherFlags>--lexlib Internal.Utilities.Text.Lexing</OtherFlags>
+    </FsLex>
+    <FsYacc Include="fslexpars.fsy">
+      <OtherFlags>--internal --module FSharp.PowerPack.FsLex.Parser --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing</OtherFlags>
+    </FsYacc>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="assemblyinfo.fslex.exe.fs" />
+    <Compile Include="..\FSharp.PowerPack\Lexing.fsi">
+      <Link>lexing.fsi</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Lexing.fs">
+      <Link>lexing.fs</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Parsing.fsi">
+      <Link>parsing.fsi</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Parsing.fs">
+      <Link>parsing.fs</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Arg.fsi">
+      <Link>arg.fsi</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Arg.fs">
+      <Link>arg.fs</Link>
+    </Compile>
+    <Compile Include="fslexast.fs" />
+    <Compile Include="fslexpars.fs" />
+    <Compile Include="fslexlex.fs" />
+    <Compile Include="fslex.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="FSharp.Core" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(FSharpPowerPackSourcesRoot)\..\lkg\FSharp.PowerPack-$(LkgVersion)\bin\FSharp.PowerPack.targets" />
+</Project>
\ No newline at end of file
diff --git a/src/FsLex/FsLex.fsproj.vspscc b/src/FsLex/FsLex.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FsLex/FsLex.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FsLex/assemblyinfo.fslex.exe.fs b/src/FsLex/assemblyinfo.fslex.exe.fs
new file mode 100755
index 0000000..6f47839
--- /dev/null
+++ b/src/FsLex/assemblyinfo.fslex.exe.fs
@@ -0,0 +1,8 @@
+
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("fslex.exe")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("fslex.exe")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
diff --git a/src/FsLex/fslex.fs b/src/FsLex/fslex.fs
new file mode 100755
index 0000000..bd9fc8c
--- /dev/null
+++ b/src/FsLex/fslex.fs
@@ -0,0 +1,225 @@
+// (c) Microsoft Corporation 2005-2009.  
+
+module internal FSharp.PowerPack.FsLex.Driver 
+
+open FSharp.PowerPack.FsLex
+open FSharp.PowerPack.FsLex.AST
+open FSharp.PowerPack.FsLex.Parser
+open Printf
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+open System
+open System.Collections.Generic
+open System.IO 
+
+//------------------------------------------------------------------
+// This code is duplicated from Microsoft.FSharp.Compiler.UnicodeLexing
+
+type Lexbuf =  LexBuffer<char>
+
+/// Standard utility to create a Unicode LexBuffer
+///
+/// One small annoyance is that LexBuffers and not IDisposable. This means 
+/// we can't just return the LexBuffer object, since the file it wraps wouldn't
+/// get closed when we're finished with the LexBuffer. Hence we return the stream,
+/// the reader and the LexBuffer. The caller should dispose the first two when done.
+let UnicodeFileAsLexbuf (filename,codePage : int option) : FileStream * StreamReader * Lexbuf =
+    // Use the .NET functionality to auto-detect the unicode encoding
+    // It also presents the bytes read to the lexer in UTF8 decoded form
+    let stream  = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read) 
+    let reader = 
+        match codePage with 
+        | None -> new  StreamReader(stream,true)
+        | Some n -> new  StreamReader(stream,System.Text.Encoding.GetEncoding(n)) 
+    let lexbuf = LexBuffer.FromFunction(reader.Read) 
+    lexbuf.EndPos <- Position.FirstLine(filename);
+    stream, reader, lexbuf
+    
+//------------------------------------------------------------------
+// This is the program proper
+
+let input = ref None
+let out = ref None
+let inputCodePage = ref None
+let light = ref None
+
+let mutable lexlib = "Microsoft.FSharp.Text.Lexing"
+
+let usage =
+  [ ArgInfo ("-o", ArgType.String (fun s -> out := Some s), "Name the output file."); 
+    ArgInfo ("--codepage", ArgType.Int (fun i -> inputCodePage := Some i), "Assume input lexer specification file is encoded with the given codepage."); 
+    ArgInfo ("--light", ArgType.Unit (fun () ->  light := Some true), "(ignored)");
+    ArgInfo ("--light-off", ArgType.Unit (fun () ->  light := Some false), "Add #light \"off\" to the top of the generated file");
+    ArgInfo ("--lexlib", ArgType.String (fun s ->  lexlib <- s), "Specify the namespace for the implementation of the lexer table interperter (default Microsoft.FSharp.Text.Lexing)");
+    ArgInfo ("--unicode", ArgType.Set unicode, "Produce a lexer for use with 16-bit unicode characters.");  
+  ]
+
+let _ = ArgParser.Parse(usage, (fun x -> match !input with Some _ -> failwith "more than one input given" | None -> input := Some x), "fslex <filename>")
+
+let outputInt (os: TextWriter) (n:int) = os.Write(string n)
+
+let outputCodedUInt16 (os: #TextWriter)  (n:int) = 
+  os.Write n;
+  os.Write "us; ";
+
+let sentinel = 255 * 256 + 255 
+
+let lineCount = ref 0
+let cfprintfn (os: #TextWriter) fmt = Printf.kfprintf (fun () -> incr lineCount; os.WriteLine()) os fmt
+
+let main() = 
+  try 
+    let filename = (match !input with Some x -> x | None -> failwith "no input given") 
+    let domain = if !unicode then "Unicode" else "Ascii" 
+    let spec = 
+      let stream,reader,lexbuf = UnicodeFileAsLexbuf(filename, !inputCodePage) 
+      use stream = stream
+      use reader = reader
+      try 
+          Parser.spec Lexer.token lexbuf 
+      with e -> 
+          printf "%s(%d,%d): error: %s" filename lexbuf.StartPos.Line lexbuf.StartPos.Column 
+              (match e with 
+               | Failure s -> s 
+               | _ -> e.Message);
+          exit 1
+    printfn "compiling to dfas (can take a while...)";
+    let perRuleData, dfaNodes = AST.Compile spec
+    let dfaNodes = dfaNodes |> List.sortBy (fun n -> n.Id) 
+
+    printfn "%d states" dfaNodes.Length;
+    printfn "writing output"; 
+    
+    let output = 
+        match !out with 
+        | Some x -> x 
+        | _ -> 
+            Path.Combine (Path.GetDirectoryName filename,Path.GetFileNameWithoutExtension(filename)) + ".fs"
+    use os = System.IO.File.CreateText output
+
+    if (!light = Some(false)) || (!light = None && (Path.HasExtension(output) && Path.GetExtension(output) = ".ml")) then
+        cfprintfn os "#light \"off\"";
+    
+    let printLinesIfCodeDefined (code,pos:Position) =
+        if pos <> Position.Empty  // If bottom code is unspecified, then position is empty.        
+        then 
+            cfprintfn os "# %d \"%s\"" pos.Line pos.FileName;
+            cfprintfn os "%s" code;
+
+    printLinesIfCodeDefined spec.TopCode
+    let code = fst spec.TopCode
+    lineCount := !lineCount + code.Replace("\r","").Split([| '\n' |]).Length;
+    cfprintfn os "# %d \"%s\"" !lineCount output;
+    
+    cfprintfn os "let trans : uint16[] array = ";
+    cfprintfn os "    [| ";
+    if !unicode then 
+        let specificUnicodeChars = GetSpecificUnicodeChars()
+        // This emits a (numLowUnicodeChars+NumUnicodeCategories+(2*#specificUnicodeChars)+1) * #states array of encoded UInt16 values
+        
+        // Each row for the Unicode table has format 
+        //      128 entries for ASCII characters
+        //      A variable number of 2*UInt16 entries for SpecificUnicodeChars 
+        //      30 entries, one for each UnicodeCategory
+        //      1 entry for EOF
+        //
+        // Each entry is an encoded UInt16 value indicating the next state to transition to for this input.
+        //
+        // For the SpecificUnicodeChars the entries are char/next-state pairs.
+        for state in dfaNodes do
+            cfprintfn os "    (* State %d *)" state.Id;
+            fprintf os "     [| ";
+            let trans = 
+                let dict = new Dictionary<_,_>()
+                state.Transitions |> List.iter dict.Add
+                dict
+            let emit n = 
+                if trans.ContainsKey(n) then 
+                  outputCodedUInt16 os trans.[n].Id 
+                else
+                  outputCodedUInt16 os sentinel
+            for i = 0 to numLowUnicodeChars-1 do 
+                let c = char i
+                emit (EncodeChar c);
+            for c in specificUnicodeChars do 
+                outputCodedUInt16 os (int c); 
+                emit (EncodeChar c);
+            for i = 0 to NumUnicodeCategories-1 do 
+                emit (EncodeUnicodeCategoryIndex i);
+            emit Eof;
+            cfprintfn os "|];"
+        done;
+    
+    else
+        // Each row for the ASCII table has format 
+        //      256 entries for ASCII characters
+        //      1 entry for EOF
+        //
+        // Each entry is an encoded UInt16 value indicating the next state to transition to for this input.
+
+        // This emits a (256+1) * #states array of encoded UInt16 values
+        for state in dfaNodes do
+            cfprintfn os "   (* State %d *)" state.Id;
+            fprintf os " [|";
+            let trans = 
+                let dict = new Dictionary<_,_>()
+                state.Transitions |> List.iter dict.Add
+                dict
+            let emit n = 
+                if trans.ContainsKey(n) then 
+                  outputCodedUInt16 os trans.[n].Id 
+                else
+                  outputCodedUInt16 os sentinel
+            for i = 0 to 255 do 
+                let c = char i
+                emit (EncodeChar c);
+            emit Eof;
+            cfprintfn os "|];"
+        done;
+    
+    cfprintfn os "    |] ";
+    
+    fprintf os "let actions : uint16[] = [|";
+    for state in dfaNodes do
+        if state.Accepted.Length > 0 then 
+          outputCodedUInt16 os (snd state.Accepted.Head)
+        else
+          outputCodedUInt16 os sentinel
+    done;
+    cfprintfn os "|]";
+    cfprintfn os "let _fslex_tables = %s.%sTables.Create(trans,actions)" lexlib domain;
+    
+    cfprintfn os "let rec _fslex_dummy () = _fslex_dummy() ";
+
+    // These actions push the additional start state and come first, because they are then typically inlined into later
+    // rules. This means more tailcalls are taken as direct branches, increasing efficiency and 
+    // improving stack usage on platforms that do not take tailcalls.
+    for ((startNode, actions),(ident,args,_)) in List.zip perRuleData spec.Rules do
+        cfprintfn os "(* Rule %s *)" ident;
+        cfprintfn os "and %s %s (lexbuf : %s.LexBuffer<_>) = _fslex_%s %s %d lexbuf" ident (String.Join(" ",Array.ofList args)) lexlib ident (String.Join(" ",Array.ofList args)) startNode.Id;
+    for ((startNode, actions),(ident,args,_)) in List.zip perRuleData spec.Rules do
+        cfprintfn os "(* Rule %s *)" ident;
+        cfprintfn os "and _fslex_%s %s _fslex_state lexbuf =" ident (String.Join(" ",Array.ofList args));
+        cfprintfn os "  match _fslex_tables.Interpret(_fslex_state,lexbuf) with" ;
+        actions |> Seq.iteri (fun i (code,pos) -> 
+            cfprintfn os "  | %d -> ( " i;
+            cfprintfn os "# %d \"%s\"" pos.Line pos.FileName;
+            let lines = code.Split([| '\r'; '\n' |], StringSplitOptions.RemoveEmptyEntries)
+            for line in lines do
+                cfprintfn os "               %s" line;
+            cfprintfn os "# %d \"%s\"" !lineCount output;
+            cfprintfn os "          )")
+        cfprintfn os "  | _ -> failwith \"%s\"" ident
+    
+
+    cfprintfn os "";
+        
+    printLinesIfCodeDefined spec.BottomCode
+    cfprintfn os "# 3000000 \"%s\"" output;
+    
+  with e -> 
+    printf "FSLEX: error FSL000: %s" (match e with Failure s -> s | e -> e.ToString());
+    exit 1
+
+
+let _ = main()
diff --git a/src/FsLex/fslexast.fs b/src/FsLex/fslexast.fs
new file mode 100755
index 0000000..c1d8a46
--- /dev/null
+++ b/src/FsLex/fslexast.fs
@@ -0,0 +1,409 @@
+(* (c) Microsoft Corporation 2005-2008.  *)
+
+module FSharp.PowerPack.FsLex.AST
+
+open System.Collections.Generic
+open Microsoft.FSharp.Text
+open Microsoft.FSharp.Collections
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+
+let (|KeyValue|) (kvp:KeyValuePair<_,_>) = kvp.Key,kvp.Value
+
+type Ident = string
+type Code = string * Position
+
+type Alphabet = uint32
+
+let Eof : Alphabet = 0xFFFFFFFEu
+let Epsilon : Alphabet = 0xFFFFFFFFu
+
+
+let unicode = ref false
+
+let unicodeCategories = 
+ dict 
+  [| "Pe", System.Globalization.UnicodeCategory.ClosePunctuation; // (Pe)
+    "Pc", System.Globalization.UnicodeCategory.ConnectorPunctuation; // (Pc)
+    "Cc", System.Globalization.UnicodeCategory.Control; // (Cc)
+    "Sc", System.Globalization.UnicodeCategory.CurrencySymbol; // (Sc)
+    "Pd", System.Globalization.UnicodeCategory.DashPunctuation; // (Pd)
+    "Nd", System.Globalization.UnicodeCategory.DecimalDigitNumber; // (Nd)
+    "Me", System.Globalization.UnicodeCategory.EnclosingMark; // (Me)
+    "Pf", System.Globalization.UnicodeCategory.FinalQuotePunctuation; // (Pf)
+    "Cf", enum 15; //System.Globalization.UnicodeCategory.Format; // (Cf)
+    "Pi", System.Globalization.UnicodeCategory.InitialQuotePunctuation; // (Pi)
+    "Nl", System.Globalization.UnicodeCategory.LetterNumber; // (Nl)
+    "Zl", System.Globalization.UnicodeCategory.LineSeparator; // (Zl)
+    "Ll", System.Globalization.UnicodeCategory.LowercaseLetter; // (Ll)
+    "Sm", System.Globalization.UnicodeCategory.MathSymbol; // (Sm)
+    "Lm", System.Globalization.UnicodeCategory.ModifierLetter; // (Lm)
+    "Sk", System.Globalization.UnicodeCategory.ModifierSymbol; // (Sk)
+    "Mn", System.Globalization.UnicodeCategory.NonSpacingMark; // (Mn)
+    "Ps", System.Globalization.UnicodeCategory.OpenPunctuation; // (Ps)
+    "Lo", System.Globalization.UnicodeCategory.OtherLetter; // (Lo)
+    "Cn", System.Globalization.UnicodeCategory.OtherNotAssigned; // (Cn)
+    "No", System.Globalization.UnicodeCategory.OtherNumber; // (No)
+    "Po", System.Globalization.UnicodeCategory.OtherPunctuation; // (Po)
+    "So", System.Globalization.UnicodeCategory.OtherSymbol; // (So)
+    "Zp", System.Globalization.UnicodeCategory.ParagraphSeparator; // (Zp)
+    "Co", System.Globalization.UnicodeCategory.PrivateUse; // (Co)
+    "Zs", System.Globalization.UnicodeCategory.SpaceSeparator; // (Zs)
+    "Mc", System.Globalization.UnicodeCategory.SpacingCombiningMark; // (Mc)
+    "Cs", System.Globalization.UnicodeCategory.Surrogate; // (Cs)
+    "Lt", System.Globalization.UnicodeCategory.TitlecaseLetter; // (Lt)
+    "Lu", System.Globalization.UnicodeCategory.UppercaseLetter; // (Lu)
+  |]
+
+let NumUnicodeCategories = unicodeCategories.Count
+let _ = assert (NumUnicodeCategories = 30) // see table interpreter
+let encodedUnicodeCategoryBase = 0xFFFFFF00u
+let EncodeUnicodeCategoryIndex(idx:int) = encodedUnicodeCategoryBase + uint32 idx
+let EncodeUnicodeCategory(s:string) = 
+    if not (!unicode) then 
+         failwith "unicode category classes may only be used if --unicode is specified";
+    if unicodeCategories.ContainsKey(s) then 
+        EncodeUnicodeCategoryIndex (int32 unicodeCategories.[s])
+    else
+        failwithf "invalid Unicode category: '%s'" s
+
+let IsUnicodeCategory(x:Alphabet) = (encodedUnicodeCategoryBase <= x) && (x < encodedUnicodeCategoryBase + uint32 NumUnicodeCategories)
+let UnicodeCategoryIndex(x:Alphabet) = (x - encodedUnicodeCategoryBase)
+
+let numLowUnicodeChars = 128
+let _ = assert (numLowUnicodeChars = 128) // see table interpreter
+let specificUnicodeChars = new Dictionary<_,_>()
+let specificUnicodeCharsDecode = new Dictionary<_,_>()
+let EncodeChar(c:char) = 
+     let x = System.Convert.ToUInt32 c
+     if !unicode then 
+         if x < uint32 numLowUnicodeChars then x 
+         else 
+             if not(specificUnicodeChars.ContainsKey(c)) then
+                 let idx = uint32 numLowUnicodeChars + uint32 specificUnicodeChars.Count  
+                 specificUnicodeChars.[c] <- idx
+                 specificUnicodeCharsDecode.[idx] <- c
+             specificUnicodeChars.[c]
+     else         
+         if x >= 256u then failwithf "the Unicode character '%c' may not be used unless --unicode is specified" c;
+         x
+let DecodeChar(x:Alphabet) = 
+     if !unicode then 
+         if x < uint32 numLowUnicodeChars then System.Convert.ToChar x
+         else specificUnicodeCharsDecode.[x]
+     else
+         if x >= 256u then failwithf "the Unicode character '%x' may not be used unless --unicode is specified" x;
+         System.Convert.ToChar x
+         
+         
+
+let NumSpecificUnicodeChars() = specificUnicodeChars.Count
+let GetSpecificUnicodeChars() = 
+    specificUnicodeChars 
+        |> Seq.sortBy (fun (KeyValue(k,v)) -> v) 
+        |> Seq.map (fun (KeyValue(k,v)) -> k) 
+
+let GetSingleCharAlphabet() = 
+    if !unicode 
+    then Set.ofList [ for c in 0..numLowUnicodeChars-1 do yield (char c)
+                      for c in GetSpecificUnicodeChars() do yield c ]
+    else Set.ofList [ for x in 0..255 ->  (char x) ]
+         
+let GetAlphabet() = 
+    if !unicode 
+    then Set.ofList [ for c in GetSingleCharAlphabet() do yield EncodeChar c
+                      for uc in 0 .. NumUnicodeCategories-1 do yield EncodeUnicodeCategoryIndex uc ]
+    else Set.ofList [ for c in GetSingleCharAlphabet() do yield EncodeChar c ]
+
+         
+//let DecodeAlphabet (x:Alphabet) = System.Convert.ToChar(x)
+
+(*
+for i in 0 .. 65535 do 
+    let c = char i
+    if System.Char.GetUnicodeCategory c = System.Globalization.UnicodeCategory.PrivateUse then 
+        printfn "i = %x" i
+*)
+
+type Spec = 
+    { TopCode: Code;
+      Macros: (Ident * Regexp) list;
+      Rules: (Ident * Ident list * Clause list) list;
+      BottomCode: Code }
+and Clause = Regexp * Code
+and Regexp = 
+  | Alt of Regexp list
+  | Seq of Regexp list
+  | Inp of Input
+  | Star of Regexp
+  | Macro of Ident
+and Input =
+  | Alphabet of Alphabet
+  | UnicodeCategory of string 
+  | Any 
+  | NotCharSet of Set<Alphabet>
+
+type NodeId = int   
+
+type NfaNode = 
+    { Id: NodeId;
+      Name: string;
+      Transitions: Dictionary<Alphabet, NfaNode list>;
+      Accepted: (int * int) list }
+
+type DfaNode = 
+    { Id: int;
+      Name: string;
+      mutable Transitions: (Alphabet * DfaNode) list;
+      Accepted: (int * int) list }
+
+type MultiMap<'a,'b> = Dictionary<'a,'b list>
+let LookupMultiMap (trDict:MultiMap<_,_>) a  =
+    if trDict.ContainsKey(a) then trDict.[a] else []
+
+let AddToMultiMap (trDict:MultiMap<_,_>) a b =
+    let prev = LookupMultiMap trDict a
+    trDict.[a] <- b::prev
+
+type NfaNodeMap() = 
+    let map = new Dictionary<int,NfaNode>(100)
+    member x.Item with get(nid) = map.[nid]
+    member x.Count = map.Count
+
+    member x.NewNfaNode(trs,ac) = 
+        let nodeId = map.Count+1 // ID zero is reserved
+        let trDict = new Dictionary<_,_>(List.length trs)
+        for (a,b) in trs do
+           AddToMultiMap trDict a b
+           
+        let node : NfaNode = {Id=nodeId; Name=string nodeId; Transitions=trDict; Accepted=ac}
+        map.[nodeId] <-node;
+        node
+
+let LexerStateToNfa (macros: Map<string,_>) (clauses: Clause list) = 
+
+    /// Table allocating node ids 
+    let nfaNodeMap = new NfaNodeMap()
+    
+    /// Compile a regular expression into the NFA
+    let rec CompileRegexp re dest = 
+        match re with 
+        | Alt res -> 
+            let trs = res |> List.map (fun re -> (Epsilon,CompileRegexp re dest)) 
+            nfaNodeMap.NewNfaNode(trs,[])
+        | Seq res -> 
+            List.foldBack (CompileRegexp) res dest 
+        | Inp (Alphabet c) -> 
+            nfaNodeMap.NewNfaNode([(c, dest)],[])
+            
+        | Star re -> 
+            let nfaNode = nfaNodeMap.NewNfaNode([(Epsilon, dest)],[])
+            let sre = CompileRegexp re nfaNode
+            AddToMultiMap nfaNode.Transitions Epsilon sre
+            nfaNodeMap.NewNfaNode([(Epsilon,sre); (Epsilon,dest)],[])
+        | Macro m -> 
+            if not (macros.ContainsKey(m)) then failwith ("The macro "+m+" is not defined");
+            CompileRegexp (macros.[m]) dest 
+
+        // These cases unwind the difficult cases in the syntax that rely on knowing the
+        // entire alphabet.
+        //
+        // Note we've delayed the expension of these until we've worked out all the 'special' Unicode characters
+        // mentioned in the entire lexer spec, i.e. we wait until GetAlphabet returns a reliable and stable answer.
+        | Inp (UnicodeCategory uc) -> 
+            let re = Alt([ yield Inp(Alphabet(EncodeUnicodeCategory uc))
+                           // Also include any specific characters in this category
+                           for c in GetSingleCharAlphabet() do 
+                               if System.Char.GetUnicodeCategory(c) = unicodeCategories.[uc] then 
+                                    yield Inp(Alphabet(EncodeChar(c))) ])
+            CompileRegexp re dest
+
+        | Inp Any -> 
+            let re = Alt([ for n in GetAlphabet() do yield Inp(Alphabet(n)) ])
+            CompileRegexp re dest
+
+        | Inp (NotCharSet chars) -> 
+            let re = Alt [ // Include any characters from those in the alphabet besides those that are not immediately excluded
+                           for c in GetSingleCharAlphabet() do 
+                               let ec = EncodeChar c
+                               if not (chars.Contains(ec)) then 
+                                   yield Inp(Alphabet(ec))
+
+                           // Include all unicode categories 
+                           // That is, negations _only_ exclude precisely the given set of characters. You can't
+                           // exclude whole classes of characters as yet
+                           if !unicode then 
+                               let ucs = chars |> Set.map(DecodeChar >> System.Char.GetUnicodeCategory)  
+                               for KeyValue(nm,uc) in unicodeCategories do
+                                   //if ucs.Contains(uc) then 
+                                   //    do printfn "warning: the unicode category '\\%s' ('%s') is automatically excluded by this character set negation. Consider adding this to the negation." nm  (uc.ToString())
+                                   //    yield! []
+                                   //else
+                                       yield Inp(Alphabet(EncodeUnicodeCategory nm)) 
+                         ]
+            CompileRegexp re dest
+
+    let actions = new System.Collections.Generic.List<_>()
+    
+    /// Compile an acceptance of a regular expression into the NFA
+    let sTrans macros nodeId (regexp,code) = 
+        let actionId = actions.Count
+        actions.Add(code)
+        let sAccept = nfaNodeMap.NewNfaNode([],[(nodeId,actionId)])
+        CompileRegexp regexp sAccept 
+
+    let trs = clauses |> List.mapi (fun n x -> (Epsilon,sTrans macros n x)) 
+    let nfaStartNode = nfaNodeMap.NewNfaNode(trs,[])
+    nfaStartNode,(actions |> Seq.readonly), nfaNodeMap
+
+// TODO: consider a better representation here.
+type internal NfaNodeIdSetBuilder = HashSet<NodeId>
+
+type internal NfaNodeIdSet(nodes: NfaNodeIdSetBuilder) = 
+    // BEWARE: the next line is performance critical
+    let s = nodes |> Seq.toArray |> (fun arr -> Array.sortInPlaceWith compare arr; arr) // 19
+
+    // These are all surprisingly slower:
+    //let s = nodes |> Seq.toArray |> Array.sort 
+    //let s = nodes |> Seq.toArray |> Array.sortWith compare // 76
+    //let s = nodes |> Seq.toArray |> (fun arr -> Array.sortInPlace arr; arr) // 76
+
+    member x.Representation = s
+    member x.Elements = s 
+    member x.Fold f z = Array.fold f z s
+    interface System.IComparable with 
+        member x.CompareTo(y:obj) = 
+            let y = (y :?> NfaNodeIdSet)
+            let xr = x.Representation
+            let yr = y.Representation
+            let c = compare xr.Length yr.Length
+            if c <> 0 then c else 
+            let n = yr.Length
+            let rec go i = 
+                if i >= n then 0 else
+                let c = compare xr.[i] yr.[i]
+                if c <> 0 then c else
+                go (i+1) 
+            go 0
+
+    override x.Equals(y:obj) = 
+        match y with 
+        | :? NfaNodeIdSet as y -> 
+            let xr = x.Representation
+            let yr = y.Representation
+            let n = yr.Length
+            xr.Length = n && 
+            (let rec go i = (i < n) && xr.[i] = yr.[i] && go (i+1) 
+             go 0)
+        | _ -> false
+
+    override x.GetHashCode() = hash s
+
+    member x.IsEmpty = (s.Length = 0)
+    member x.Iterate f = s |> Array.iter f
+
+type NodeSetSet = Set<NfaNodeIdSet>
+
+let newDfaNodeId = 
+    let i = ref 0 
+    fun () -> let res = !i in incr i; res
+   
+let NfaToDfa (nfaNodeMap:NfaNodeMap) nfaStartNode = 
+    let numNfaNodes = nfaNodeMap.Count
+    let rec EClosure1 (acc:NfaNodeIdSetBuilder) (n:NfaNode) = 
+        if not (acc.Contains(n.Id)) then 
+            acc.Add(n.Id) |> ignore;
+            if n.Transitions.ContainsKey(Epsilon) then
+                match n.Transitions.[Epsilon] with 
+                | [] -> () // this Clause is an optimization - the list is normally empty
+                | tr -> 
+                    //printfn "n.Id = %A, #Epsilon = %d" n.Id tr.Length
+                    tr |> List.iter (EClosure1 acc) 
+
+    let EClosure (moves:list<NodeId>) = 
+        let acc = new NfaNodeIdSetBuilder(HashIdentity.Structural)
+        for i in moves do
+            EClosure1 acc nfaNodeMap.[i];
+        new NfaNodeIdSet(acc)
+
+    // Compute all the immediate one-step moves for a set of NFA states, as a dictionary
+    // mapping inputs to destination lists
+    let ComputeMoves (nset:NfaNodeIdSet) = 
+        let moves = new MultiMap<_,_>()
+        nset.Iterate(fun nodeId -> 
+            for (KeyValue(inp,dests)) in nfaNodeMap.[nodeId].Transitions do
+                if inp <> Epsilon then 
+                    match dests with 
+                    | [] -> ()  // this Clause is an optimization - the list is normally empty
+                    | tr -> tr |> List.iter(fun dest -> AddToMultiMap moves inp dest.Id))
+        moves
+
+    let acc = new NfaNodeIdSetBuilder(HashIdentity.Structural)
+    EClosure1 acc nfaStartNode;
+    let nfaSet0 = new NfaNodeIdSet(acc)
+
+    let dfaNodes = ref (Map.empty<NfaNodeIdSet,DfaNode>)
+
+    let GetDfaNode nfaSet = 
+        if (!dfaNodes).ContainsKey(nfaSet) then 
+            (!dfaNodes).[nfaSet]
+        else 
+            let dfaNode =
+                { Id= newDfaNodeId(); 
+                  Name = nfaSet.Fold (fun s nid -> nfaNodeMap.[nid].Name+"-"+s) ""; 
+                  Transitions=[];
+                  Accepted= nfaSet.Elements 
+                            |> Seq.map (fun nid -> nfaNodeMap.[nid].Accepted)
+                            |> List.concat }
+            //Printf.printfn "id = %d" dfaNode.Id;
+
+            dfaNodes := (!dfaNodes).Add(nfaSet,dfaNode); 
+            dfaNode
+            
+    let workList = ref [nfaSet0]
+    let doneSet = ref Set.empty
+
+    //let count = ref 0 
+    let rec Loop () = 
+        match !workList with 
+        | [] -> ()
+        | nfaSet ::t -> 
+            workList := t;
+            if (!doneSet).Contains(nfaSet) then 
+                Loop () 
+            else
+                let moves = ComputeMoves nfaSet
+                for (KeyValue(inp,movesForInput)) in moves do
+                    assert (inp <> Epsilon);
+                    let moveSet = EClosure movesForInput;
+                    if not moveSet.IsEmpty then 
+                        //incr count
+                        let dfaNode = GetDfaNode nfaSet
+                        dfaNode.Transitions <- (inp, GetDfaNode moveSet) :: dfaNode.Transitions;
+                        (* Printf.printf "%d (%s) : %s --> %d (%s)\n" dfaNode.Id dfaNode.Name (match inp with EncodeChar c -> String.make 1 c | LEof -> "eof") moveSetDfaNode.Id moveSetDfaNode.Name;*)
+                        workList := moveSet :: !workList;
+
+                doneSet := (!doneSet).Add(nfaSet);
+
+
+                Loop()
+    Loop();
+    //Printf.printfn "count = %d" !count;
+    let ruleStartNode = GetDfaNode nfaSet0
+    let ruleNodes = 
+        (!dfaNodes) 
+        |> Seq.map (fun kvp -> kvp.Value) 
+        |> Seq.toList
+        |> List.sortBy (fun s -> s.Id)
+    ruleStartNode,ruleNodes
+
+let Compile spec = 
+    List.foldBack
+        (fun (name,args,clauses) (perRuleData,dfaNodes) -> 
+            let nfa, actions, nfaNodeMap = LexerStateToNfa (Map.ofList spec.Macros) clauses
+            let ruleStartNode, ruleNodes = NfaToDfa nfaNodeMap nfa
+            //Printf.printfn "name = %s, ruleStartNode = %O" name ruleStartNode.Id;
+            (ruleStartNode,actions) :: perRuleData, ruleNodes @ dfaNodes)
+        spec.Rules
+        ([],[])
+
diff --git a/src/FsLex/fslexlex.fsl b/src/FsLex/fslexlex.fsl
new file mode 100755
index 0000000..ad64ecd
--- /dev/null
+++ b/src/FsLex/fslexlex.fsl
@@ -0,0 +1,208 @@
+{
+(* (c) Microsoft Corporation 2005-2008.  *)
+  
+module internal FSharp.PowerPack.FsLex.Lexer
+  
+open FSharp.PowerPack.FsLex.AST
+open FSharp.PowerPack.FsLex.Parser
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+open System.Text
+
+let escape c = 
+  match c with
+  | '\\' -> '\\'
+  | '\'' -> '\''
+  | 'n' -> '\n'
+  | 't' -> '\t'
+  | 'b' -> '\b'
+  | 'r' -> '\r'
+  | c -> c
+
+let lexeme (lexbuf : LexBuffer<char>) = new System.String(lexbuf.Lexeme)
+let newline (lexbuf:LexBuffer<_>) = lexbuf.EndPos <- lexbuf.EndPos.NextLine
+
+let unexpected_char lexbuf =
+      failwith ("Unexpected character '"+(lexeme lexbuf)+"'")
+
+let digit d = 
+      if d >= '0' && d <= '9' then int32 d - int32 '0'   
+      else failwith "digit" 
+
+let hexdigit d = 
+      if d >= '0' && d <= '9' then digit d 
+      else if d >= 'a' && d <= 'f' then int32 d - int32 'a' + 10
+      else if d >= 'A' && d <= 'F' then int32 d - int32 'A' + 10
+      else failwithf "bad hexdigit: %c" d 
+
+let trigraph c1 c2 c3 =
+      char (digit c1 * 100 + digit c2 * 10 + digit c3)
+
+let hexgraph c1 c2 =
+      char (hexdigit c1 * 16 + hexdigit c2)
+
+let unicodegraph_short (s:string) =
+    if s.Length <> 4 then failwith "unicodegraph";
+    char(hexdigit s.[0] * 4096 + hexdigit s.[1] * 256 + hexdigit s.[2] * 16 + hexdigit s.[3])
+
+let unicodegraph_long (s:string) =
+    if s.Length <> 8 then failwith "unicodegraph_long";
+    let high = hexdigit s.[0] * 4096 + hexdigit s.[1] * 256 + hexdigit s.[2] * 16 + hexdigit s.[3] in 
+    let low = hexdigit s.[4] * 4096 + hexdigit s.[5] * 256 + hexdigit s.[6] * 16 + hexdigit s.[7] in 
+    if high = 0 then None, char low 
+    else 
+      (* A surrogate pair - see http://www.unicode.org/unicode/uni2book/ch03.pdf, section 3.7 *)
+      Some (char(0xD800 + ((high * 0x10000 + low - 0x10000) / 0x400))),
+      char(0xDF30 + ((high * 0x10000 + low - 0x10000) % 0x400))
+
+} 
+
+let letter = ['A'-'Z'] | ['a'-'z']
+let digit = ['0'-'9']
+let whitespace = [' ' '\t']
+let char = '\'' ( [^'\\'] | ('\\' ( '\\' | '\'' | "\"" | 'n' | 't' | 'b' | 'r'))) '\''
+let hex = ['0'-'9'] | ['A'-'F'] | ['a'-'f']
+let hexgraph = '\\' 'x' hex hex
+let trigraph = '\\' digit digit digit
+let newline = ('\n' | '\r' '\n')
+let ident_start_char = letter       
+let ident_char = ( ident_start_char| digit | ['\'' '_'] )
+let ident = ident_start_char ident_char*
+
+let unicodegraph_short = '\\' 'u' hex hex hex hex
+let unicodegraph_long =  '\\' 'U' hex hex hex hex hex hex hex hex
+
+rule token = parse
+ | "rule" {RULE }
+ | "parse" {PARSE }
+ | "eof" {EOF }
+ | "let" {LET }
+ | "and" {AND }
+ | char
+   { let s = lexeme lexbuf in 
+     CHAR (if s.[1] = '\\' then escape s.[2] else s.[1])  }
+ 
+ | '\'' trigraph '\''
+   { let s = lexeme lexbuf in 
+     CHAR (trigraph s.[2] s.[3] s.[4]) }
+ 
+ | '\'' hexgraph '\''
+   { let s = lexeme lexbuf in 
+     CHAR (hexgraph s.[3] s.[4]) }
+ 
+ | '\'' unicodegraph_short '\''
+   { let s = lexeme lexbuf in 
+     CHAR (unicodegraph_short s.[3..6]) }
+ 
+ | '\'' unicodegraph_long '\''
+   { let s = lexeme lexbuf in 
+     match (unicodegraph_long s.[3..10]) with 
+     | None, c -> CHAR(c)
+     | Some _ , _ -> failwith "Unicode characters needing surrogate pairs are not yet supported by this tool" }
+ 
+ | '\'' '\\' ['A'-'Z'] ['a'-'z'] '\''
+   { let s = (lexeme lexbuf).[2..3] in 
+     UNICODE_CATEGORY (s) }
+     
+ | '{' { let p = lexbuf.StartPos in 
+         let buff = (new StringBuilder 100) in
+         // adjust the first line to get even indentation for all lines w.r.t. the left hand margin
+         buff.Append (String.replicate (lexbuf.StartPos.Column+1) " ") |> ignore;
+         code p buff lexbuf }
+
+ | '"' { string  lexbuf.StartPos (new StringBuilder 100) lexbuf }
+ 
+ | whitespace+  { token lexbuf }
+ | newline { newline lexbuf; token lexbuf }
+ | ident_start_char ident_char* { IDENT (lexeme lexbuf) }
+ | '|' { BAR }
+ | '.' { DOT }
+ | '+' { PLUS }
+ | '*' { STAR }
+ | '?' { QMARK }
+ | '=' { EQUALS }
+ | '[' { LBRACK }
+ | ']' { RBRACK }
+ | '(' { LPAREN }
+ | ')' { RPAREN }
+ | '_' { UNDERSCORE }
+ | '^' { HAT }
+ | '-' { DASH }
+ | "(*" { ignore(comment lexbuf.StartPos lexbuf); token lexbuf }
+ | "//" [^'\n''\r']* { token lexbuf }
+ | _ { unexpected_char lexbuf }     
+ | eof { EOF  }                                     
+and string p buff = parse
+ |  '\\' newline { newline lexbuf; string p buff lexbuf }
+ |  '\\' ( '"' | '\\' | '\'' | 'n' | 't' | 'b' | 'r')
+   { let _ = buff.Append (escape (lexeme lexbuf).[1]) in
+     string p buff lexbuf } 
+ | trigraph
+   { let s = lexeme lexbuf in 
+     let _ = buff.Append (trigraph s.[1] s.[2] s.[3]) in
+     string p buff lexbuf  }
+ | '"' { STRING (buff.ToString()) }
+ | newline { newline lexbuf; 
+             let _ = buff.Append System.Environment.NewLine in
+             string p buff lexbuf }
+ | (whitespace | letter | digit) +  
+   { let _ = buff.Append (lexeme lexbuf) in 
+     string p buff lexbuf }
+ | eof { failwith (Printf.sprintf "end of file in string started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))  }
+ | _ { let _ = buff.Append (lexeme lexbuf).[0] in
+       string p buff lexbuf }
+and code p buff = parse
+ | "}" { CODE (buff.ToString(), p) }
+ | "{" { let _ = buff.Append (lexeme lexbuf) in 
+         ignore(code p buff lexbuf); 
+         let _ = buff.Append "}" in
+         code p buff lexbuf }
+ | '\\' ('"' | '\\')
+   { let _ = buff.Append (lexeme lexbuf) in 
+     code p buff lexbuf } 
+ | "\"" { let _ = buff.Append (lexeme lexbuf) in 
+          ignore(codestring buff lexbuf); 
+          code p buff lexbuf }
+ | newline { newline lexbuf; 
+             let _ = buff.Append System.Environment.NewLine in
+             code p buff lexbuf }
+ | (whitespace | letter | digit) +  
+   { let _ = buff.Append (lexeme lexbuf) in 
+     code p buff lexbuf }
+ | "//" [^'\n''\r']*
+   { let _ = buff.Append (lexeme lexbuf) in
+     code p buff lexbuf }
+ | eof { EOF }
+ | _ { let _ = buff.Append (lexeme lexbuf).[0] in
+       code p buff lexbuf }
+
+and codestring buff = parse
+ |  '\\' ('"' | '\\')
+   { let _ = buff.Append (lexeme lexbuf) in 
+     codestring buff lexbuf } 
+ | '"' { let _ = buff.Append (lexeme lexbuf) in 
+         buff.ToString() }
+ | newline { newline lexbuf; 
+             let _ = buff.Append System.Environment.NewLine in
+             codestring buff lexbuf }
+ | (whitespace | letter | digit) +  
+   { let _ = buff.Append (lexeme lexbuf) in 
+     codestring buff lexbuf }
+ | eof { failwith "unterminated string in code" }
+ | _ { let _ = buff.Append (lexeme lexbuf).[0] in
+       codestring buff lexbuf }
+
+and comment p = parse
+ |  char { comment p lexbuf } 
+ | '"' { ignore(try string lexbuf.StartPos (new StringBuilder 100) lexbuf 
+                with Failure s -> failwith (s + "\n" + Printf.sprintf "error while processing string nested in comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))); 
+         comment p lexbuf }
+ | "(*" { ignore(try comment p lexbuf with Failure s -> failwith (s + "\n" + Printf.sprintf "error while processing nested comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))); 
+          comment p lexbuf }
+ | newline { newline lexbuf; comment p lexbuf }
+ | "*)" { () }
+ | eof { failwith (Printf.sprintf "end of file in comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))  }
+ | [^ '\'' '(' '*' '\n' '\r' '"' ')' ]+  { comment p lexbuf }
+ | _  { comment p lexbuf }
+
+               
diff --git a/src/FsLex/fslexpars.fsy b/src/FsLex/fslexpars.fsy
new file mode 100755
index 0000000..b0efec9
--- /dev/null
+++ b/src/FsLex/fslexpars.fsy
@@ -0,0 +1,55 @@
+%{
+(* (c) Microsoft Corporation 2005-2008.  *)
+
+open FSharp.PowerPack.FsLex
+open FSharp.PowerPack.FsLex.AST
+
+%} 
+
+%type <AST.Spec> spec
+%token <string> STRING IDENT
+%token <AST.Code> CODE 
+%token <char> CHAR
+%token <string> UNICODE_CATEGORY
+%token RULE PARSE LET  AND LPAREN RPAREN
+%token EOF BAR DOT PLUS STAR QMARK EQUALS UNDERSCORE LBRACK RBRACK HAT DASH
+%start spec
+%left BAR
+%left regexp_alt
+%left regexp_seq
+%nonassoc regexp_opt
+%nonassoc regexp_plus regexp_star
+%%      
+
+spec: codeopt Macros RULE Rules codeopt { { TopCode=$1;Macros=$2;Rules=$4;BottomCode=$5 } }
+codeopt: CODE { $1 } | { "", (parseState.ResultRange |> fst) }
+Macros:  { [] } | macro Macros { $1 :: $2 }
+macro: LET IDENT EQUALS regexp { ($2, $4) }
+Rules: rule AND Rules { $1 :: $3 } | rule { [$1] }
+rule: IDENT args EQUALS PARSE optbar clauses { ($1,$2,$6) }
+args: { [] } | IDENT args { $1 :: $2 } 
+optbar: { } | BAR { }
+clauses: clause BAR clauses {$1 :: $3 } | clause { [$1] }
+clause: regexp CODE { $1, $2 }
+regexp: 
+| CHAR { Inp(Alphabet(EncodeChar $1)) }
+| UNICODE_CATEGORY { Inp(UnicodeCategory $1) }
+| EOF { Inp(Alphabet(Eof)) }
+| UNDERSCORE { Inp Any }
+| STRING { Seq([ for n in 0 .. $1.Length - 1 -> Inp(Alphabet(EncodeChar $1.[n]))]) }
+| IDENT { Macro($1) }
+| regexp regexp %prec regexp_seq  { Seq[$1;$2] }
+| regexp PLUS %prec regexp_plus  { Seq[$1;Star $1] }
+| regexp STAR %prec regexp_star  { Star $1 }
+| regexp QMARK %prec regexp_opt  { Alt[Seq[];$1] }
+| regexp BAR regexp %prec regexp_alt  { Alt[$1;$3] }
+| LPAREN regexp RPAREN  { $2 }
+| LBRACK charset RBRACK   { Alt [ for c in $2 -> Inp(Alphabet(c)) ] }
+| LBRACK HAT charset RBRACK   { Inp(NotCharSet($3)) }
+
+charset: 
+ | CHAR { Set.singleton(EncodeChar $1) } 
+ | CHAR DASH CHAR { Set.ofSeq [ for c in $1 .. $3 -> EncodeChar c ] }
+ | charset charset { Set.union $1 $2  }
+
+
diff --git a/src/FsYacc/FsYacc.fsproj b/src/FsYacc/FsYacc.fsproj
new file mode 100755
index 0000000..390121c
--- /dev/null
+++ b/src/FsYacc/FsYacc.fsproj
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <TargetFrameworkProfile />
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <!-- Always use x86 emulation for this binary... -->
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProjectGuid>{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AssemblyName>FsYacc</AssemblyName>
+    <TreatWarningsAsErrors>
+    </TreatWarningsAsErrors>
+    <!-- 5310 tracks reenabling -->
+    <DefineConstants>INTERNALIZED_POWER_PACK;$(DefineConstants)</DefineConstants>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <FsLex Include="fsyacclex.fsl">
+      <OtherFlags>--lexlib Internal.Utilities.Text.Lexing</OtherFlags>
+    </FsLex>
+    <FsYacc Include="fsyaccpars.fsy">
+      <OtherFlags>--internal --module FSharp.PowerPack.FsYacc.Parser --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing</OtherFlags>
+    </FsYacc>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="assemblyinfo.fsyacc.exe.fs">
+      <Link>assemblyinfo.fsyacc.exe.fs</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Lexing.fsi">
+      <Link>lexing.fsi</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Lexing.fs">
+      <Link>lexing.fs</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Parsing.fsi">
+      <Link>parsing.fsi</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Parsing.fs">
+      <Link>parsing.fs</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Arg.fsi">
+      <Link>arg.fsi</Link>
+    </Compile>
+    <Compile Include="..\FSharp.PowerPack\Arg.fs">
+      <Link>arg.fs</Link>
+    </Compile>
+    <Compile Include="fsyaccast.fs" />
+    <Compile Include="fsyaccpars.fs" />
+    <Compile Include="fsyacclex.fs" />
+    <Compile Include="fsyacc.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="FSharp.Core" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(FSharpPowerPackSourcesRoot)\..\lkg\FSharp.PowerPack-$(LkgVersion)\bin\FSharp.PowerPack.targets" />
+</Project>
\ No newline at end of file
diff --git a/src/FsYacc/FsYacc.fsproj.vspscc b/src/FsYacc/FsYacc.fsproj.vspscc
new file mode 100755
index 0000000..feffdec
--- /dev/null
+++ b/src/FsYacc/FsYacc.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/src/FsYacc/assemblyinfo.fsyacc.exe.fs b/src/FsYacc/assemblyinfo.fsyacc.exe.fs
new file mode 100755
index 0000000..569be01
--- /dev/null
+++ b/src/FsYacc/assemblyinfo.fsyacc.exe.fs
@@ -0,0 +1,7 @@
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("fsyacc.exe")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("fsyacc.exe")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
diff --git a/src/FsYacc/fsyacc.fs b/src/FsYacc/fsyacc.fs
new file mode 100755
index 0000000..82807ad
--- /dev/null
+++ b/src/FsYacc/fsyacc.fs
@@ -0,0 +1,531 @@
+(* (c) Microsoft Corporation 2005-2008.  *)
+
+module internal FSharp.PowerPack.FsYacc.Driver 
+
+open System.IO 
+open System.Collections.Generic
+open Printf
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+
+open FSharp.PowerPack.FsYacc
+open FSharp.PowerPack.FsYacc.AST
+
+//------------------------------------------------------------------
+// This code is duplicated from Microsoft.FSharp.Compiler.UnicodeLexing
+
+type Lexbuf =  LexBuffer<char>
+
+/// Standard utility to create a Unicode LexBuffer
+///
+/// One small annoyance is that LexBuffers and not IDisposable. This means 
+/// we can't just return the LexBuffer object, since the file it wraps wouldn't
+/// get closed when we're finished with the LexBuffer. Hence we return the stream,
+/// the reader and the LexBuffer. The caller should dispose the first two when done.
+let UnicodeFileAsLexbuf (filename,codePage : int option) : FileStream * StreamReader * Lexbuf =
+    // Use the .NET functionality to auto-detect the unicode encoding
+    // It also uses Lexing.from_text_reader to present the bytes read to the lexer in UTF8 decoded form
+    let stream  = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read) 
+    let reader = 
+        match codePage with 
+        | None -> new  StreamReader(stream,true)
+        | Some n -> new  StreamReader(stream,System.Text.Encoding.GetEncoding(n)) 
+    let lexbuf = LexBuffer<char>.FromFunction(reader.Read) 
+    lexbuf.EndPos <- Position.FirstLine(filename);
+    stream, reader, lexbuf
+
+//------------------------------------------------------------------
+// This is the program proper
+
+let input = ref None
+let modname= ref None
+let internal_module = ref false
+let opens= ref []
+let out = ref None
+let tokenize = ref false
+let compat = ref false
+let log = ref false
+let light = ref None
+let inputCodePage = ref None
+let mutable lexlib = "Microsoft.FSharp.Text.Lexing"
+let mutable parslib = "Microsoft.FSharp.Text.Parsing"
+
+let usage =
+  [ ArgInfo("-o", ArgType.String (fun s -> out := Some s), "Name the output file.");
+    ArgInfo("-v", ArgType.Unit (fun () -> log := true), "Produce a listing file."); 
+    ArgInfo("--module", ArgType.String (fun s -> modname := Some s), "Define the F# module name to host the generated parser."); 
+    ArgInfo("--internal", ArgType.Unit (fun () -> internal_module := true), "Generate an internal module");
+    ArgInfo("--open", ArgType.String (fun s -> opens := !opens @ [s]), "Add the given module to the list of those to open in both the generated signature and implementation."); 
+    ArgInfo("--light", ArgType.Unit (fun () ->  light := Some true), "(ignored)");
+    ArgInfo("--light-off", ArgType.Unit (fun () ->  light := Some false), "Add #light \"off\" to the top of the generated file");
+    ArgInfo("--ml-compatibility", ArgType.Set compat, "Support the use of the global state from the 'Parsing' module in FSharp.PowerPack.dll."); 
+    ArgInfo("--tokens", ArgType.Set tokenize, "Simply tokenize the specification file itself."); 
+    ArgInfo("--lexlib", ArgType.String (fun s ->  lexlib <- s), "Specify the namespace for the implementation of the parser table interperter (default Microsoft.FSharp.Text.Parsing)");
+    ArgInfo("--parslib", ArgType.String (fun s ->  parslib <- s), "Specify the namespace for the implementation of the parser table interperter (default Microsoft.FSharp.Text.Parsing)");
+    ArgInfo("--codepage", ArgType.Int (fun i -> inputCodePage := Some i), "Assume input lexer specification file is encoded with the given codepage.");  ]
+
+let _ = ArgParser.Parse(usage,(fun x -> match !input with Some _ -> failwith "more than one input given" | None -> input := Some x),"fsyacc <filename>")
+
+let output_int (os: #TextWriter) (n:int) = os.Write(string n)
+
+let outputCodedUInt16 (os: #TextWriter)  (n:int) = 
+  os.Write n;
+  os.Write "us; ";
+
+let shiftFlag = 0x0000
+let reduceFlag = 0x4000
+let errorFlag = 0x8000
+let acceptFlag = 0xc000
+let actionMask = 0xc000
+
+let anyMarker = 0xffff
+
+let actionCoding action  =
+  match action with 
+  | Accept -> acceptFlag
+  | Shift n -> shiftFlag ||| n
+  | Reduce n -> reduceFlag ||| n
+  | Error -> errorFlag 
+
+let main() = 
+  let filename = (match !input with Some x -> x | None -> failwith "no input given") in 
+  let spec = 
+      let stream,reader,lexbuf = UnicodeFileAsLexbuf(filename, !inputCodePage) 
+      use stream = stream
+      use reader = reader
+
+      try 
+        if !tokenize then begin 
+          while true do 
+            printf "tokenize - getting one token";
+            let t = Lexer.token lexbuf in 
+            (*F# printf "tokenize - got %s" (Parser.token_to_string t); F#*)
+            if t = Parser.EOF then exit 0;
+          done;
+        end;
+    
+        Parser.spec Lexer.token lexbuf 
+      with e -> 
+         printf "%s(%d,%d): error: %s" filename lexbuf.StartPos.Line lexbuf.StartPos.Column e.Message;
+         exit 1  in
+
+  let has_extension (s:string) = 
+    (s.Length >= 1 && s.[s.Length - 1] = '.') 
+    || Path.HasExtension(s)
+
+  let chop_extension (s:string) =
+    if not (has_extension s) then invalidArg "s" "the file name does not have an extension"
+    Path.Combine (Path.GetDirectoryName s,Path.GetFileNameWithoutExtension(s)) 
+  
+  let checkSuffix (x:string) (y:string) = x.EndsWith(y)
+
+  let output = match !out with Some x -> x | _ -> chop_extension filename + (if checkSuffix filename ".mly" then ".ml" else ".fs") in
+  let outputi = match !out with Some x -> chop_extension x + (if checkSuffix x ".ml" then ".mli" else ".fsi") | _ -> chop_extension filename + (if checkSuffix filename ".mly" then ".mli" else ".fsi") in
+  let outputo = 
+      if !log then Some (match !out with Some x -> chop_extension x + ".fsyacc.output" | _ -> chop_extension filename + ".fsyacc.output") 
+      else None 
+
+  use os = (File.CreateText output :> TextWriter)
+  use osi = (File.CreateText outputi :> TextWriter)
+
+  let lineCountOutput = ref 0
+  let lineCountSignature = ref 0
+  let cos = (os,lineCountOutput)
+  let cosi = (osi,lineCountSignature)
+  let cprintf (os:TextWriter,lineCount) fmt = Printf.fprintf os fmt
+  let cprintfn (os:TextWriter,lineCount) fmt = Printf.kfprintf (fun () -> incr lineCount; os.WriteLine()) os fmt
+
+  let logf = 
+      match outputo with 
+      | None -> (fun f -> ())
+      | Some filename -> 
+          let oso = (File.CreateText filename :> TextWriter) 
+          (fun f -> f oso) 
+
+  logf (fun oso -> fprintfn oso "Output file describing compiled parser placed in %s and %s" output outputi);
+
+  printfn "building tables"; 
+  let spec1 = ProcessParserSpecAst spec 
+  let (prods,states, startStates,actionTable,immediateActionTable,gotoTable,endOfInputTerminalIdx,errorTerminalIdx,nonTerminals) = 
+      CompilerLalrParserSpec logf spec1 
+
+  let (code,pos) = spec.Header 
+  printfn "%d states" states.Length; 
+  printfn "%d nonterminals" gotoTable.[0].Length; 
+  printfn "%d terminals" actionTable.[0].Length; 
+  printfn "%d productions" prods.Length; 
+  printfn "#rows in action table: %d" actionTable.Length; 
+(*
+  printfn "#unique rows in action table: %d" (List.length (Array.foldBack (fun row acc -> insert (Array.to_list row) acc) actionTable [])); 
+  printfn "maximum #different actions per state: %d" (Array.foldBack (fun row acc ->max (List.length (List.foldBack insert (Array.to_list row) [])) acc) actionTable 0); 
+  printfn "average #different actions per state: %d" ((Array.foldBack (fun row acc -> (List.length (List.foldBack insert (Array.to_list row) [])) + acc) actionTable 0) / (Array.length states)); 
+*)
+
+  cprintfn cos "// Implementation file for parser generated by fsyacc";
+  cprintfn cosi "// Signature file for parser generated by fsyacc";
+
+  if (!light = Some(false)) || (!light = None && checkSuffix output ".ml") then
+      cprintfn cos "#light \"off\"";
+      cprintfn cosi "#light \"off\"";
+
+  match !modname with 
+  | None -> ()
+  | Some s -> 
+      match !internal_module with
+      | true ->
+          cprintfn cos "module internal %s" s;
+          cprintfn cosi "module internal %s" s;
+      | false ->
+          cprintfn cos "module %s" s;
+          cprintfn cosi "module %s" s;
+  
+  cprintfn cos "#nowarn \"64\";; // turn off warnings that type variables used in production annotations are instantiated to concrete type";
+
+  for s in !opens do
+      cprintfn cos "open %s" s;
+      cprintfn cosi "open %s" s;
+
+  cprintfn cos "open %s" lexlib;
+  cprintfn cos "open %s.ParseHelpers" parslib;
+  if !compat then 
+      cprintfn cos "open Microsoft.FSharp.Compatibility.OCaml.Parsing";
+
+  cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname;
+  cprintfn cos "%s" code;
+  lineCountOutput := !lineCountOutput + code.Replace("\r","").Split([| '\n' |]).Length;
+
+  cprintfn cos "# %d \"%s\"" !lineCountOutput output;
+  // Print the datatype for the tokens
+  cprintfn cos "// This type is the type of tokens accepted by the parser";
+  for out in [cos;cosi] do
+      cprintfn out "type token = ";
+      for id,typ in spec.Tokens do 
+          match typ with
+          | None -> cprintfn out "  | %s" id
+          | Some ty -> cprintfn out "  | %s of (%s)" id ty; 
+
+  // Print the datatype for the token names
+  cprintfn cos "// This type is used to give symbolic names to token indexes, useful for error messages";
+  for out in [cos;cosi] do
+      cprintfn out "type tokenId = ";
+      for id,typ in spec.Tokens do 
+          cprintfn out "    | TOKEN_%s" id;
+      cprintfn out "    | TOKEN_end_of_input";
+      cprintfn out "    | TOKEN_error";
+
+  cprintfn cos "// This type is used to give symbolic names to token indexes, useful for error messages";
+  for out in [cos;cosi] do
+      cprintfn out "type nonTerminalId = ";
+      for nt in nonTerminals do 
+          cprintfn out "    | NONTERM_%s" nt;
+
+  cprintfn cos "";
+  cprintfn cos "// This function maps tokens to integers indexes";
+  cprintfn cos "let tagOfToken (t:token) = ";
+  cprintfn cos "  match t with";
+  spec.Tokens |> List.iteri (fun i (id,typ) -> 
+      cprintfn cos "  | %s %s -> %d " id (match typ with Some _ -> "_" | None -> "") i);
+  cprintfn cosi "/// This function maps integers indexes to symbolic token ids";
+  cprintfn cosi "val tagOfToken: token -> int";
+
+  cprintfn cos "";
+  cprintfn cos "// This function maps integers indexes to symbolic token ids";
+  cprintfn cos "let tokenTagToTokenId (tokenIdx:int) = ";
+  cprintfn cos "  match tokenIdx with";
+  spec.Tokens |> List.iteri (fun i (id,typ) -> 
+      cprintfn cos "  | %d -> TOKEN_%s " i id)
+  cprintfn cos "  | %d -> TOKEN_end_of_input" endOfInputTerminalIdx;
+  cprintfn cos "  | %d -> TOKEN_error" errorTerminalIdx;
+  cprintfn cos "  | _ -> failwith \"tokenTagToTokenId: bad token\""
+
+  cprintfn cosi "";
+  cprintfn cosi "/// This function maps integers indexes to symbolic token ids";
+  cprintfn cosi "val tokenTagToTokenId: int -> tokenId";
+
+  cprintfn cos "";
+  cprintfn cos "/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production";
+  cprintfn cos "let prodIdxToNonTerminal (prodIdx:int) = ";
+  cprintfn cos "  match prodIdx with";
+  prods |> Array.iteri (fun i (nt,ntIdx,syms,code) -> 
+      cprintfn cos "    | %d -> NONTERM_%s " i nt);
+  cprintfn cos "    | _ -> failwith \"prodIdxToNonTerminal: bad production index\""
+
+  cprintfn cosi "";
+  cprintfn cosi "/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production";
+  cprintfn cosi "val prodIdxToNonTerminal: int -> nonTerminalId";
+
+  cprintfn cos "";
+  cprintfn cos "let _fsyacc_endOfInputTag = %d " endOfInputTerminalIdx;
+  cprintfn cos "let _fsyacc_tagOfErrorTerminal = %d" errorTerminalIdx;
+  cprintfn cos "";
+  cprintfn cos "// This function gets the name of a token as a string";
+  cprintfn cos "let token_to_string (t:token) = ";
+  cprintfn cos "  match t with ";
+  spec.Tokens |> List.iteri (fun i (id,typ) -> 
+      cprintfn cos "  | %s %s -> \"%s\" " id (match typ with Some _ -> "_" | None -> "") id);
+
+  cprintfn cosi "";
+  cprintfn cosi "/// This function gets the name of a token as a string";
+  cprintfn cosi "val token_to_string: token -> string";
+
+  cprintfn cos "";
+  cprintfn cos "// This function gets the data carried by a token as an object";
+  cprintfn cos "let _fsyacc_dataOfToken (t:token) = ";
+  cprintfn cos "  match t with ";
+
+  for (id,typ) in spec.Tokens do
+      cprintfn cos "  | %s %s -> %s " 
+        id
+        (match typ with Some _ -> "_fsyacc_x" | None -> "")
+        (match typ with Some _ -> "Microsoft.FSharp.Core.Operators.box _fsyacc_x" | None -> "(null : System.Object)")
+
+  let tychar = "'cty" 
+
+  for (key,_) in spec.Types |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1)  do
+        failwithf "%s is given multiple %%type declarations" key;
+    
+  for (key,_) in spec.Tokens |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1)  do
+        failwithf "%s is given %%token declarations" key
+    
+  let types = Map.ofList spec.Types 
+  let tokens = Map.ofList spec.Tokens 
+  
+  let nStates = states.Length 
+  begin 
+      cprintf cos "let _fsyacc_gotos = [| " ;
+      let numGotoNonTerminals = gotoTable.[0].Length 
+      let gotoIndexes = Array.create numGotoNonTerminals 0 
+      let gotoTableCurrIndex = ref 0 in 
+      for j = 0 to numGotoNonTerminals-1 do  
+          gotoIndexes.[j] <- !gotoTableCurrIndex;
+
+          (* Count the number of entries in the association table. *)
+          let count = ref 0 in 
+          for i = 0 to nStates - 1 do 
+            let goto = gotoTable.[i].[j] 
+            match goto with 
+            | None -> ()
+            | Some _ -> incr count
+   
+          (* Write the head of the table (i.e. the number of entries and the default value) *)
+          gotoTableCurrIndex := !gotoTableCurrIndex + 1;
+          outputCodedUInt16 os !count;
+          outputCodedUInt16 os anyMarker;
+          
+          (* Write the pairs of entries in incremental order by key *)
+          (* This lets us implement the lookup by a binary chop. *)
+          for i = 0 to nStates - 1 do 
+            let goto = gotoTable.[i].[j] 
+            match goto with 
+            | None -> ()
+            | Some n -> 
+                gotoTableCurrIndex := !gotoTableCurrIndex + 1;
+                outputCodedUInt16 os i;
+                outputCodedUInt16 os n;
+      cprintfn cos "|]" ;
+      (* Output offsets into gotos table where the gotos for a particular nonterminal begin *)
+      cprintf cos "let _fsyacc_sparseGotoTableRowOffsets = [|" ;
+      for j = 0 to numGotoNonTerminals-1 do  
+          outputCodedUInt16 os gotoIndexes.[j];
+      cprintfn cos "|]" ;
+  end;
+
+  begin 
+      cprintf cos "let _fsyacc_stateToProdIdxsTableElements = [| " ;
+      let indexes = Array.create states.Length 0 
+      let currIndex = ref 0 
+      for j = 0 to states.Length - 1 do
+          let state = states.[j]
+          indexes.[j] <- !currIndex;
+
+          (* Write the head of the table (i.e. the number of entries) *)
+          outputCodedUInt16 os state.Length;
+          currIndex := !currIndex + state.Length + 1;
+          
+          (* Write the pairs of entries in incremental order by key *)
+          (* This lets us implement the lookup by a binary chop. *)
+          for prodIdx in state do
+                outputCodedUInt16 os prodIdx;
+      cprintfn cos "|]" ;
+      (* Output offsets into gotos table where the gotos for a particular nonterminal begin *)
+      cprintf cos "let _fsyacc_stateToProdIdxsTableRowOffsets = [|" ;
+      for idx in indexes do 
+          outputCodedUInt16 os idx;
+      cprintfn cos "|]" ;
+  end;
+
+  begin 
+    let numActionRows = (Array.length actionTable) 
+    let maxActionColumns = Array.length actionTable.[0] 
+    cprintfn cos "let _fsyacc_action_rows = %d" numActionRows;
+    cprintf cos "let _fsyacc_actionTableElements = [|" ;
+    let actionIndexes = Array.create numActionRows 0 
+    
+    let actionTableCurrIndex = ref 0 
+    for i = 0 to nStates-1 do 
+        actionIndexes.[i] <- !actionTableCurrIndex;
+        let actions = actionTable.[i] 
+        let terminalsByAction = new Dictionary<_,int list>(10) 
+        let countPerAction = new Dictionary<_,_>(10) 
+        for terminal = 0 to actions.Length - 1 do  
+              let action = snd actions.[terminal] 
+              if terminalsByAction.ContainsKey action then 
+                  terminalsByAction.[action] <- terminal :: terminalsByAction.[action] ;
+              else
+                  terminalsByAction.[action] <- [terminal];
+              if countPerAction.ContainsKey action then 
+                countPerAction.[action] <- countPerAction.[action]+1
+              else 
+                countPerAction.[action] <- 1
+
+        let mostCommonAction = 
+            let mostCommon = ref Error 
+            let max = ref 0 
+            for (KeyValue(x,y)) in countPerAction do 
+                if y > !max then (mostCommon := x; max := y)
+            !mostCommon 
+
+        (* Count the number of entries in the association table. *)
+        let count = ref 0 
+        for (KeyValue(action,terminals)) in terminalsByAction do 
+            for terminals  in terminals do 
+               if action <> mostCommonAction then  
+                   incr count;
+        
+        (* Write the head of the table (i.e. the number of entries and the default value) *)
+        actionTableCurrIndex := !actionTableCurrIndex + 1;
+        outputCodedUInt16 os !count;
+        outputCodedUInt16 os (actionCoding mostCommonAction);
+        
+        (* Write the pairs of entries in incremental order by key *)
+        (* This lets us implement the lookup by a binary chop. *)
+        for terminal = 0 to Array.length actions-1 do  
+            let action = snd actions.[terminal] in 
+            if action <> mostCommonAction then  (
+                actionTableCurrIndex := !actionTableCurrIndex + 1;
+                outputCodedUInt16 os terminal;
+                outputCodedUInt16 os (actionCoding action);
+            );
+    cprintfn cos "|]" ;
+    (* Output offsets into actions table where the actions for a particular nonterminal begin *)
+    cprintf cos "let _fsyacc_actionTableRowOffsets = [|" ;
+    for j = 0 to numActionRows-1 do  
+        cprintf cos "%a" outputCodedUInt16 actionIndexes.[j];
+    cprintfn cos "|]" ;
+
+  end;
+  begin 
+      cprintf cos "let _fsyacc_reductionSymbolCounts = [|" ;
+      for nt,ntIdx,syms,code in prods do 
+          cprintf cos "%a" outputCodedUInt16 (List.length syms);
+      cprintfn cos "|]" ;
+  end;
+  begin 
+      cprintf cos "let _fsyacc_productionToNonTerminalTable = [|" ;
+      for nt,ntIdx,syms,code in prods do 
+          cprintf cos "%a" outputCodedUInt16 ntIdx;
+      cprintfn cos "|]" ;
+  end;
+  begin 
+      cprintf cos "let _fsyacc_immediateActions = [|" ;
+      for prodIdx in immediateActionTable do 
+          match prodIdx with
+            | None     -> cprintf cos "%a" outputCodedUInt16 anyMarker (* NONE REP *)
+            | Some act -> cprintf cos "%a" outputCodedUInt16 (actionCoding act)
+      cprintfn cos "|]" ;
+  end;
+  
+  let getType nt = if types.ContainsKey nt then  types.[nt] else "'"+nt 
+  begin 
+      cprintf cos "let _fsyacc_reductions ()  =" ;
+      cprintfn cos "    [| " ;
+      for nt,ntIdx,syms,code in prods do 
+          cprintfn cos "# %d \"%s\"" !lineCountOutput output;
+          cprintfn cos "        (fun (parseState : %s.IParseState) ->"  parslib
+          if !compat then 
+              cprintfn cos "            Parsing.set_parse_state parseState;"
+          syms |> List.iteri (fun i sym -> 
+              let tyopt = 
+                  match sym with
+                  | Terminal t -> 
+                      if tokens.ContainsKey t then 
+                        tokens.[t]
+                      else None
+                  | NonTerminal nt -> Some (getType nt) 
+              match tyopt with 
+              | Some ty -> cprintfn cos "            let _%d = (let data = parseState.GetInput(%d) in (Microsoft.FSharp.Core.Operators.unbox data : %s)) in" (i+1) (i+1) ty
+              | None -> ())
+          cprintfn cos "            Microsoft.FSharp.Core.Operators.box" 
+          cprintfn cos "                (";
+          cprintfn cos "                   (";
+          match code with 
+          | Some (_,pos) -> cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname
+          | None -> ()
+          match code with 
+          | Some (code,_) -> 
+              let dollar = ref false in 
+              let c = code |> String.collect (fun c -> 
+                  if not !dollar && c = '$' then (dollar := true; "")
+                  elif !dollar && c >= '0' && c <= '9' then (dollar := false; "_"+new System.String(c,1))
+                  elif !dollar then (dollar := false; "$"+new System.String(c,1))
+                  else new System.String(c,1))
+              let lines = c.Split([| '\r'; '\n' |], System.StringSplitOptions.RemoveEmptyEntries);
+              for line in lines do 
+                  cprintfn cos "                     %s" line;
+              if !dollar then os.Write '$'
+          | None -> 
+              cprintfn cos "                      raise (%s.Accept(Microsoft.FSharp.Core.Operators.box _1))" parslib
+          cprintfn cos "                   )";
+          // Place the line count back for the type constraint
+          match code with 
+          | Some (_,pos) -> cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname
+          | None -> ()
+          cprintfn cos "                 : %s));" (if types.ContainsKey nt then  types.[nt] else "'"+nt);
+      done;
+      cprintfn cos "|]" ;
+  end;
+  cprintfn cos "# %d \"%s\"" !lineCountOutput output;
+  cprintfn cos "let tables () : %s.Tables<_> = " parslib
+  cprintfn cos "  { reductions= _fsyacc_reductions ();"
+  cprintfn cos "    endOfInputTag = _fsyacc_endOfInputTag;"
+  cprintfn cos "    tagOfToken = tagOfToken;"
+  cprintfn cos "    dataOfToken = _fsyacc_dataOfToken; "
+  cprintfn cos "    actionTableElements = _fsyacc_actionTableElements;"
+  cprintfn cos "    actionTableRowOffsets = _fsyacc_actionTableRowOffsets;"
+  cprintfn cos "    stateToProdIdxsTableElements = _fsyacc_stateToProdIdxsTableElements;"
+  cprintfn cos "    stateToProdIdxsTableRowOffsets = _fsyacc_stateToProdIdxsTableRowOffsets;"
+  cprintfn cos "    reductionSymbolCounts = _fsyacc_reductionSymbolCounts;"
+  cprintfn cos "    immediateActions = _fsyacc_immediateActions;"
+  cprintfn cos "    gotos = _fsyacc_gotos;"
+  cprintfn cos "    sparseGotoTableRowOffsets = _fsyacc_sparseGotoTableRowOffsets;"
+  cprintfn cos "    tagOfErrorTerminal = _fsyacc_tagOfErrorTerminal;"
+  cprintfn cos "    parseError = (fun (ctxt:%s.ParseErrorContext<_>) -> " parslib
+  cprintfn cos "                              match parse_error_rich with "
+  cprintfn cos "                              | Some f -> f ctxt"
+  cprintfn cos "                              | None -> parse_error ctxt.Message);"
+  
+  cprintfn cos "    numTerminals = %d;" (Array.length actionTable.[0]);
+  cprintfn cos "    productionToNonTerminalTable = _fsyacc_productionToNonTerminalTable  }"
+  cprintfn cos "let engine lexer lexbuf startState = (tables ()).Interpret(lexer, lexbuf, startState)"                                                                                                         
+
+  for (id,startState) in List.zip spec.StartSymbols startStates do
+        if not (types.ContainsKey id) then 
+          failwith ("a %type declaration is required for for start token "+id);
+        let ty = types.[id] in 
+        cprintfn cos "let %s lexer lexbuf : %s =" id ty;
+        cprintfn cos "    Microsoft.FSharp.Core.Operators.unbox ((tables ()).Interpret(lexer, lexbuf, %d))" startState
+
+  for id in spec.StartSymbols do
+      if not (types.ContainsKey id) then 
+        failwith ("a %type declaration is required for start token "+id);
+      let ty = types.[id] in 
+      cprintfn cosi "val %s : (%s.LexBuffer<%s> -> token) -> %s.LexBuffer<%s> -> (%s) " id lexlib tychar lexlib tychar ty;
+
+  logf (fun oso -> oso.Close())
+
+let _ = 
+    try main()
+    with e -> 
+      printf "FSYACC: error FSY000: %s" (match e with Failure s -> s | e -> e.Message);
+      exit 1
+
diff --git a/src/FsYacc/fsyaccast.fs b/src/FsYacc/fsyaccast.fs
new file mode 100755
index 0000000..151c085
--- /dev/null
+++ b/src/FsYacc/fsyaccast.fs
@@ -0,0 +1,965 @@
+// (c) Microsoft Corporation 2005-2007.
+
+module internal FSharp.PowerPack.FsYacc.AST
+
+#nowarn "62" // This construct is for ML compatibility.
+
+
+open System
+open System.Collections.Generic
+open Printf
+open Microsoft.FSharp.Collections
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+
+/// An active pattern that should be in the F# standard library
+let (|KeyValue|) (kvp:KeyValuePair<_,_>) = kvp.Key,kvp.Value
+
+
+type Identifier = string
+type Code = string * Position
+
+type ParserSpec= 
+    { Header         : Code;
+      Tokens         : (Identifier * string option) list;
+      Types          : (Identifier * string) list;
+      Associativities: (Identifier * Associativity) list list;
+      StartSymbols   : Identifier list;
+      Rules          : (Identifier * Rule list) list }
+      
+and Rule = Rule of Identifier list * Identifier option * Code option
+and Associativity = LeftAssoc | RightAssoc | NonAssoc
+
+type Terminal = string
+type NonTerminal = string
+type Symbol = Terminal of Terminal | NonTerminal of NonTerminal
+type Symbols = Symbol list
+
+
+//---------------------------------------------------------------------
+// Output Raw Parser Spec AST
+
+let StringOfSym sym = match sym with Terminal s -> "'" ^ s ^ "'" | NonTerminal s -> s
+
+let OutputSym os sym = fprintf os "%s" (StringOfSym sym)
+
+let OutputSyms os syms =
+    fprintf os "%s" (String.Join(" ",Array.map StringOfSym syms))
+
+let OutputTerminalSet os (tset:string seq)  =
+    fprintf os "%s" (String.Join(";", tset |> Seq.toArray))
+
+let OutputAssoc os p = 
+    match p with 
+    | LeftAssoc -> fprintf os "left"
+    | RightAssoc -> fprintf os "right"
+    | NonAssoc -> fprintf os "nonassoc"
+
+
+//---------------------------------------------------------------------
+// PreProcess Raw Parser Spec AST
+
+type PrecedenceInfo = 
+    | ExplicitPrec of Associativity * int 
+    | NoPrecedence
+      
+type Production = Production of NonTerminal * PrecedenceInfo * Symbols * Code option
+
+type ProcessedParserSpec = 
+    { Terminals: (Terminal * PrecedenceInfo) list;
+      NonTerminals: NonTerminal list;
+      Productions: Production list;
+      StartSymbols: NonTerminal list }
+
+
+let ProcessParserSpecAst (spec: ParserSpec) = 
+    let explicitPrecInfo = 
+        spec.Associativities 
+        |> List.mapi (fun n precSpecs -> precSpecs |> List.map (fun (precSym, assoc) -> precSym,ExplicitPrec (assoc, 10000 - n)))
+        |> List.concat
+    
+    for (key,_) in explicitPrecInfo |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1)  do
+        failwithf "%s is given two associativities" key
+    
+    let explicitPrecInfo = 
+        explicitPrecInfo |> Map.ofList
+
+    let implicitSymPrecInfo = NoPrecedence
+    let terminals = List.map fst spec.Tokens @ ["error"]in 
+    let terminalSet = Set.ofList terminals
+    let IsTerminal z = terminalSet.Contains(z)
+    let prec_of_terminal sym implicitPrecInfo = 
+       if explicitPrecInfo.ContainsKey(sym) then explicitPrecInfo.[sym]
+       else match implicitPrecInfo with Some x -> x | None -> implicitSymPrecInfo
+       
+    let mkSym s = if IsTerminal s then Terminal s else NonTerminal s
+    let prods =  
+        spec.Rules |> List.mapi (fun i (nonterm,rules) -> 
+            rules |> List.mapi (fun j (Rule(syms,precsym,code)) -> 
+                let precInfo = 
+                    let precsym = List.foldBack (fun x acc -> match acc with Some _ -> acc | None -> match x with z when IsTerminal z -> Some z | _ -> acc) syms precsym
+                    let implicitPrecInfo = NoPrecedence
+                    match precsym with 
+                    | None -> implicitPrecInfo 
+                    | Some sym -> if explicitPrecInfo.ContainsKey(sym) then explicitPrecInfo.[sym] else implicitPrecInfo
+                Production(nonterm, precInfo, List.map mkSym syms, code)))
+         |> List.concat
+    let nonTerminals = List.map fst spec.Rules
+    let nonTerminalSet = Set.ofList nonTerminals
+    let checkNonTerminal nt =  
+        if nt <> "error" && not (nonTerminalSet.Contains(nt)) then 
+            failwith (sprintf "NonTerminal '%s' has no productions" nt)
+
+    for (Production(nt,_,syms,_)) in prods do
+        for sym in syms do 
+           match sym with 
+           | NonTerminal nt -> 
+               checkNonTerminal nt 
+           | Terminal t ->  
+               if not (IsTerminal t) then failwith (sprintf "token %s is not declared" t)
+           
+    if spec.StartSymbols= [] then (failwith "at least one %start declaration is required\n");
+
+    for (nt,_) in spec.Types do 
+        checkNonTerminal nt;
+
+    let terminals = terminals |> List.map (fun t -> (t,prec_of_terminal t None)) 
+
+    { Terminals=terminals;
+      NonTerminals=nonTerminals;
+      Productions=prods;
+      StartSymbols=spec.StartSymbols }
+
+
+//-------------------------------------------------
+// Process LALR(1) grammars to tables
+
+type ProductionIndex = int
+type ProdictionDotIndex = int
+
+/// Represent (ProductionIndex,ProdictionDotIndex) as one integer 
+type Item0 = uint32  
+
+let mkItem0 (prodIdx,dotIdx) : Item0 = (uint32 prodIdx <<< 16) ||| uint32 dotIdx
+let prodIdx_of_item0 (item0:Item0) = int32 (item0 >>> 16)
+let dotIdx_of_item0 (item0:Item0) = int32 (item0 &&& 0xFFFFu)
+
+/// Part of the output of CompilerLalrParserSpec
+type Action = 
+  | Shift of int
+  | Reduce of ProductionIndex
+  | Accept
+  | Error
+    
+let outputPrecInfo os p = 
+    match p with 
+    | ExplicitPrec (assoc,n) -> fprintf os "explicit %a %d" OutputAssoc assoc n
+    | NoPrecedence  -> fprintf os "noprec"
+
+
+/// LR(0) kernels
+type Kernel = Set<Item0>
+
+/// Indexes of LR(0) kernels in the KernelTable
+type KernelIdx = int
+
+/// Indexes in the TerminalTable and NonTerminalTable
+type TerminalIndex = int
+type NonTerminalIndex = int
+
+/// Representation of Symbols.
+/// Ideally would be declared as 
+///    type SymbolIndex = PTerminal of TerminalIndex | PNonTerminal of NonTerminalIndex
+/// but for performance reasons we embed as a simple integer (saves ~10%)
+///
+/// We use an active pattern to reverse the embedding.
+type SymbolIndex = int
+let PTerminal(i:TerminalIndex) : SymbolIndex = -i-1
+let PNonTerminal(i:NonTerminalIndex) : SymbolIndex = i
+let (|PTerminal|PNonTerminal|) x = if x < 0 then PTerminal (-(x+1)) else PNonTerminal x
+
+type SymbolIndexes = SymbolIndex list
+
+/// Indexes in the LookaheadTable, SpontaneousTable, PropagateTable
+/// Embed in a single integer, since these are faster
+/// keys for the dictionary hash tables
+///
+/// Logically:
+///
+///   type KernelItemIndex = KernelItemIdx of KernelIdx * Item0
+type KernelItemIndex = int64
+let KernelItemIdx (i1,i2) = ((int64 i1) <<< 32) ||| int64 i2
+
+
+/// Indexes into the memoizing table for the Goto computations
+/// Embed in a single integer, since these are faster
+/// keys for the dictionary hash tables
+///
+/// Logically:
+///
+///   type GotoItemIndex = GotoItemIdx of KernelIdx * SymbolIndex
+type GotoItemIndex = uint64
+let GotoItemIdx (i1:KernelIdx,i2:SymbolIndex) = (uint64 (uint32 i1) <<< 32) ||| uint64 (uint32 i2)
+let (|GotoItemIdx|) (i64:uint64) = int32 ((i64 >>> 32) &&& 0xFFFFFFFFUL), int32 (i64 &&& 0xFFFFFFFFUL)
+
+/// Create a work list and loop until it is exhausted, calling a worker function for
+/// each element. Pass a function to queue additional work on the work list 
+/// to the worker function
+let ProcessWorkList start f =
+    let work = ref (start : 'a list)
+    let queueWork = (fun x -> work := x :: !work)
+    let rec loop() = 
+        match !work with 
+        | [] -> ()
+        | x::t -> 
+            work := t; 
+            f queueWork x;
+            loop()
+    loop()
+
+/// A standard utility to compute a least fixed point of a set under a generative computation
+let LeastFixedPoint f set = 
+    let acc = ref set
+    ProcessWorkList (Set.toList set) (fun queueWork item ->
+          f(item) |> List.iter (fun i2 -> if not (Set.contains i2 !acc) then (acc := Set.add i2 !acc; queueWork i2)) )
+    !acc
+
+/// A general standard memoization utility. Be sure to apply to only one (function) argument to build the
+/// residue function!
+let Memoize f = 
+    let t = new Dictionary<_,_>(1000)
+    fun x -> 
+        let ok,v = t.TryGetValue(x) 
+        if ok then v else let res = f x in t.[x] <- res; res 
+
+/// A standard utility to create a dictionary from a list of pairs
+let CreateDictionary xs = 
+    let dict = new Dictionary<_,_>()
+    for x,y in xs do dict.Add(x,y)
+    dict
+
+/// Allocate indexes for each non-terminal
+type NonTerminalTable(nonTerminals:NonTerminal list) = 
+    let nonterminalsWithIdxs = List.mapi (fun (i:NonTerminalIndex) n -> (i,n)) nonTerminals
+    let nonterminalIdxs = List.map fst nonterminalsWithIdxs
+    let a = Array.ofList nonTerminals
+    let b = CreateDictionary [ for i,x in nonterminalsWithIdxs -> x,i ];
+    member table.OfIndex(i) = a.[i]
+    member table.ToIndex(i) = b.[i]
+    member table.Indexes = nonterminalIdxs
+
+/// Allocate indexes for each terminal
+type TerminalTable(terminals:(Terminal * PrecedenceInfo) list) = 
+    let terminalsWithIdxs = List.mapi (fun i (t,_) -> (i,t)) terminals
+    let terminalIdxs = List.map fst terminalsWithIdxs
+    let a = Array.ofList (List.map fst terminals)
+    let b = Array.ofList (List.map snd terminals)
+    let c = CreateDictionary [ for i,x in terminalsWithIdxs -> x,i ]
+
+    member table.OfIndex(i) = a.[i]
+    member table.PrecInfoOfIndex(i) = b.[i]
+    member table.ToIndex(i) = c.[i]
+    member table.Indexes = terminalIdxs
+
+/// Allocate indexes for each production
+type ProductionTable(ntTab:NonTerminalTable, termTab:TerminalTable, nonTerminals:string list, prods: Production list) =
+    let prodsWithIdxs = List.mapi (fun i n -> (i,n)) prods
+    let a =  
+        prodsWithIdxs
+        |> List.map(fun (_,Production(_,_,syms,_)) -> 
+              syms 
+              |> Array.ofList  
+              |> Array.map (function 
+                            | Terminal t -> PTerminal (termTab.ToIndex t) 
+                            | NonTerminal nt -> PNonTerminal (ntTab.ToIndex nt )) )
+        |> Array.ofList
+    let b = Array.ofList (List.map (fun (_,Production(nt,_,_,_)) -> ntTab.ToIndex nt) prodsWithIdxs)
+    let c = Array.ofList (List.map (fun (_,Production(_,prec,_,_)) -> prec) prodsWithIdxs)
+    let productions = 
+        nonTerminals
+        |> List.map(fun nt -> (ntTab.ToIndex nt, List.choose (fun (i,Production(nt2,prec,syms,_)) -> if nt2=nt then Some i else None) prodsWithIdxs))
+        |> CreateDictionary
+
+    member prodTab.Symbols(i) = a.[i]
+    member prodTab.NonTerminal(i) = b.[i]
+    member prodTab.Precedence(i) = c.[i]
+    member prodTab.Symbol i n = 
+        let syms = prodTab.Symbols i
+        if n >= syms.Length then None else Some (syms.[n])
+    member prodTab.Productions = productions
+
+/// A mutable table maping kernels to sets of lookahead tokens
+type LookaheadTable() = 
+    let t = new Dictionary<KernelItemIndex,Set<TerminalIndex>>()
+    member table.Add(x,y) = 
+        let prev = if t.ContainsKey(x) then t.[x] else Set.empty 
+        t.[x] <- prev.Add(y)
+    member table.Contains(x,y) = t.ContainsKey(x) && t.[x].Contains(y)
+    member table.GetLookaheads(idx:KernelItemIndex) = 
+        let ok,v = t.TryGetValue(idx)  
+        if ok then v else Set.empty
+    member table.Count = t |> Seq.fold(fun acc (KeyValue(_,v)) -> v.Count+acc) 0
+
+/// A mutable table giving an index to each LR(0) kernel. Kernels are referred to only by index.
+type KernelTable(kernels) =
+    // Give an index to each LR(0) kernel, and from now on refer to them only by index 
+    // Also develop "kernelItemIdx" to refer to individual items within a kernel 
+    let kernelsAndIdxs = List.mapi (fun i x -> (i,x)) kernels
+    let kernelIdxs = List.map fst kernelsAndIdxs
+    let toIdxMap = Map.ofList [ for i,x in kernelsAndIdxs -> x,i ]
+    let ofIdxMap = Array.ofList kernels
+    member t.Indexes = kernelIdxs
+    member t.Index(kernel) = toIdxMap.[kernel]
+    member t.Kernel(i) = ofIdxMap.[i]
+
+/// Hold the results of cpmuting the LALR(1) closure of an LR(0) kernel
+type Closure1Table() = 
+    let t = new Dictionary<Item0,HashSet<TerminalIndex>>()
+    member table.Add(a,b) = 
+        if not (t.ContainsKey(a)) then t.[a] <- new HashSet<_>(HashIdentity.Structural)
+        t.[a].Add(b)
+    member table.Count  = t.Count
+    member table.IEnumerable = (t :> seq<_>)
+    member table.Contains(a,b) = t.ContainsKey(a) && t.[a].Contains(b)
+
+/// A mutable table giving a lookahead set Set<Terminal> for each kernel. The terminals represent the
+/// "spontaneous" items for the kernel. TODO: document this more w.r.t. the Dragon book.
+type SpontaneousTable() = 
+    let t = new Dictionary<KernelItemIndex,HashSet<TerminalIndex>>()
+    member table.Add(a,b) = 
+        if not (t.ContainsKey(a)) then t.[a] <- new HashSet<_>(HashIdentity.Structural)
+        t.[a].Add(b)
+    member table.Count  = t.Count
+    member table.IEnumerable = (t :> seq<_>)
+
+/// A mutable table giving a Set<KernelItemIndex> for each kernel. The kernels represent the
+/// "propagate" items for the kernel. TODO: document this more w.r.t. the Dragon book.
+type PropagateTable() = 
+    let t = new Dictionary<KernelItemIndex,HashSet<KernelItemIndex>>()
+    member table.Add(a,b) = 
+        if not (t.ContainsKey(a)) then t.[a] <- new HashSet<KernelItemIndex>(HashIdentity.Structural)
+        t.[a].Add(b)
+    member table.Item 
+      with get(a) = 
+        let ok,v = t.TryGetValue(a) 
+        if ok then v :> seq<_> else Seq.empty
+    member table.Count  = t.Count
+
+
+/// Compile a pre-processed LALR parser spec to tables following the Dragon book algorithm
+let CompilerLalrParserSpec logf (spec : ProcessedParserSpec) =
+    let stopWatch = new System.Diagnostics.Stopwatch()
+    let reportTime() = printfn "time: %A" stopWatch.Elapsed; stopWatch.Reset(); stopWatch.Start()
+    stopWatch.Start()
+
+    // Augment the grammar 
+    let fakeStartNonTerminals = spec.StartSymbols |> List.map(fun nt -> "_start"^nt) 
+    let nonTerminals = fakeStartNonTerminals at spec.NonTerminals
+    let endOfInputTerminal = "$$"
+    let dummyLookahead = "#"
+    let dummyPrec = NoPrecedence
+    let terminals = spec.Terminals @ [(dummyLookahead,dummyPrec); (endOfInputTerminal,dummyPrec)]
+    let prods = List.map2 (fun a b -> Production(a, dummyPrec,[NonTerminal b],None)) fakeStartNonTerminals spec.StartSymbols @ spec.Productions
+    let startNonTerminalIdx_to_prodIdx (i:int) = i
+
+    // Build indexed tables 
+    let ntTab = NonTerminalTable(nonTerminals)
+    let termTab = TerminalTable(terminals)
+    let prodTab = ProductionTable(ntTab,termTab,nonTerminals,prods)
+    let dummyLookaheadIdx = termTab.ToIndex dummyLookahead
+    let endOfInputTerminalIdx = termTab.ToIndex endOfInputTerminal
+
+
+    // printf "terminalPrecInfo(ELSE) = %a\n" outputPrecInfo (termTab.PrecInfoOfIndex (termTab.ToIndex "ELSE"));
+
+    let errorTerminalIdx = termTab.ToIndex "error"
+
+    // Compute the FIRST function
+    printf  "computing first function..."; stdout.Flush();
+
+    let computedFirstTable = 
+        let seed = 
+            Map.ofList
+             [ for term in termTab.Indexes do yield (PTerminal(term),Set.singleton (Some term))
+               for nonTerm in ntTab.Indexes do 
+                  yield 
+                    (PNonTerminal nonTerm, 
+                     List.foldBack 
+                       (fun prodIdx acc -> match prodTab.Symbol prodIdx 0 with None -> Set.add None acc | Some _ -> acc) 
+                       prodTab.Productions.[nonTerm] 
+                       Set.empty) ]
+                 
+        let add changed ss (x,y) = 
+            let s = Map.find x ss
+            if Set.contains y s then ss 
+            else (changed := true; Map.add x (Set.add y s) ss)
+
+        let oneRound (ss:Map<_,_>) = 
+            let changed = ref false
+            let frontier = 
+                let res = ref []
+                for nonTermX in ntTab.Indexes do 
+                    for prodIdx in prodTab.Productions.[nonTermX] do
+                        let rhs = Array.toList (prodTab.Symbols prodIdx)
+                        let rec place l =
+                            match l with
+                            | (yi::t) -> 
+                                res := 
+                                   List.choose 
+                                     (function None -> None | Some a -> Some (PNonTerminal nonTermX,Some a)) 
+                                     (Set.toList ss.[yi]) 
+                                   @ !res;
+                                if ss.[yi].Contains(None) then place t;
+                            | [] -> 
+                                res := (PNonTerminal nonTermX,None) :: !res
+                        place rhs
+                !res
+            let ss' = List.fold (add changed) ss frontier
+            !changed, ss'
+
+        let rec loop ss = 
+            let changed, ss' = oneRound ss
+            if changed then loop ss' else ss'
+        loop seed 
+            
+      
+    /// Compute the first set of the given sequence of non-terminals. If any of the non-terminals
+    /// have an empty token in the first set then we have to iterate through those. 
+    let ComputeFirstSetOfTokenList =
+        Memoize (fun (str,term) -> 
+            let acc = new System.Collections.Generic.List<_>()
+            let rec add l = 
+                match l with 
+                | [] -> acc.Add(term)
+                | sym::moreSyms -> 
+                    let firstSetOfSym = computedFirstTable.[sym]
+                    firstSetOfSym |> Set.iter (function None -> () | Some v -> acc.Add(v)) 
+                    if firstSetOfSym.Contains(None) then add moreSyms 
+            add str;
+            Set.ofSeq acc)
+    
+    // (int,int) representation of LR(0) items 
+    let prodIdx_to_item0 idx = mkItem0(idx,0) 
+    let prec_of_item0 item0 = prodTab.Precedence (prodIdx_of_item0 item0)
+    let ntIdx_of_item0 item0 = prodTab.NonTerminal (prodIdx_of_item0 item0)
+
+    let lsyms_of_item0 item0 = 
+        let prodIdx = prodIdx_of_item0 item0
+        let dotIdx = dotIdx_of_item0 item0
+        let syms = prodTab.Symbols prodIdx
+        syms.[..dotIdx-1]
+
+    let rsyms_of_item0 item0 = 
+        let prodIdx = prodIdx_of_item0 item0
+        let dotIdx = dotIdx_of_item0 item0
+        let syms = prodTab.Symbols prodIdx
+        syms.[dotIdx..]
+
+    let rsym_of_item0 item0 = 
+        let prodIdx = prodIdx_of_item0 item0
+        let dotIdx = dotIdx_of_item0 item0
+        prodTab.Symbol prodIdx dotIdx
+
+    let advance_of_item0 item0 = 
+        let prodIdx = prodIdx_of_item0 item0
+        let dotIdx = dotIdx_of_item0 item0
+        mkItem0(prodIdx,dotIdx+1)
+    let fakeStartNonTerminalsSet = Set.ofList (fakeStartNonTerminals |> List.map ntTab.ToIndex)
+
+    let IsStartItem item0 = fakeStartNonTerminalsSet.Contains(ntIdx_of_item0 item0)
+    let IsKernelItem item0 = (IsStartItem item0 || dotIdx_of_item0 item0 <> 0)
+
+    let StringOfSym sym = match sym with PTerminal s -> "'" ^ termTab.OfIndex s ^ "'" | PNonTerminal s -> ntTab.OfIndex s
+
+    let OutputSym os sym = fprintf os "%s" (StringOfSym sym)
+
+    let OutputSyms os syms =
+        fprintf os "%s" (String.Join(" ",Array.map StringOfSym syms))
+
+    // Print items and other stuff 
+    let OutputItem0 os item0 =
+        fprintf os "    %s -> %a . %a" (ntTab.OfIndex (ntIdx_of_item0 item0)) (* outputPrecInfo precInfo *) OutputSyms (lsyms_of_item0 item0) OutputSyms (rsyms_of_item0 item0) 
+        
+    let OutputItem0Set os s = 
+        Set.iter (fun item -> fprintf os "%a\n" OutputItem0 item) s
+
+    let OutputFirstSet os m = 
+        Set.iter (function None ->  fprintf os "<empty>" | Some x -> fprintf os "  term %s\n" x) m
+
+    let OutputFirstMap os m = 
+        Map.iter (fun x y -> fprintf os "first '%a' = \n%a\n" OutputSym x OutputFirstSet y) m
+
+    let OutputAction os m = 
+        match m with 
+        | Shift n -> fprintf os "  shift %d" n 
+        | Reduce prodIdx ->  fprintf os "  reduce %s --> %a" (ntTab.OfIndex (prodTab.NonTerminal prodIdx)) OutputSyms (prodTab.Symbols prodIdx)
+        | Error ->  fprintf os "  error"
+        | Accept -> fprintf os "  accept" 
+    
+    let OutputActions os m = 
+        Array.iteri (fun i (prec,action) -> let term = termTab.OfIndex i in fprintf os "    action '%s' (%a): %a\n" term outputPrecInfo prec OutputAction action) m
+
+    let OutputActionTable os m = 
+        Array.iteri (fun i n -> fprintf os "state %d:\n%a\n" i OutputActions n) m
+
+    let OutputImmediateActions os m = 
+        match m with 
+        | None -> fprintf os "<none>"
+        | Some a -> OutputAction os a
+    
+    let OutputGotos os m = 
+        Array.iteri (fun ntIdx s -> let nonterm = ntTab.OfIndex ntIdx in match s with Some st -> fprintf os "    goto %s: %d\n" nonterm st | None -> ()) m
+    
+    let OutputCombined os m = 
+        Array.iteri (fun i (a,b,c,d) -> fprintf os "state %d:\n  items:\n%a\n  actions:\n%a\n  immediate action: %a\n gotos:\n%a\n" i OutputItem0Set a OutputActions b OutputImmediateActions c OutputGotos d) m
+    
+    let OutputLalrTables os (prods,states, startStates,actionTable,immediateActionTable,gotoTable,endOfInputTerminalIdx,errorTerminalIdx) = 
+        let combined = Array.ofList (List.map2 (fun x (y,(z,w)) -> x,y,z,w) (Array.toList states) (List.zip (Array.toList actionTable) (List.zip (Array.toList immediateActionTable) (Array.toList gotoTable))))
+        fprintfn os "------------------------";
+        fprintfn os "states = ";
+        fprintfn os "%a" OutputCombined combined;
+        fprintfn os "startStates = %s" (String.Join(";",Array.ofList (List.map string startStates)));
+        fprintfn os "------------------------"
+
+
+    // Closure of LR(0) nonTerminals, items etc 
+    let ComputeClosure0NonTerminal = 
+        Memoize (fun nt -> 
+            let seed = (List.foldBack (prodIdx_to_item0 >> Set.add) prodTab.Productions.[nt] Set.empty)
+            LeastFixedPoint 
+                (fun item0 -> 
+                   match rsym_of_item0 item0 with
+                   | None -> []
+                   | Some(PNonTerminal ntB) ->  List.map prodIdx_to_item0 prodTab.Productions.[ntB]
+                   | Some(PTerminal _) -> [])
+                seed)
+
+    // Close a symbol under epsilon moves
+    let ComputeClosure0Symbol rsym acc = 
+        match rsym with
+        | Some (PNonTerminal nt) -> Set.union (ComputeClosure0NonTerminal nt) acc
+        | _ -> acc
+
+    // Close a set under epsilon moves
+    let ComputeClosure0 iset = 
+        Set.fold (fun acc x -> ComputeClosure0Symbol (rsym_of_item0 x) acc) iset iset 
+
+    // Right symbols after closing under epsilon moves
+    let RelevantSymbolsOfKernel kernel =
+        let kernelClosure0 = ComputeClosure0 kernel
+        Set.fold (fun acc x -> Option.fold (fun acc x -> Set.add x acc) acc (rsym_of_item0 x)) Set.empty kernelClosure0 
+
+    // Goto set of a kernel of LR(0) nonTerminals, items etc 
+    // Input is kernel, output is kernel
+    let ComputeGotosOfKernel iset sym = 
+        let isetClosure = ComputeClosure0 iset
+        let acc = new System.Collections.Generic.List<_>(10)
+        isetClosure |> Set.iter (fun item0 -> 
+              match rsym_of_item0 item0 with 
+              | Some sym2 when sym = sym2 -> acc.Add(advance_of_item0 item0) 
+              | _ -> ()) 
+        Set.ofSeq acc
+    
+    // Build the full set of LR(0) kernels 
+    reportTime(); printf "building kernels..."; stdout.Flush();
+    let startItems = List.mapi (fun i _ -> prodIdx_to_item0 (startNonTerminalIdx_to_prodIdx i)) fakeStartNonTerminals
+    let startKernels = List.map Set.singleton startItems
+    let kernels = 
+
+        /// We use a set-of-sets here. F# sets support structural comparison but at the time of writing
+        /// did not structural hashing. 
+        let acc = ref Set.empty
+        ProcessWorkList startKernels (fun addToWorkList kernel -> 
+            if not ((!acc).Contains(kernel)) then
+                acc := (!acc).Add(kernel);
+                for csym in RelevantSymbolsOfKernel kernel do 
+                    let gotoKernel = ComputeGotosOfKernel kernel csym 
+                    assert (gotoKernel.Count > 0)
+                    addToWorkList gotoKernel )
+                    
+        !acc |> Seq.toList |> List.map (Set.filter IsKernelItem)
+    
+    reportTime(); printf "building kernel table..."; stdout.Flush();
+    // Give an index to each LR(0) kernel, and from now on refer to them only by index 
+    let kernelTab = new KernelTable(kernels)
+    let startKernelIdxs = List.map kernelTab.Index startKernels
+    let startKernelItemIdxs = List.map2 (fun a b -> KernelItemIdx(a,b)) startKernelIdxs startItems
+
+    let outputKernelItemIdx os (kernelIdx,item0)  =
+        fprintf os "kernel %d, item %a" kernelIdx OutputItem0 item0
+
+    /// A cached version of the "goto" computation on LR(0) kernels 
+    let gotoKernel = 
+        Memoize (fun (GotoItemIdx(kernelIdx,sym)) -> 
+            let gset = ComputeGotosOfKernel (kernelTab.Kernel kernelIdx) sym
+            if gset.IsEmpty then None else Some (kernelTab.Index gset))
+
+    /// Iterate (iset,sym) pairs such that (gotoKernel kernelIdx sym) is not empty
+    let IterateGotosOfKernel kernelIdx f =
+        for sym in RelevantSymbolsOfKernel (kernelTab.Kernel kernelIdx) do 
+            match gotoKernel (GotoItemIdx(kernelIdx,sym)) with 
+            | None -> ()
+            | Some k -> f sym k
+    
+
+    // This is used to compute the closure of an LALR(1) kernel 
+    //
+    // For each item [A --> X.BY, a] in I
+    //   For each production B -> g in G'
+    //     For each terminal b in FIRST(Ya)
+    //        such that [B --> .g, b] is not in I do
+    //            add [B --> .g, b] to I
+    
+    let ComputeClosure1 iset = 
+        let acc = new Closure1Table()
+        ProcessWorkList iset (fun addToWorkList (item0,pretokens:Set<TerminalIndex>) ->
+            pretokens |> Set.iter (fun pretoken -> 
+                if not (acc.Contains(item0,pretoken)) then
+                    acc.Add(item0,pretoken) |> ignore
+                    let rsyms = rsyms_of_item0 item0 
+                    if rsyms.Length > 0 then 
+                        match rsyms.[0] with 
+                        | (PNonTerminal ntB) -> 
+                             let firstSet = ComputeFirstSetOfTokenList (Array.toList rsyms.[1..],pretoken)
+                             for prodIdx in prodTab.Productions.[ntB] do
+                                 addToWorkList (prodIdx_to_item0 prodIdx,firstSet)
+                        | PTerminal _ -> ()))
+        acc
+
+    // Compute the "spontaneous" and "propagate" maps for each LR(0) kernelItem 
+    //
+    // Input: The kernal K of a set of LR(0) items I and a grammar symbol X
+    //
+    // Output: The lookaheads generated spontaneously by items in I for kernel items 
+    // in goto(I,X) and the items I from which lookaheads are propagated to kernel
+    // items in goto(I,X)
+    //
+    // Method
+    //   1. Construct LR(0) kernel items (done - above)
+    //   2. 
+    // TODO: this is very, very slow. 
+    //
+    // PLAN TO OPTIMIZE THIS;
+    //   - Clarify and comment what's going on here
+    //   - verify if we really have to do these enormouos closure computations
+    //   - assess if it's possible to use the symbol we're looking for to help trim the jset
+    
+    reportTime(); printf "computing lookahead relations..."; stdout.Flush();
+
+        
+    let spontaneous, propagate  =
+        let closure1OfItem0WithDummy = 
+            Memoize (fun item0 -> ComputeClosure1 [(item0,Set.ofList [dummyLookaheadIdx])])
+
+        let spontaneous = new SpontaneousTable()
+        let propagate = new PropagateTable()
+        let count = ref 0 
+
+        for kernelIdx in kernelTab.Indexes do
+            printf  "."; stdout.Flush();
+            //printf  "kernelIdx = %d\n" kernelIdx; stdout.Flush();
+            let kernel = kernelTab.Kernel(kernelIdx)
+            for item0 in kernel do  
+                let item0Idx = KernelItemIdx(kernelIdx,item0)
+                let jset = closure1OfItem0WithDummy item0
+                //printf  "#jset = %d\n" jset.Count; stdout.Flush();
+                for (KeyValue(closureItem0, lookaheadTokens)) in jset.IEnumerable do
+                    incr count
+                    match rsym_of_item0 closureItem0 with 
+                    | None -> ()
+                    | Some rsym ->
+                         match gotoKernel (GotoItemIdx(kernelIdx,rsym)) with 
+                         | None -> ()
+                         | Some gotoKernelIdx ->
+                              let gotoItem = advance_of_item0 closureItem0
+                              let gotoItemIdx = KernelItemIdx(gotoKernelIdx,gotoItem)
+                              for lookaheadToken in lookaheadTokens do
+                                  if lookaheadToken = dummyLookaheadIdx 
+                                  then propagate.Add(item0Idx, gotoItemIdx) |> ignore
+                                  else spontaneous.Add(gotoItemIdx, lookaheadToken) |> ignore
+
+
+        //printfn "#kernelIdxs = %d, count = %d" kernelTab.Indexes.Length !count
+        spontaneous,
+        propagate
+   
+    //printfn "#spontaneous = %d, #propagate = %d" spontaneous.Count propagate.Count; stdout.Flush();
+   
+    //exit 0;
+    // Repeatedly use the "spontaneous" and "propagate" maps to build the full set 
+    // of lookaheads for each LR(0) kernelItem.   
+    reportTime(); printf  "building lookahead table..."; stdout.Flush();
+    let lookaheadTable = 
+
+        // Seed the table with the startKernelItems and the spontaneous info
+        let initialWork =
+            [ for idx in startKernelItemIdxs do
+                  yield (idx,endOfInputTerminalIdx)
+              for (KeyValue(kernelItemIdx,lookaheads)) in spontaneous.IEnumerable do
+                  for lookahead in lookaheads do
+                      yield (kernelItemIdx,lookahead) ]
+
+        let acc = new LookaheadTable()
+        // Compute the closure
+        ProcessWorkList 
+            initialWork
+            (fun queueWork (kernelItemIdx,lookahead) ->
+                acc.Add(kernelItemIdx,lookahead)
+                for gotoKernelIdx in propagate.[kernelItemIdx] do
+                    if not (acc.Contains(gotoKernelIdx,lookahead)) then 
+                        queueWork(gotoKernelIdx,lookahead))
+        acc
+
+    //printf  "built lookahead table, #lookaheads = %d\n" lookaheadTable.Count; stdout.Flush();
+
+    reportTime(); printf "building action table..."; stdout.Flush();
+    let shiftReduceConflicts = ref 0
+    let reduceReduceConflicts = ref 0
+    let actionTable, immediateActionTable = 
+
+        // Now build the action tables. First a utility to merge the given action  
+        // into the table, taking into account precedences etc. and reporting errors. 
+        let addResolvingPrecedence (arr: _[]) kernelIdx termIdx (precNew, actionNew) = 
+            // printf "DEBUG: state %d: adding action for %s, precNew = %a, actionNew = %a\n" kernelIdx (termTab.OfIndex termIdx) outputPrec precNew OutputAction actionNew; 
+            // We add in order of precedence - however the precedences may be the same, and we give warnings when rpecedence resolution is based on implicit file orderings 
+
+            let (precSoFar, actionSoFar) as itemSoFar = arr.[termIdx]
+
+            // printf "DEBUG: state %d: adding action for %s, precNew = %a, precSoFar = %a, actionSoFar = %a\n" kernelIdx (termTab.OfIndex termIdx) outputPrec precNew outputPrec precSoFar OutputAction actionSoFar; 
+            // if compare_prec precSoFar precNew = -1 then failwith "addResolvingPrecedence"; 
+
+            let itemNew = (precNew, actionNew) 
+            let winner = 
+                match itemSoFar,itemNew with 
+                | (_,Shift _),(_, Shift _) -> 
+                   if actionSoFar <> actionNew then 
+                      printf "internal error in fsyacc: shift/shift conflict";
+                   itemSoFar
+
+                | (((precShift,Shift _) as shiftItem), 
+                   ((precReduce,Reduce _) as reduceItem))
+                | (((precReduce,Reduce _) as reduceItem), 
+                   ((precShift,Shift _) as shiftItem)) -> 
+                    match precReduce, precShift with 
+                    | (ExplicitPrec (_,p1), ExplicitPrec(assocNew,p2)) -> 
+                      if p1 < p2 then shiftItem
+                      elif p1 > p2 then reduceItem
+                      else
+                        match precShift with 
+                        | ExplicitPrec(LeftAssoc,_) ->  reduceItem
+                        | ExplicitPrec(RightAssoc,_) -> shiftItem
+                        | _ ->
+                           printf "state %d: shift/reduce error on %s\n" kernelIdx (termTab.OfIndex termIdx); 
+                           incr shiftReduceConflicts;
+                           shiftItem
+                    | _ ->
+                       printf "state %d: shift/reduce error on %s\n" kernelIdx (termTab.OfIndex termIdx); 
+                       incr shiftReduceConflicts;
+                       shiftItem
+                | ((_,Reduce prodIdx1),(_, Reduce prodIdx2)) -> 
+                   printf "state %d: reduce/reduce error on %s\n" kernelIdx (termTab.OfIndex termIdx); 
+                   incr reduceReduceConflicts;
+                   if prodIdx1 < prodIdx2 then itemSoFar else itemNew
+                | _ -> itemNew 
+            arr.[termIdx] <- winner
+
+          
+        // This build the action table for one state. 
+        let ComputeActions kernelIdx = 
+            let kernel = kernelTab.Kernel kernelIdx
+            let arr = Array.create terminals.Length (NoPrecedence,Error)
+
+            //printf  "building lookahead table LR(1) items for kernelIdx %d\n" kernelIdx; stdout.Flush();
+
+            // Compute the LR(1) items based on lookaheads
+            let items = 
+                 [ for item0 in kernel do
+                     let kernelItemIdx = KernelItemIdx(kernelIdx,item0)
+                     let lookaheads = lookaheadTable.GetLookaheads(kernelItemIdx)
+                     yield (item0,lookaheads) ]
+                 |> ComputeClosure1
+
+            for (KeyValue(item0,lookaheads)) in items.IEnumerable do
+
+                let nonTermA = ntIdx_of_item0 item0
+                match rsym_of_item0 item0 with 
+                | Some (PTerminal termIdx) -> 
+                    let action =
+                      match gotoKernel (GotoItemIdx(kernelIdx,PTerminal termIdx)) with 
+                      | None -> failwith "action on terminal should have found a non-empty goto state"
+                      | Some gkernelItemIdx -> Shift gkernelItemIdx
+                    let prec = termTab.PrecInfoOfIndex termIdx
+                    addResolvingPrecedence arr kernelIdx termIdx (prec, action) 
+                | None ->
+                    for lookahead in lookaheads do
+                        if not (IsStartItem(item0)) then
+                            let prodIdx = prodIdx_of_item0 item0
+                            let prec = prec_of_item0 item0
+                            let action = (prec, Reduce prodIdx)
+                            addResolvingPrecedence arr kernelIdx lookahead action 
+                        elif lookahead = endOfInputTerminalIdx then
+                            let prec = prec_of_item0 item0
+                            let action = (prec,Accept)
+                            addResolvingPrecedence arr kernelIdx lookahead action 
+                        else ()
+                | _ -> ()
+
+            // If there is a single item A -> B C . and no Shift or Accept actions (i.e. only Error or Reduce, so the choice of terminal 
+            // cannot affect what we do) then we emit an immediate reduce action for the rule corresponding to that item 
+            // Also do the same for Accept rules. 
+            let closure = (ComputeClosure0 kernel)
+
+            let immediateAction =
+                match Set.toList closure with
+                | [item0] ->
+                    match (rsym_of_item0 item0) with 
+                    | None when (let reduceOrErrorAction = function Error | Reduce _ -> true | Shift _ | Accept -> false
+                                 termTab.Indexes |> List.forall(fun terminalIdx -> reduceOrErrorAction (snd(arr.[terminalIdx]))))
+                        -> Some (Reduce (prodIdx_of_item0 item0))
+
+                    | None when (let acceptOrErrorAction = function Error | Accept -> true | Shift _ | Reduce _ -> false
+                                 List.forall (fun terminalIdx -> acceptOrErrorAction (snd(arr.[terminalIdx]))) termTab.Indexes)
+                        -> Some Accept
+
+                    | _ -> None
+                | _ -> None
+
+            // A -> B C . rules give rise to reductions in favour of errors 
+            for item0 in ComputeClosure0 kernel do
+                let prec = prec_of_item0 item0
+                match rsym_of_item0 item0 with 
+                | None ->
+                    for terminalIdx in termTab.Indexes do 
+                        if snd(arr.[terminalIdx]) = Error then 
+                            let prodIdx = prodIdx_of_item0 item0
+                            let action = (prec, (if IsStartItem(item0) then Accept else Reduce prodIdx))
+                            addResolvingPrecedence arr kernelIdx terminalIdx action
+                | _  -> ()
+
+            arr,immediateAction
+
+        let actionInfo = List.map ComputeActions kernelTab.Indexes
+        Array.ofList (List.map fst actionInfo),
+        Array.ofList (List.map snd actionInfo)
+
+    // The goto table is much simpler - it is based on LR(0) kernels alone. 
+
+    reportTime(); printf  "building goto table..."; stdout.Flush();
+    let gotoTable = 
+         let gotos kernelIdx = Array.ofList (List.map (fun nt -> gotoKernel (GotoItemIdx(kernelIdx,PNonTerminal nt))) ntTab.Indexes)
+         Array.ofList (List.map gotos kernelTab.Indexes)
+
+    reportTime(); printfn  "returning tables."; stdout.Flush();
+    if !shiftReduceConflicts > 0 then printfn  "%d shift/reduce conflicts" !shiftReduceConflicts; stdout.Flush();
+    if !reduceReduceConflicts > 0 then printfn  "%d reduce/reduce conflicts" !reduceReduceConflicts; stdout.Flush();
+
+    /// The final results
+    let states = kernels |> Array.ofList 
+    let prods = Array.ofList (List.map (fun (Production(nt,prec,syms,code)) -> (nt, ntTab.ToIndex nt, syms,code)) prods)
+
+    logf (fun logStream -> 
+        printf  "writing tables to log\n"; stdout.Flush();
+        OutputLalrTables logStream     (prods, states, startKernelIdxs, actionTable, immediateActionTable, gotoTable, (termTab.ToIndex endOfInputTerminal), errorTerminalIdx));
+
+    let states = states |> Array.map (Set.toList >> List.map prodIdx_of_item0)
+    (prods, states, startKernelIdxs, 
+     actionTable, immediateActionTable, gotoTable, 
+     (termTab.ToIndex endOfInputTerminal), 
+     errorTerminalIdx, nonTerminals)
+
+  
+(* Some examples for testing *)  
+
+(*
+
+let example1 = 
+  let e = "E" 
+  let t = "Terminal"
+  let plus = "+"
+  let mul = "*"
+  let f = "F"
+  let lparen = "("
+  let rparen = ")"
+  let id = "id"
+  
+  let terminals = [plus; mul; lparen; rparen; id]
+  let nonTerminals = [e; t; f]
+  
+  let p2 = e, (NonAssoc, ExplicitPrec 1), [NonTerminal e; Terminal plus; NonTerminal t], None
+  let p3 = e, (NonAssoc, ExplicitPrec 2), [NonTerminal t], None in  
+  let p4 = t, (NonAssoc, ExplicitPrec 3), [NonTerminal t; Terminal mul; NonTerminal f], None
+  let p5 = t, (NonAssoc, ExplicitPrec 4), [NonTerminal f], None
+  let p6 = f, (NonAssoc, ExplicitPrec  5), [Terminal lparen; NonTerminal e; Terminal rparen], None
+  let p7 = f, (NonAssoc, ExplicitPrec 6), [Terminal id], None
+
+  let prods = [p2;p3;p4;p5;p6;p7]
+  Spec(terminals,nonTerminals,prods, [e])
+
+let example2 = 
+  let prods = [ "S", (NonAssoc, ExplicitPrec 1), [NonTerminal "C";NonTerminal "C"], None; 
+                "C", (NonAssoc, ExplicitPrec 2), [Terminal "c";NonTerminal "C"], None ;
+                "C", (NonAssoc, ExplicitPrec 3), [Terminal "d"] , None  ]in
+  Spec(["c";"d"],["S";"C"],prods, ["S"])
+
+let example3 = 
+  let terminals = ["+"; "*"; "("; ")"; "id"]
+  let nonTerminals = ["E"; "Terminal"; "E'"; "F"; "Terminal'"]
+  let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "Terminal"; NonTerminal "E'" ], None;
+                "E'", (NonAssoc, ExplicitPrec 2), [ Terminal "+"; NonTerminal "Terminal"; NonTerminal "E'"], None;
+                "E'", (NonAssoc, ExplicitPrec 3), [ ], None;
+                "Terminal", (NonAssoc, ExplicitPrec 4), [ NonTerminal "F"; NonTerminal "Terminal'" ], None;
+                "Terminal'", (NonAssoc, ExplicitPrec 5), [ Terminal "*"; NonTerminal "F"; NonTerminal "Terminal'"], None;
+                "Terminal'", (NonAssoc, ExplicitPrec 6), [ ], None;
+                "F", (NonAssoc, ExplicitPrec 7), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
+                "F", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ]
+  Spec(terminals,nonTerminals,prods, ["E"])
+
+let example4 = 
+  let terminals = ["+"; "*"; "("; ")"; "id"]
+  let nonTerminals = ["E"]
+  let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None;
+                "E", (NonAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None;
+                "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
+                "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"],  None ]
+  Spec(terminals,nonTerminals,prods, ["E"])
+
+let example5 = 
+  let terminals = ["+"; "*"; "("; ")"; "id"]
+  let nonTerminals = ["E"]
+  let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None;
+                "E", (NonAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None;
+                "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
+                "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ]
+  Spec(terminals,nonTerminals,prods, ["E"])
+
+let example6 = 
+  let terminals = ["+"; "*"; "("; ")"; "id"; "-"]
+  let nonTerminals = ["E"]
+  let prods = [ "E", (RightAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "-"; NonTerminal "E" ], None;
+                "E", (LeftAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None;
+                "E", (LeftAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None;
+                "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
+                "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ]
+  Spec(terminals,nonTerminals,prods, ["E"])
+
+
+let example7 = 
+  let prods = [ "S", (NonAssoc, ExplicitPrec 1), [NonTerminal "L";Terminal "="; NonTerminal "R"], None; 
+                "S", (NonAssoc, ExplicitPrec 2), [NonTerminal "R"], None ;
+                "L", (NonAssoc, ExplicitPrec 3), [Terminal "*"; NonTerminal "R"], None;
+                "L", (NonAssoc, ExplicitPrec 3), [Terminal "id"], None; 
+                "R", (NonAssoc, ExplicitPrec 3), [NonTerminal "L"], None; ]
+  Spec(["*";"=";"id"],["S";"L";"R"],prods, ["S"])
+
+
+
+let test ex = CompilerLalrParserSpec stdout ex
+
+(* let _ = test example2*)
+(* let _ = exit 1*)
+(* let _ = test example3 
+let _ = test example1  
+let _ = test example4
+let _ = test example5
+let _ = test example6 *)
+*)
diff --git a/src/FsYacc/fsyacclex.fsl b/src/FsYacc/fsyacclex.fsl
new file mode 100755
index 0000000..ba0f639
--- /dev/null
+++ b/src/FsYacc/fsyacclex.fsl
@@ -0,0 +1,144 @@
+{
+(* (c) Microsoft Corporation 2005-2008.  *)
+
+module internal FSharp.PowerPack.FsYacc.Lexer
+  
+open FSharp.PowerPack.FsYacc.AST
+open FSharp.PowerPack.FsYacc.Parser
+open System.Text
+open Internal.Utilities.Text.Lexing
+
+let lexeme  (lexbuf : LexBuffer<char>) = new System.String(lexbuf.Lexeme)
+let newline (lexbuf:LexBuffer<_>) = lexbuf.EndPos <- lexbuf.EndPos.NextLine
+
+let unexpected_char lexbuf =
+  failwith ("Unexpected character '"+(lexeme lexbuf)+"'")
+
+let typeDepth = ref 0
+let startPos = ref Position.Empty
+let mutable str_buf = new System.Text.StringBuilder()
+
+let appendBuf (str:string) = str_buf.Append str |> ignore
+let clearBuf () = str_buf <- new System.Text.StringBuilder()
+
+} 
+
+let letter = ['A'-'Z'] | ['a'-'z']
+let digit = ['0'-'9']
+let whitespace = [' ' '\t']
+let newline = ('\n' | '\r' '\n')
+let ident_start_char = letter       
+let ident_char = ( ident_start_char| digit | ['\'' '_'] )
+let ident = ident_start_char ident_char*
+
+rule token = parse
+ | "%{" { let p = lexbuf.StartPos in header p (new StringBuilder 100) lexbuf }
+ | "%%" { PERCENT_PERCENT }
+ | "%token" (whitespace* '<') { typeDepth := 1; startPos := lexbuf.StartPos; clearBuf(); TOKEN (fs_type lexbuf) }
+ | "%token" { TOKEN (None) }
+ | "%start"{ START }
+ | "%prec"{ PREC }
+ | "%type" (whitespace* '<') { typeDepth := 1; startPos := lexbuf.StartPos; clearBuf(); TYPE (match fs_type lexbuf with Some x -> x | None -> failwith "gettype") }
+ | "%left" { LEFT }
+ | "%right" { RIGHT }
+ | "%nonassoc" { NONASSOC }
+ | "error" { ERROR }
+ | '<' { LESS }
+ | '>' { GREATER }
+ | ';' { SEMI }
+ | '{' { let p = lexbuf.StartPos in 
+         let buff = (new StringBuilder 100) in
+         // adjust the first line to get even indentation for all lines w.r.t. the left hand margin
+         buff.Append (String.replicate (lexbuf.StartPos.Column+1) " ")  |> ignore;
+         code p buff lexbuf }
+ | whitespace+  { token lexbuf }
+ | newline { newline lexbuf; token lexbuf }
+ | ident_start_char ident_char* { IDENT (lexeme lexbuf) }
+ | '|' { BAR }
+ | "/*" { ignore(comment lexbuf); token lexbuf }
+ | "//" [^'\n''\r']* {  token lexbuf  }
+ | ':' { COLON }
+ | _ { unexpected_char lexbuf }     
+ | eof { EOF  }  
+
+and fs_type = parse
+  | '<' { incr typeDepth; appendBuf(lexeme lexbuf); fs_type lexbuf}
+  | '>'
+    { decr typeDepth; 
+      if !typeDepth = 0
+      then Some(string str_buf) 
+      else appendBuf(lexeme lexbuf); fs_type lexbuf }
+  | _ { appendBuf(lexeme lexbuf); fs_type lexbuf } 
+                                   
+and header p buff = parse
+ | "%}" { HEADER (buff.ToString(), p) }
+ | newline { newline lexbuf; 
+             ignore <| buff.Append System.Environment.NewLine; 
+             header p buff lexbuf }
+ | (whitespace | letter | digit) +  
+      { ignore <| buff.Append (lexeme lexbuf); 
+        header p buff lexbuf }
+ | "//" [^'\n''\r']*
+      { ignore <| buff.Append (lexeme lexbuf); 
+        header p buff lexbuf }
+ | "'\"'" | "'\\\"'"
+      { ignore <| buff.Append (lexeme lexbuf); 
+        header p buff lexbuf }
+ | "\"" 
+      { ignore <| buff.Append (lexeme lexbuf); 
+        ignore(codestring buff lexbuf); 
+        header p buff lexbuf }
+ | eof { EOF }
+ | _ { ignore <| buff.Append(lexeme lexbuf).[0]; 
+       header p buff lexbuf }
+and code p buff = parse
+ | "}" { CODE (buff.ToString(), p) }
+ | "{" { ignore <| buff.Append (lexeme lexbuf); 
+         ignore(code p buff lexbuf); 
+         ignore <| buff.Append "}"; 
+         code p buff lexbuf }
+ | newline { newline lexbuf; 
+             ignore <| buff.Append System.Environment.NewLine; 
+             code p buff lexbuf }
+ | "'\"'" | "'\\\"'"
+      { ignore <| buff.Append (lexeme lexbuf); 
+        code p buff lexbuf }
+ | "\"" { ignore <| buff.Append (lexeme lexbuf); 
+          ignore(codestring buff lexbuf); 
+          code p buff lexbuf }
+ | (whitespace | letter | digit) +  
+   { ignore <| buff.Append (lexeme lexbuf); 
+     code p buff lexbuf }
+ | "//" [^'\n''\r']*
+   { ignore <| buff.Append (lexeme lexbuf); 
+     code p buff lexbuf }
+ | eof { EOF }
+ | _ { ignore <| buff.Append(lexeme lexbuf).[0]; 
+       code p buff lexbuf }
+
+
+and codestring buff = parse
+ |  '\\' ('"' | '\\')
+   { ignore <| buff.Append (lexeme lexbuf); 
+     codestring buff lexbuf } 
+ | '"' { ignore <| buff.Append (lexeme lexbuf); 
+         buff.ToString() }
+ | newline { newline lexbuf; 
+             ignore <| buff.Append System.Environment.NewLine; 
+             codestring buff lexbuf }
+ | (whitespace | letter | digit) +  
+   { ignore <| buff.Append (lexeme lexbuf); 
+     codestring buff lexbuf }
+ | eof { failwith "unterminated string in code" }
+ | _ { ignore <| buff.Append(lexeme lexbuf).[0]; 
+       codestring buff lexbuf }
+
+
+and comment = parse
+ | "/*" { ignore(comment lexbuf); comment lexbuf }
+ | newline { newline lexbuf; comment lexbuf }
+ | "*/" { () }
+ | eof { failwith "end of file in comment" }
+ | [^ '/' '*' '\n' '\r' '"' '/' ]+  { comment lexbuf }
+ | _  { comment lexbuf }
+
diff --git a/src/FsYacc/fsyaccpars.fsy b/src/FsYacc/fsyaccpars.fsy
new file mode 100755
index 0000000..163b316
--- /dev/null
+++ b/src/FsYacc/fsyaccpars.fsy
@@ -0,0 +1,55 @@
+%{
+(* (c) Microsoft Corporation 2005-2008.  *)
+
+// FSharp.PowerPack.FsYacc.Parser
+
+open FSharp.PowerPack.FsYacc
+open FSharp.PowerPack.FsYacc.AST
+
+#nowarn "62" // This construct is for ML compatibility
+
+%} 
+
+%type <AST.ParserSpec> spec
+%token <string>  IDENT 
+%token <AST.Code> HEADER CODE 
+%token BAR PERCENT_PERCENT  START LEFT RIGHT NONASSOC LESS GREATER COLON PREC SEMI EOF ERROR
+%token <string> TYPE
+%token <string option> TOKEN
+%start spec
+%left BAR
+%%      
+
+spec: 
+    headeropt decls PERCENT_PERCENT rules 
+    { List.foldBack (fun f x -> f x) $2 { Header=$1;Tokens=[];Types=[];Associativities=[];StartSymbols=[];Rules=$4 } }
+
+headeropt: 
+  | HEADER 
+       { $1 } 
+  | 
+      { "", (parseState.ResultRange |> fst)}
+
+decls:  
+    { [] } 
+  | decl decls { $1 :: $2 }
+
+decl: 
+    TOKEN idents { (fun x -> {x with Tokens = x.Tokens @ (List.map (fun x -> (x,$1)) $2)}) }
+  | TYPE idents   { (fun x -> {x with Types = x.Types @ (List.map (fun x -> (x,$1)) $2)} ) } 
+  | START idents   { (fun x -> {x with StartSymbols = x.StartSymbols @ $2} ) }
+  | LEFT idents   { (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,LeftAssoc)) $2)]} ) }
+  | RIGHT idents   { (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,RightAssoc)) $2)]} ) }
+  | NONASSOC idents   { (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,NonAssoc)) $2)]} ) }
+
+idents: IDENT idents { $1 :: $2 } | { [] }
+rules: rule rules { $1 :: $2 } | rule { [$1] }
+rule: IDENT COLON optbar clauses optsemi { ($1,$4) }
+optbar: { } | BAR { }
+optsemi: { } | SEMI { }
+clauses: clause BAR clauses {$1 :: $3 } | clause { [$1] }
+clause: syms optprec CODE { Rule($1,$2,Some $3) }
+syms: IDENT syms { $1 :: $2 } | ERROR syms { "error" :: $2 } | { [] }
+optprec: { None } | PREC IDENT { Some $2 }
+
+
diff --git a/src/MsiInstaller/License.rtf b/src/MsiInstaller/License.rtf
new file mode 100755
index 0000000..d3ab1fb
--- /dev/null
+++ b/src/MsiInstaller/License.rtf
@@ -0,0 +1,267 @@
+{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch0\stshfloch37\stshfhich37\stshfbi37\deflang2057\deflangfe2057\themelang1033\themelangfe2052\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
+{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f13\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}SimSun{\*\falt ???\'a1\'ec??};}
+{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f38\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}
+{\f39\fbidi \fnil\fcharset134\fprq2{\*\panose 00000000000000000000}@SimSun;}{\f40\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0502040204020203}Segoe UI;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\fdbmajor\f31501\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}SimSun{\*\falt ???\'a1\'ec??};}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}
+{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\fdbminor\f31505\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}SimSun{\*\falt ???\'a1\'ec??};}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
+{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f43\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f44\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\f46\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f47\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f48\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f49\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\f50\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f51\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f53\fbidi \fswiss\fcharset238\fprq2 Arial CE;}{\f54\fbidi \fswiss\fcharset204\fprq2 Arial Cyr;}
+{\f56\fbidi \fswiss\fcharset161\fprq2 Arial Greek;}{\f57\fbidi \fswiss\fcharset162\fprq2 Arial Tur;}{\f58\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f59\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic);}
+{\f60\fbidi \fswiss\fcharset186\fprq2 Arial Baltic;}{\f61\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f63\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f64\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}
+{\f66\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f67\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f68\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f69\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}
+{\f70\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f71\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f175\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt ???\'a1\'ec??};}{\f383\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}
+{\f384\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f386\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f387\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f390\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}
+{\f391\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f413\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f414\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f416\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}
+{\f417\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f420\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f421\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\f423\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}
+{\f424\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f426\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}{\f427\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;}{\f428\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}
+{\f429\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f430\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f431\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f432\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}
+{\f435\fbidi \fnil\fcharset0\fprq2 @SimSun Western;}{\f443\fbidi \fswiss\fcharset238\fprq2 Segoe UI CE;}{\f444\fbidi \fswiss\fcharset204\fprq2 Segoe UI Cyr;}{\f446\fbidi \fswiss\fcharset161\fprq2 Segoe UI Greek;}
+{\f447\fbidi \fswiss\fcharset162\fprq2 Segoe UI Tur;}{\f449\fbidi \fswiss\fcharset178\fprq2 Segoe UI (Arabic);}{\f450\fbidi \fswiss\fcharset186\fprq2 Segoe UI Baltic;}{\f451\fbidi \fswiss\fcharset163\fprq2 Segoe UI (Vietnamese);}
+{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
+{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31520\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt ???\'a1\'ec??};}
+{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;}
+{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
+{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
+{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
+{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
+{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
+{\fdbminor\f31560\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt ???\'a1\'ec??};}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}
+{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
+{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
+{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}
+{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
+\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red204\green204\blue204;\red48\green51\blue45;}{\*\defchp \f37 }{\*\defpap 
+\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 
+\ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 \styrsid6359658 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
+\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv 
+\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af37\afs20\alang1025 \ltrch\fcs0 \f37\fs20\lang2057\langfe2057\cgrid\langnp2057\langfenp2057 \snext11 \ssemihidden \sunhideused \sqformat Normal Table;}{
+\s15\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 
+\f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 \slink16 \ssemihidden \sunhideused \styrsid2586401 HTML Preformatted;}{\*\cs16 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 
+\sbasedon10 \slink15 \slocked \ssemihidden \styrsid2586401 HTML Preformatted Char;}{\*\cs17 \additive \rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \fs16 \sbasedon10 \ssemihidden \sunhideused \styrsid2586401 annotation reference;}{
+\s18\ql \li0\ri0\sa200\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \f37\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 
+\sbasedon0 \snext18 \slink19 \ssemihidden \sunhideused \styrsid2586401 annotation text;}{\*\cs19 \additive \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \fs20 \sbasedon10 \slink18 \slocked \ssemihidden \styrsid2586401 Comment Text Char;}{
+\s20\ql \li0\ri0\sa200\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs20\alang1025 \ltrch\fcs0 \b\f37\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 
+\sbasedon18 \snext18 \slink21 \ssemihidden \sunhideused \styrsid2586401 annotation subject;}{\*\cs21 \additive \rtlch\fcs1 \ab\af0\afs20 \ltrch\fcs0 \b\fs20 \sbasedon19 \slink20 \slocked \ssemihidden \styrsid2586401 Comment Subject Char;}{
+\s22\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af38\afs16\alang1025 \ltrch\fcs0 \f38\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 
+\sbasedon0 \snext22 \slink23 \ssemihidden \sunhideused \styrsid2586401 Balloon Text;}{\*\cs23 \additive \rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16 \sbasedon10 \slink22 \slocked \ssemihidden \styrsid2586401 Balloon Text Char;}{
+\s24\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 
+\sbasedon0 \snext24 \sqformat \spriority34 \styrsid11930140 List Paragraph;}{\s25\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs23\alang1025 \ltrch\fcs0 
+\b\fs23\lang1033\langfe2052\loch\f0\hich\af0\dbch\af13\cgrid\langnp1033\langfenp2052 \sbasedon0 \snext25 \spriority0 \styrsid2768696 title;}{\s26\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\brdrt\brdrinset\brdrw15\brsp80 \brdrl
+\brdrinset\brdrw15\brsp80 \brdrb\brdrinset\brdrw15\brsp80 \brdrr\brdrinset\brdrw15 \wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \cbpat17 \rtlch\fcs1 \ab\af0\afs18\alang1025 \ltrch\fcs0 
+\b\fs18\lang1033\langfe2052\loch\f0\hich\af0\dbch\af13\cgrid\langnp1033\langfenp2052 \sbasedon0 \snext26 \spriority0 \styrsid2768696 label;}{
+\s27\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 
+\sbasedon0 \snext27 \styrsid11805901 Normal (Web);}}{\*\listtable{\list\listtemplateid774910488{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 
+\af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li720\jclisttab\tx720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 
+\hres0\chhres0 \fi-360\li1440\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 
+\fi-360\li2160\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880
+\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600
+\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li4320
+\jclisttab\tx4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040
+\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760
+\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li6480
+\jclisttab\tx6480\lin6480 }{\listname ;}\listid20909527}{\list\listtemplateid511971906\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698705
+\'02\'00);}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713
+\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li1440\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715
+\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2160\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698703
+\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713
+\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715
+\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li4320\jclisttab\tx4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698703
+\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698713
+\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698715
+\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li6480\jclisttab\tx6480\lin6480 }{\listname ;}\listid312490227}{\list\listtemplateid-1781468132\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0
+\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \dbch\af0\fbias0\hres0\chhres0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0
+\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0
+\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0
+\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0
+\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0
+\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0
+\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0
+\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0
+\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li6480\lin6480 }{\listname ;}\listid568228894}{\list\listtemplateid623048920
+\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0\hres0\chhres0 \fi-360\li720\lin720 }
+{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li1440\lin1440 }
+{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li2160\lin2160 }
+{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880\lin2880 }
+{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600\lin3600 }
+{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li4320\lin4320 }
+{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040\lin5040 }
+{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760\lin5760 }
+{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li6480\lin6480 }
+{\listname ;}\listid1655064483}{\list\listtemplateid42258022\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid-826796942\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 
+\af1 \ltrch\fcs0 \fs20\loch\af1\hich\af1\dbch\af0\hres0\chhres0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713
+\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715
+\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698703
+\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713
+\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715
+\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698703
+\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713
+\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715
+\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li6480\lin6480 }{\listname ;}\listid1829663624}{\list\listtemplateid405036400\listhybrid{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1
+\levelspace0\levelindent0{\leveltext\leveltemplateid-717196318\'03(\'00);}{\levelnumbers\'02;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0\hres0\chhres0 \fi-720\li1080\lin1080 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1
+\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1
+\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1
+\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1
+\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1
+\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1
+\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1
+\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1
+\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li6480\lin6480 }{\listname ;}\listid1926917201}{\list\listtemplateid-1157985748\listhybrid
+{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid-1852304376\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af1 \ltrch\fcs0 
+\fs22\loch\af1\hich\af1\dbch\af13\fbias0\hres0\chhres0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'01.;}{\levelnumbers
+\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'02.;}{\levelnumbers
+\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'03.;}{\levelnumbers
+\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'04.;}{\levelnumbers
+\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'05.;}{\levelnumbers
+\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698703\'02\'06.;}{\levelnumbers
+\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698713\'02\'07.;}{\levelnumbers
+\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\leveltemplateid67698715\'02\'08.;}{\levelnumbers
+\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \hres0\chhres0 \fi-180\li6480\lin6480 }{\listname ;}\listid2052072285}}{\*\listoverridetable{\listoverride\listid312490227\listoverridecount9{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat
+\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel
+\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}\ls1}{\listoverride\listid1926917201\listoverridecount0\ls2}{\listoverride\listid1829663624\listoverridecount0\ls3}{\listoverride\listid2052072285\listoverridecount0\ls4}
+{\listoverride\listid568228894\listoverridecount0\ls5}{\listoverride\listid1655064483\listoverridecount0\ls6}{\listoverride\listid20909527\listoverridecount0\ls7}}{\*\pgptbl {\pgp\ipgp7\itap1\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp4
+\itap2\li0\ri0\sb0\sa0}{\pgp\ipgp1\itap2\li0\ri0\sb0\sa0}{\pgp\ipgp10\itap0\li240\ri240\sb240\sa240}{\pgp\ipgp2\itap1\li0\ri0\sb0\sa0}{\pgp\ipgp6\itap1\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp3\itap0
+\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid84265\rsid599059\rsid675185\rsid999462\rsid1146826\rsid1202076\rsid2586401\rsid2768696\rsid3085619\rsid3411389\rsid3478834\rsid3746009\rsid4225869\rsid4854444\rsid4876618\rsid5455599\rsid5596599\rsid6052385\rsid6183650
+\rsid6358978\rsid6359658\rsid6433848\rsid6497079\rsid6898870\rsid7275217\rsid7825665\rsid8353396\rsid8416904\rsid8672401\rsid8797287\rsid9388661\rsid9511157\rsid9640135\rsid10029082\rsid10569878\rsid11627981\rsid11805901\rsid11827719\rsid11930140
+\rsid12599774\rsid12612379\rsid12714714\rsid12723133\rsid13177071\rsid14685900\rsid14897889\rsid15628542}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info
+{\author yonglee}{\operator Don Syme}{\creatim\yr2008\mo8\dy18\hr13\min33}{\revtim\yr2010\mo2\dy4\hr18\min49}{\version5}{\edmins1}{\nofpages1}{\nofwords404}{\nofchars2228}{\*\company Microsoft}{\nofcharsws2627}{\vern32771}}{\*\xmlnstbl {\xmlns1 http://sch
+emas.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect 
+\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen
+\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1
+\jexpand\viewkind1\viewscale200\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
+\asianbrkrule\rsidroot2586401\newtblstyruls\nogrowautofit\utinl \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sectrsid6359658\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang 
+{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}
+{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9
+\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa200\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid675185 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 
+\f37\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af40\afs19 \ltrch\fcs0 \f40\fs19\cf18\lang2057\langfe2057\langnp2057\langfenp2057\insrsid675185\charrsid675185 Microsoft Public License (Ms-PL)\line \line 
+This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.\line \line 1. Definitions\line \line 
+The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.\line \line A "contribution" is the original software, or any additions or changes to the software.\line \line 
+A "contributor" is any person that distributes its contribution under this license.\line \line "Licensed patents" are a contributor's patent claims that read directly on its contribution.\line \line 2. Grant of Rights\line \line 
+(A) Copyright Grant- Subject to the terms of this license, including the license conditio
+ns and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works th
+at you create.\line \line 
+(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made
+, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.\line \line 3. Conditions and Limitations\line \line 
+(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.\line \line 
+(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.\line \line (C) If you di
+stribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.\line \line 
+(D) If you distribute any portion of the software in source code form, you may do so only under this license 
+by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.\line \line 
+(E) The software is licensed "as-is." Y
+ou bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contrib
+utors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. 
+\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid675185 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3746009\charrsid675185 
+\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8
+72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7
+2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b
+44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7
+065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000
+00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08
+84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc
+52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353
+bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468
+656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c
+070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7
+29e245eb2b260a0238fd010000ffff0300504b03041400060008000000210096b5ade296060000501b0000160000007468656d652f7468656d652f7468656d65
+312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87615b8116d8
+a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad79482a9c04
+98f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b5d8a314d3c
+94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab999fb7b471
+7509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9699640f671
+9e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd5868b37a088d1
+e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d60cf03ac1a5
+193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f9e7ef3f2d1
+17d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be15c308d3f2
+8acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a99793849c26ae6
+6252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d32a423279a
+668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2af074481847
+bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86e877f0034e
+16bafb0e258ebb4faf06b769e888340b103d3311da9750aa9d0a1cd3e4efca31a3508f6d0c5c5c398602f8e2ebc71591f5b616e24dd893aa3261fb44f95d843b
+5974bb5c04f4edafb95b7892ec1108f3f98de75dc97d5772bdff7cc95d94cf672db4b3da0a6557f70db629362d72bcb0431e53c6066acac80d699a6409fb44d0
+8741bdce9c0e4971624a2378cceaba830b05366b90e0ea23aaa241845368b0eb9e2612ca8c742851ca251ceccc70256d8d87265dd96361531f186c3d9058edf2
+c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db02565e85f3b966
+0d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276b9f7dec44b
+7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399161ee314bc2e75cf8759081743be1236ec4f4d6693e5336fb672c5dc24a8c33585b5fb
+9cc24e1d4885545b58463634cc5416022cd19cacfccb4d30eb45296023fd35a458598360f8d7a4003bbaae25e331f155d9d9a5116d3bfb9a95523e51440ca2e0
+088dd844ec6370bf0e55d027a012ae264c45d02f708fa6ad6da6dce29c255df9f6cae0ec38666984b372ab5334cf640b37795cc860de4ae2816e95b21be5ceaf
+8a49f90b52a51cc6ff3355f47e0237052b81f6800fd7b802239daf6d8f0b1571a8426944fdbe80c6c1d40e8816b88b8569082ab84c36ff0539d4ff6dce591a26
+ade1c0a7f669880485fd484582903d284b26fa4e2156cff62e4b9265844c4495c495a9157b440e091bea1ab8aaf7760f4510eaa69a6465c0e04ec69ffb9e65d0
+28d44d4e39df9c1a52ecbd3607fee9cec7263328e5d661d3d0e4f62f44acd855ed7ab33cdf7bcb8ae889599bd5c8b3029895b6825696f6af29c239b75a5bb1e6
+345e6ee6c28117e73586c1a2214ae1be07e93fb0ff51e133fb65426fa843be0fb515c187064d0cc206a2fa926d3c902e907670048d931db4c1a44959d366ad93
+b65abe595f70a75bf03d616c2dd959fc7d4e6317cd99cbcec9c58b34766661c7d6766ca1a9c1b327531486c6f941c638c67cd22a7f75e2a37be0e82db8df9f30
+254d30c1372581a1f51c983c80e4b71ccdd28dbf000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f74
+68656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f24
+51eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198
+720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528
+a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c0200001300000000000000000000000000
+000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b000000000000000000000000
+002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000140200007468
+656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210096b5ade296060000501b000016000000000000000000
+00000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b010000270000000000
+00000000000000009b0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000960a00000000}
+{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
+617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
+6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
+656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
+{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;
+\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
+\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;
+\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7;
+\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font;
+\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;
+\lsdpriority0 \lsdlocked0 Normal (Web);\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision;
+\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6;
+\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;
+\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
+\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;
+\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000
+4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000
+d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f00000000000000000000000070e7
+47c9caa5ca01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000105000000000000}}
\ No newline at end of file
diff --git a/src/MsiInstaller/build-msi.bat b/src/MsiInstaller/build-msi.bat
new file mode 100755
index 0000000..64646f4
--- /dev/null
+++ b/src/MsiInstaller/build-msi.bat
@@ -0,0 +1,58 @@
+ at if "%_echo%"=="" echo off
+setlocal
+
+if "%TOOLS%" == "" (
+    set TOOLS=c:\fsharp\rc1\tools
+)
+if "%WIX_HOME%" == "" (
+    set WIX_HOME=%TOOLS%\win86\wix-ms\3.0.4116.0\bin
+)
+if "%WIX_UI_PATH%" == "" (
+    set WIX_UI_PATH=%TOOLS%\win86\wix\WixUI_en-us.wxl
+)
+if "%CYGWIN%" == "" (
+    set CYGWIN=%TOOLS%\win86\cygwin
+)
+set CANDLE=%WIX_HOME%\candle.exe
+set LIGHT=%WIX_HOME%\light.exe
+set FSI_TOOL=fsi.exe
+set RM=%CYGWIN%\rm.exe
+set SED=%CYGWIN%\sed.exe
+set CP=%CYGWIN%\cp.exe
+set PKZIP=%TOOLS%\win86\cygwin\zip.exe
+if "%MSIDUMP%" == "" (
+    set MSIDUMP=%TOOLS%\win86\msidump\x86\msidump.exe
+)
+set tree=FSharpPowerPack-2.0.0.0
+
+%FSI_TOOL% --quiet generateWixFileEntries.fsx  %tree%
+pushd %tree%
+%CANDLE%  -ext WixNetFxExtension ..\files.wxs ..\product.wxs
+%LIGHT%  -out ..\InstallFSharpPowerPack.msi -ext WixVsExtension -ext WixNetFxExtension  -ext WixUIExtension -loc %WIX_UI_PATH% product.wixobj files.wixobj
+popd
+
+REM %CHMOD% u+rx LICENSE-fsharp.rtf
+%MSIDUMP% -list -format:f InstallFSharpPowerPack.msi > InstallFSharpPowerPack.msi.files
+
+REM # Build the zip at the same time, from the same files (note, no need to sign the zip%.
+del  FSharpPowerPack.zip
+%PKZIP% -@ FSharpPowerPack.zip < zip.args
+
+ at echo off
+REM Process to sign the MSI
+REM 
+REM %MKDIR% -p %deployment_cpx_tree%\unsigned-msi
+REM %RM% -rf %deployment_cpx_tree%\signed-msi
+REM %CP% %tree%\InstallFSharpPowerPack.msi %deployment_cpx_tree%\unsigned-msi
+REM %CHMOD% a+rwx %deployment_cpx_tree%\unsigned-msi\InstallFSharpPowerPack.msi
+REM %SUBMITTER% %NOSIGN% -src %deployment_cpx_tree%\unsigned-msi -dst %deployment_cpx_tree%\signed-msi -description "Microsoft Research F# %ILX_VERSION% Installer" %APPROVER_OPTIONS%
+REM %CP% %deployment_cpx_tree%\signed-msi\InstallFSharpPowerPack.msi $@
+REM %MSIDUMP% -list -format:pfv InstallFSharpPowerPack.msi | sort > %tree%\InstallFSharpPowerPack.msi.files.txt
+REM %DIFF% %tree%\InstallFSharpPowerPack.msi.files.txt src\wix\regression.msi.files.txt
+REM %MKDIR% -p %release_config_drop%
+REM %CP% %deployment_cpx_tree%\signed-msi\InstallFSharpPowerPack.msi %release_config_drop%\InstallFSharpPowerPack.msi
+REM %CP% %tree%\fsharp.zip                %release_config_drop%\fsharp.zip
+REM %DATE% > %release_config_drop%\timestamp.txt
+REM %FCIV% %release_config_drop% > %release_config_drop%\hashes.txt
+
+endlocal
diff --git a/src/MsiInstaller/generateWixFileEntries.fsx b/src/MsiInstaller/generateWixFileEntries.fsx
new file mode 100755
index 0000000..1c5d8f3
--- /dev/null
+++ b/src/MsiInstaller/generateWixFileEntries.fsx
@@ -0,0 +1,314 @@
+//----------------------------------------------------------------------------
+//
+
+open System
+open System.IO
+open System.Text
+open System.Security.Cryptography
+
+let argv = System.Environment.GetCommandLineArgs()
+let targetDirectoryTree = argv.[argv.Length - 1]
+
+
+module List = 
+    let rec contains x l = match l with [] -> false | h::t -> x = h || contains x t
+    let mem x l = contains x l
+
+    let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
+
+    let rec assoc x l = 
+        match l with 
+        | [] -> indexNotFound()
+        | ((h,r)::t) -> if x = h then r else assoc x t
+
+    let rec memAssoc x l = 
+        match l with 
+        | [] -> false
+        | ((h,_)::t) -> x = h || memAssoc x t
+
+    let rec removeAssoc x l = 
+        match l with 
+        | [] -> []
+        | (((h,_) as p) ::t) -> if x = h then t else p:: removeAssoc x t
+
+
+let sourcePath = "."  // no trailing / 
+
+let gac20s =
+  [ "bin\gac\FSharp.Compiler.CodeDom.dll",[];
+    "bin\gac\FSharp.PowerPack.dll",[];
+    "bin\gac\FSharp.PowerPack.Compatibility.dll",[];
+    "bin\gac\FSharp.PowerPack.Linq.dll",[];
+    "bin\gac\FSharp.PowerPack.Metadata.dll",[];
+// Include these if we ever ship policy DLLs again
+//    "bin/gac/policy.1.9.FSharp.PowerPack.dll",            ["bin/gac/policy.1.9.FSharp.PowerPack.dll.config"];
+//    "bin/gac/policy.1.9.FSharp.PowerPack.Linq.dll",       ["bin/gac/policy.1.9.FSharp.PowerPack.Linq.dll.config"];
+    ]
+
+let shortcuts = 
+  [ // "README-fsharp.html"  , "F# Release Notes" ;
+    // "bin/fsi.exe", "F# Interactive (Console)";
+    // "doc/README-vfsi.html", "F# Interactive (Visual Studio)";
+    // "doc/README-samples.html", "F# Samples";
+  ]
+
+//----------------------------------------------------------------------------
+// md5
+//----------------------------------------------------------------------------
+
+let md5 = new MD5CryptoServiceProvider()
+let md5sum (text:string) =
+    let bytes = System.Text.Encoding.ASCII.GetBytes text 
+    md5.ComputeHash(bytes)
+
+let md5Text (text:string) =
+    let bytes = System.Text.Encoding.ASCII.GetBytes text 
+    let bytes = md5.ComputeHash(bytes) 
+    let x = Array.map int bytes 
+    sprintf "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
+      x.[0] x.[1] x.[2]  x.[3]  x.[4]  x.[5]  x.[6]  x.[7]
+      x.[8] x.[9] x.[10] x.[11] x.[12] x.[13] x.[14] x.[15]
+
+
+//----------------------------------------------------------------------------
+// read lines from file
+//----------------------------------------------------------------------------
+
+let copyFilesAndPreparePaths (installLstFile:string) =
+    [ for line in System.IO.File.ReadAllLines installLstFile do
+          match line.Split([| ' ' |], StringSplitOptions.RemoveEmptyEntries) with 
+          [| fullSourcePath; partialTargetDirectory |] -> 
+               let fullTargetDirectory = Path.Combine(targetDirectoryTree, partialTargetDirectory)
+               Directory.CreateDirectory fullTargetDirectory  |> ignore
+               let partialTargetPath = Path.Combine (partialTargetDirectory, Path.GetFileName fullSourcePath)
+               let fullTargetPath = Path.Combine (fullTargetDirectory, Path.GetFileName fullSourcePath)
+               printfn "%s --> %s" fullSourcePath fullTargetPath
+               if File.Exists fullTargetPath then 
+                   File.SetAttributes(fullTargetPath, FileAttributes.Normal); 
+               File.Copy(fullSourcePath, fullTargetPath, true)
+               yield partialTargetPath
+          | [| |] -> ()
+          | _ -> failwith "Invalid file entry in install.lst: '%s'. Two entries expected on line" line ]
+    |> Seq.distinct
+    |> Seq.toList
+
+
+//----------------------------------------------------------------------------
+// file projections
+// leading/path/name/filename projections 
+// fileID   = leading.path.name.filename    
+// filePath = leading;path;name;filename as string list 
+//----------------------------------------------------------------------------
+
+let fixupID (str:string) =
+  // Only a-z, digits, underscore, periods.
+  let sb = new StringBuilder() 
+  let add c =
+    if Char.IsLetter(c) || Char.IsDigit(c) || c = '_' || c = '.' then
+      ignore (sb.Append(c))
+    else
+      ignore (sb.Append(int c))
+  sb.Append("ID") |> ignore;
+  String.iter add str;
+  let str = sb.ToString() 
+  if str.Length < 64 then
+    str
+  else
+    let hash = md5Text str 
+    "HASH_" + hash + "_" + str.Substring(str.Length - 32)  // 32 hash + 32 trailing text = 64 + 8 spare for prefixes 
+    
+let filePath   (path:string) = path.Split([|'\\';'/'|]) |> Array.toList
+let fileID     (path:string) = String.Join(".",Array.ofList<string> (filePath path)) |> fixupID
+let trailID    trail         = String.Join(".",Array.ofList<string> trail)           |> fixupID
+let fileName   (path:string) = Path.GetFileName(path)
+let fileDir    (path:string) = Path.GetDirectoryName(path)
+let fileDPath  (path:string) = Path.GetDirectoryName(path) |> filePath
+let fileDirID  (path:string) = path |> fileDir |> fileID    
+let fileCompID (path:string) = String.Join(".",Array.ofList ("FileComp" :: filePath path)) |> fixupID
+let gacCompID  (path:string) = String.Join(".",Array.ofList ("GACComp"  :: filePath path)) |> fixupID    
+let keyPathName (path:string) = String.Join(".",Array.ofList ("KeyPath"  :: filePath path)) // not an ID, but a registry key name, so no length limit 
+
+let guidOfID id =
+  let bytes = md5sum ("FSHARP_GUID:" + id) 
+  let x = Array.map int bytes 
+  sprintf "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
+    x.[0] x.[1] x.[2]  x.[3]  x.[4]  x.[5]  x.[6]  x.[7]
+    x.[8] x.[9] x.[10] x.[11] x.[12] x.[13] x.[14] x.[15]
+
+
+//----------------------------------------------------------------------------
+// dir tree structure
+//----------------------------------------------------------------------------
+    
+type dir = {id:string;subs:(string*dir)list}
+let rec addPath ndirs trail = function
+  | []      -> ndirs
+  | (p::ps) ->
+      let trail = trail @ [p] 
+      if List.memAssoc p ndirs then
+        let dir,ndirs = List.assoc p ndirs, List.removeAssoc p ndirs 
+        let dir = {dir with subs = addPath dir.subs trail ps} 
+        (p,dir)::ndirs
+      else
+        let subs = addPath [] trail ps 
+        let dir = {id = trailID trail; subs = subs } 
+        (p,dir)::ndirs
+
+let collectFileDT tree file = 
+    let dname = Path.GetDirectoryName(file) 
+    let dpath = dname.Split([|'\\'|]) |> Array.toList 
+    if dname = "" then tree else
+    addPath tree [] dpath
+
+
+//----------------------------------------------------------------------------
+// write - DirectoryTree, Component of Files
+// Write Directory structure.
+// Write Component for each directory containing it's files.
+// Write final component group collecting all directory components together.
+//----------------------------------------------------------------------------
+    
+let spaces n = String.replicate n " "
+
+let mergeMap f xs =
+    let infos = List.map f xs 
+    List.collect (fun (a,b,d) -> a) infos,
+    List.collect (fun (a,b,d) -> b) infos,
+    List.collect (fun (a,b,d) -> d) infos
+
+let mergeIds infos = mergeMap (fun x -> x) infos
+
+let writeGACComponent gacTab fp indent manFile =
+    let gacId = gacCompID manFile 
+    let guid  = guidOfID gacId 
+    let manFileID   = "GF" + fileID manFile 
+    fprintfn fp "%s<Component Id='%s' Guid='%s' DiskId='1' >" (spaces indent) gacId guid;
+    fprintfn fp "%s<File Id='%s' Name='%s' Source='%s/%s' Assembly='.net' KeyPath='yes' />"
+      (spaces (indent+2)) manFileID (fileName manFile) sourcePath manFile;
+    List.assoc manFile gacTab |> List.iter (fun auxFile -> 
+      let auxFileID   = "GF" + fileID auxFile 
+      fprintfn fp "%s<File Id='%s' Name='%s' Source='%s/%s'  />"
+        (spaces (indent+2)) auxFileID (fileName auxFile) sourcePath auxFile
+    );
+    fprintfn fp "%s</Component>" (spaces indent);  
+    gacId
+
+
+let writeDirectoryFileComponent fp indent dirID dpath file =
+    if dpath = fileDPath file then
+      let compId = fileCompID file 
+      let guid   = guidOfID compId 
+      let fid = fileID file 
+      if List.memAssoc file gac20s then 
+          [],[],[writeGACComponent gac20s fp indent file ]
+      elif (gac20s |> List.exists (fun (man,auxs) -> List.mem file auxs)) then 
+          [],[],[] // written by writeGACComponent 
+      else 
+          let isShortcut = List.memAssoc file shortcuts
+          fprintfn fp "%s<Component Id='%s' Guid='%s' DiskId='1' >" (spaces indent) compId guid;
+          fprintfn fp "%s<File Id='%s' Name='%s' Source='%s/%s'>" (spaces (indent+2)) fid (fileName file) sourcePath file;
+          if isShortcut then 
+            fprintfn fp "%s<Shortcut Id='Shortcut.%s'  Directory='FSharpMenu' Name='%s'  Description='Shortcut to %s' Advertise='no' />" (spaces (indent+4)) fid (List.assoc file shortcuts) file;
+          fprintfn fp "%s</File>" (spaces (indent+2));
+          if isShortcut then 
+            fprintfn fp "%s<RegistryValue Root='HKCU' Key='Software\\Microsoft Research\\FSharp\\ILX-VERSION\\%s' Type='string' Value='1' KeyPath='yes' />" (spaces (indent+2)) (keyPathName file);
+          if (fileName file) = "FSharp.ProjectSystem.FSharp.dll" then 
+            fprintf fp @"
+              <CreateFolder/>
+              "
+          fprintfn fp "%s</Component>" (spaces indent);
+          [compId],[],[]
+    else
+      [],[],[]
+
+let writeDirectoryFileComponents fp indent dirID dpath files =
+    mergeMap (writeDirectoryFileComponent fp indent dirID dpath) files
+
+let rec writeDTree fp indent files dpath (name,dir) =
+    let dpath = dpath @ [name] 
+    fprintfn fp "%s<Directory Id='%s' Name='%s'>" (spaces indent) dir.id name;
+    let comps    = writeDirectoryFileComponents fp (indent+2) dir.id dpath files in
+    let subcomps = mergeMap (writeDTree fp (indent+2) files dpath) dir.subs in
+    fprintfn fp "%s</Directory>" (spaces indent);
+    mergeIds [comps;subcomps]
+
+let writeComponentGroup fp indent id compIds =
+    fprintfn fp "%s<ComponentGroup Id='%s'>" (spaces indent) id;
+    let writeComponentRef compId =
+      fprintfn fp "%s<ComponentRef Id='%s' />" (spaces (indent+2)) compId
+    List.iter writeComponentRef compIds;
+    fprintfn fp "%s</ComponentGroup>" (spaces indent)
+
+
+//----------------------------------------------------------------------------
+// generate merge module wxs for filelist-
+//----------------------------------------------------------------------------
+
+let files    = copyFilesAndPreparePaths "install.lst"
+List.iter (fun f -> printfn "File: %s" f) files
+let _ =
+    use zipArgs = System.IO.File.CreateText "zip.args"
+    files |> List.iter (fun f -> fprintfn zipArgs "%s\%s " targetDirectoryTree  f)
+
+// Sanity check called-out files are present
+let fileSet     = Set.ofList files
+let gac20Set    = Set.ofList (List.map fst gac20s)
+let shortcutSet = Set.ofList (List.map fst shortcuts)
+let checkEmpty descr a = if not (Set.isEmpty a) then
+                            failwith ("Checking " + descr + " files. Could not find: " + String.concat " and " (Set.toList a))
+checkEmpty "gac20"    (gac20Set    - fileSet)
+checkEmpty "shortcut" (shortcutSet - fileSet)
+
+// Write files.wxs...
+let fp = System.IO.File.CreateText "files.wxs"
+
+fprintf fp @"<?xml version='1.0'?>
+<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'
+     xmlns:netfx='http://schemas.microsoft.com/wix/NetFxExtension'>
+   <Fragment Id='CoreFilesFragment'>
+      <DirectoryRef Id='INSTALLDIR'>
+"
+let indent = 6
+let tree = List.fold collectFileDT [] files
+let compIds,comp20Ids,gac20Ids =
+  mergeIds [writeDirectoryFileComponents fp (indent+3) "" [""] files;
+            mergeMap (writeDTree fp (indent+3) files []) tree]
+fprintfn fp "      </DirectoryRef>"
+
+writeComponentGroup fp indent "CoreFiles1ComponentGroup" compIds
+writeComponentGroup fp indent "CoreFiles2ComponentGroup" comp20Ids
+writeComponentGroup fp indent "GACFiles2ComponentGroup"  gac20Ids
+fprintf fp @"
+   </Fragment>
+</Wix>
+"
+
+fp.Close()
+exit 0
+(*
+            <ProgId Id='VisualStudio.fs.9.0' Description='Visual F# Source file' Icon='IDbin.FSharp.ProjectSystem.FSharp.dll' IconIndex='0' >
+              <Extension Id='fs' ContentType='application/fsharp-source' >
+                <Verb Id ='open' Command='Open' TargetProperty='VS90DEVENV' Argument='""%%1""' />
+              </Extension>
+            </ProgId>
+            <ProgId Id='VisualStudio.fsi.9.0' Description='Visual F# Signature file' Icon='IDbin.FSharp.ProjectSystem.FSharp.dll' IconIndex='1' >           
+              <Extension Id='fsi' ContentType='application/fsharp-signature' >
+                <Verb Id ='open' Command='Open' TargetProperty='VS90DEVENV' Argument='""%%1""' />
+              </Extension>
+            </ProgId>
+            <ProgId Id='VisualStudio.fsx.9.0' Description='Visual F# Script file' Icon='IDbin.FSharp.ProjectSystem.FSharp.dll' IconIndex='2' >
+              <Extension Id='fsx' ContentType='application/fsharp-script' >
+                <Verb Id ='open'       Command='Open'                    TargetProperty='VS90DEVENV' Argument='""%%1""' />
+              </Extension>
+            </ProgId>
+            <ProgId Id='VisualStudio.fsscript.9.0' Description='Visual F# Script file' Icon='IDbin.FSharp.ProjectSystem.FSharp.dll' IconIndex='2' >
+              <Extension Id='fsscript' ContentType='application/fsharp-script' >
+                <Verb Id ='open'       Command='Open'                    TargetProperty='VS90DEVENV' Argument='""%%1""' />
+              </Extension>
+            </ProgId>
+            <ProgId Id='VisualStudio.fsproj.9.0' Description='Visual F# Project file' Icon='IDbin.FSharp.ProjectSystem.FSharp.dll' IconIndex='3' >
+              <Extension Id='fsproj' ContentType='application/fsharp-project' >
+                <Verb Id ='open'       Command='Open'                    TargetProperty='VS90DEVENV' Argument='""%%1""' />
+              </Extension>
+            </ProgId>
+*)
diff --git a/src/MsiInstaller/install.lst b/src/MsiInstaller/install.lst
new file mode 100755
index 0000000..c4c06b9
--- /dev/null
+++ b/src/MsiInstaller/install.lst
@@ -0,0 +1,41 @@
+..\..\Release\bin\FSharp.Compiler.CodeDom.dll bin
+..\..\Release\bin\FSharp.Compiler.CodeDom.dll bin\gac
+..\..\Release\bin\FSharp.Compiler.CodeDom.pdb bin
+..\..\Release\bin\FSharp.Compiler.CodeDom.xml bin
+..\..\Release\bin\FSharp.PowerPack.Build.Tasks.dll bin
+..\..\Release\bin\FSharp.PowerPack.Build.Tasks.pdb bin
+..\..\Release\bin\FSharp.PowerPack.Build.Tasks.xml bin
+..\..\Release\bin\FSharp.PowerPack.dll bin
+..\..\Release\bin\FSharp.PowerPack.pdb bin
+..\..\Release\bin\FSharp.PowerPack.xml bin
+..\..\Release\bin\FSharp.PowerPack.dll bin\gac
+..\..\Release\bin\FSharp.PowerPack.Compatibility.dll bin
+..\..\Release\bin\FSharp.PowerPack.Compatibility.pdb bin
+..\..\Release\bin\FSharp.PowerPack.Compatibility.xml bin
+..\..\Release\bin\FSharp.PowerPack.Compatibility.dll bin\gac
+..\..\Release\bin\FSharp.PowerPack.Linq.dll bin
+..\..\Release\bin\FSharp.PowerPack.Linq.dll bin\gac
+..\..\Release\bin\FSharp.PowerPack.Linq.pdb bin
+..\..\Release\bin\FSharp.PowerPack.Linq.xml bin
+..\..\Release\bin\FSharp.PowerPack.Metadata.dll bin
+..\..\Release\bin\FSharp.PowerPack.Metadata.dll bin\gac
+..\..\Release\bin\FSharp.PowerPack.Metadata.pdb bin
+..\..\Release\bin\FSharp.PowerPack.Metadata.xml bin
+..\..\Release\bin\FSharp.PowerPack.Parallel.Seq.dll bin
+..\..\Release\bin\FSharp.PowerPack.Parallel.Seq.dll bin\gac
+..\..\Release\bin\FSharp.PowerPack.Parallel.Seq.pdb bin
+..\..\Release\bin\FSharp.PowerPack.Parallel.Seq.xml bin
+..\..\Release\bin\fshtmldoc.exe bin
+..\..\Release\bin\fslex.exe bin
+..\..\Release\bin\fsyacc.exe bin
+..\FSharp.PowerPack.Build.Tasks\FSharp.PowerPack.targets bin
+..\..\Silverlight\v3.0\Release\bin\FSharp.PowerPack.dll Silverlight\v3.0
+..\..\Silverlight\v3.0\Release\bin\FSharp.PowerPack.pdb Silverlight\v3.0
+..\..\Silverlight\v3.0\Release\bin\FSharp.PowerPack.Compatibility.dll Silverlight\v3.0
+..\..\Silverlight\v3.0\Release\bin\FSharp.PowerPack.Compatibility.pdb Silverlight\v3.0
+..\..\Silverlight\v4.0\Release\bin\FSharp.PowerPack.dll Silverlight\v4.0
+..\..\Silverlight\v4.0\Release\bin\FSharp.PowerPack.pdb Silverlight\v4.0
+..\..\Silverlight\v4.0\Release\bin\FSharp.PowerPack.Compatibility.dll Silverlight\v4.0
+..\..\Silverlight\v4.0\Release\bin\FSharp.PowerPack.Compatibility.pdb Silverlight\v4.0
+
+License.rtf .
diff --git a/src/MsiInstaller/product.wxs b/src/MsiInstaller/product.wxs
new file mode 100755
index 0000000..f42979f
--- /dev/null
+++ b/src/MsiInstaller/product.wxs
@@ -0,0 +1,232 @@
+<?xml version='1.0'?>
+<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
+  <Product Id='0462F21C-5C36-4494-B00F-847362519840'
+           Name='F# Power Pack, Version 2.0.0.1'
+           Language='1033'
+           Version='2.0.0.1'
+           UpgradeCode='FF39AC9F-A471-4DDA-BB96-847362519841'
+           Manufacturer='Microsoft Corporation'>
+    <Package Id='*'
+              Description='F# Power Pack 2.0.0.1 Installer package'
+              Comments='See http://codeplex/fsharppowerpack/ for details.'
+              Manufacturer='Microsoft Corporation'
+              InstallerVersion='200'
+              Compressed='yes' />
+    <!-- import from WixVsExtension -->
+    <PropertyRef Id="VS90DEVENV" />
+    <!-- 
+    <PropertyRef Id="VS90_ITEMTEMPLATES_DIR" />
+    <PropertyRef Id="VS90_PROJECTTEMPLATES_DIR" />
+    <PropertyRef Id="VS90_ROOT_FOLDER" />
+    <CustomActionRef Id="VS90Setup" />
+-->
+    <Media Id='1' Cabinet='FSCAB.cab' EmbedCab='yes' />
+    <!-- Media Id='2' Cabinet='VCCRT.cab' EmbedCab='yes' /-->
+
+    <Directory Id='TARGETDIR' Name='SourceDir'>
+      <Directory Id='ProgramFilesFolder' Name='PFiles' FileSource='.' SourceName='.'>
+        <Directory Id='INSTALLDIR' Name='FSharpPowerPack-2.0.0.0' FileSource='.' SourceName='.'>
+          <Component Id='FSharp.InstallLocation' Guid='5c462ddc-ac10-4d99-af6f-847362519842'>
+            <RegistryValue Root='HKLM' Key='Software\Microsoft\.NETFramework\AssemblyFolders\FSharp.PowerPack-2.0.0.0' Type='string' Value='[INSTALLDIR]\bin' KeyPath='no' />
+            <RegistryValue Root='HKLM' Key='Software\Microsoft\.NETFramework\AssemblyFolders\FSharp.PowerPack-2.0.0.0' Name='Description' Type='string' Value='FSharp Power Pack Assembly Directory' KeyPath='no' />
+            <RegistryValue Root='HKLM' Key='Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\FSharp.PowerPack-2.0.0.0' Type='string' Value='[INSTALLDIR]\bin' KeyPath='no' />
+            <RegistryValue Root='HKLM' Key='Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\FSharp.PowerPack-2.0.0.0' Name='Description' Type='string' Value='FSharp Power Pack Assembly Directory' KeyPath='no' />
+            <RegistryValue Root='HKLM' Key='Software\Microsoft\Microsoft SDKs\Silverlight\v3.0\AssemblyFoldersEx\FSharp.PowerPack' Type='string' Value='[INSTALLDIR]\Silverlight\v3.0' KeyPath='no' />
+            <RegistryValue Root='HKLM' Key='Software\Microsoft\Microsoft SDKs\Silverlight\v4.0\AssemblyFoldersEx\FSharp.PowerPack' Type='string' Value='[INSTALLDIR]\Silverlight\v4.0' KeyPath='no' />
+          </Component>
+          <Component Id='SafeImports' Guid='F7FB257C-9AAF-47A0-9CA8-847362519843' >
+            <RegistryValue Root='HKLM' Key='Software\Microsoft\VisualStudio\9.0\MSBuild\SafeImports' Name='FSharp-1.0-PowerPack' Type='string' Value='%ProgramFiles%\MSBuild\FSharp\1.0\FSharp.PowerPack.targets' KeyPath='no' />
+          </Component>
+        </Directory><!-- INSTALLDIR -->
+        <Directory Id='MSBuildExtensionsDir' Name='MSBuild'>
+          <Directory Id='MSBuildExtensionsDirFS' Name='FSharp'>
+            <Directory Id='MSBuildExtensionsDirFSVersion' Name='1.0'>
+              <Component Id='MSBuild' Guid='6ECAFBBB-299A-41FA-8D82-847362519845'>
+                <File Id='PowerPackMSBuildTargets' Name='FSharp.PowerPack.targets' DiskId='1' Source='.\bin\FSharp.PowerPack.targets' Vital='yes' />
+                <File Id='PowerPackMSBuildTask' Name='FSharp.PowerPack.Build.Tasks.dll' DiskId='1' Source='.\bin\FSharp.PowerPack.Build.Tasks.dll' Vital='yes' />
+              </Component>
+            </Directory><!-- 1.0 -->
+          </Directory><!-- FSharp -->
+        </Directory><!-- MSBuild -->
+      </Directory><!-- Prog Files -->
+<!-- ADD THIS TO INSTALL PROGRAM MENU SHORTCUT ENTRIES
+      <Directory Id='ProgramMenuFolder' Name='Programs'>
+        <Directory Id='FSharpMenu' Name='Microsoft F# CTP 2.0.0.0' >
+          <Component Id='FSharp.Shortcuts' Guid='800A6461-2538-41f0-BC8E-203AAF97EE28'>
+            <RegistryValue Root='HKCU' Key='Software\Microsoft Research\FSharp\2.0.0.0\KeyPath.Shortcuts' Type='string' Value='1' KeyPath='yes' />
+            <CreateFolder />
+            <RemoveFolder Id='FSharp.Menu.Remove' On='uninstall' />
+          </Component>
+        </Directory>
+      </Directory>
+-->
+      <!-- ADD THIS TO INSTALL VS PROJECT TEMPLATES
+      <Directory Id='VS90_PROJECTTEMPLATES_DIR' Name='Vs2008ProjTemplates'>
+        <Directory Id='FSTemplates' Name='FSharp' FileSource='.' SourceName='.'>
+          <Component Id='ProjectTemplates' Guid='77D9683F-82E4-422A-A3CD-847362519846'>
+            <File Id='ProjTemplate1' Name='ConsoleApplication.zip' DiskId='1' Source='.\bin\Templates\ProjectTemplates\ConsoleApplication.zip' Vital='yes' />
+            <File Id='ProjTemplate2' Name='Library.zip' DiskId='1' Source='.\bin\Templates\ProjectTemplates\Library.zip' Vital='yes' />
+            <File Id='ProjTemplate3' Name='Tutorial.zip' DiskId='1' Source='.\bin\Templates\ProjectTemplates\Tutorial.zip' Vital='yes' />
+            </Component>
+          </Directory>
+        </Directory>
+-->
+      <!-- ADD THIS TO INSTALL VS ITEM TEMPLATES
+      <Directory Id='VS90_ITEMTEMPLATES_DIR' Name='Vs2008ItemTemplates'>
+        <Directory Id='FSItemTemplates' Name='FSharp' FileSource='.' SourceName='.'>
+          <Component Id='ItemTemplates' Guid='2FE31519-FEF0-422e-B0ED-847362519847'>
+            <File Id='ItemTemplate1' Name='CodeFile.zip' DiskId='1' Source='.\bin\Templates\ItemTemplates\CodeFile.zip' Vital='yes' />
+            <File Id='ItemTemplate2' Name='SignatureFile.zip' DiskId='1' Source='.\bin\Templates\ItemTemplates\SignatureFile.zip' Vital='yes' />
+            <File Id='ItemTemplate3' Name='ScriptFile.zip' DiskId='1' Source='.\bin\Templates\ItemTemplates\ScriptFile.zip' Vital='yes' />
+          </Component>
+        </Directory>
+      </Directory>
+-->
+<!-- ADD THIS TO INSTALL VS SCRIPT ITEMS
+      <Directory Id='VS90_ROOT_FOLDER' Name='Vs2008Root'>
+        <Directory Id='Common7' Name='Common7' FileSource='.' SourceName='.'>
+          <Directory Id='IDE' Name='IDE' FileSource='.' SourceName='.'>
+            <Directory Id='NewScriptItems' Name='NewScriptItems' FileSource='.' SourceName='.'>
+              <Component Id='NewScriptItems' Guid='983077B0-7203-4d4e-AAB5-847362519848'>
+                <File Id='FileTemplate1' Name='Script.fsx' DiskId='1' Source='.\bin\Templates\FileTemplates\Script.fsx' Vital='yes' />
+                <File Id='FileTemplate2' Name='NewFSharpScriptItems.vsdir' DiskId='1' Source='.\bin\Templates\FileTemplates\NewFSharpScriptItems.vsdir' Vital='yes' />
+              </Component>
+            </Directory>
+          </Directory>
+        </Directory>
+      </Directory>
+-->
+    </Directory><!-- TARGETDIR -->
+
+    <UI>
+      <InstallUISequence>
+      </InstallUISequence>
+    </UI>
+
+    <!-- Require .NET 2.0 (i.e. 2.0, 3.0 or 3.5) to be prior installed (.NET 4.0 alone is not enough) -->
+    <Condition Message='.NET Framework 2.0 must be installed prior to installation of this F# product.'>
+      FRAMEWORK20 = "50727-50727"
+    </Condition>
+
+    <Property Id="FRAMEWORK10">
+      <RegistrySearch Id='Framework10Registry' Type='raw'  Root='HKLM' Key='Software\Microsoft\.NETFramework\policy\v1.0' Name='3705' />
+    </Property>
+
+    <Property Id='FRAMEWORK20'>
+      <RegistrySearch Id='Framework20Registry' Type='raw' Root='HKLM' Key='Software\Microsoft\.NETFramework\Policy\v2.0' Name='50727' />
+    </Property>
+    
+    <Feature Id='Complete' Title='Complete features' Description='Complete features'
+             Display='expand' Level='1' ConfigurableDirectory='INSTALLDIR'>
+
+      <Feature Id='CoreFilesFeature1' Title='Install F# distribution'
+               Description='You need this. It copies the distribution to Program Files.' Level='1'>
+        <ComponentGroupRef Id='CoreFiles1ComponentGroup' />
+      </Feature>
+
+      <Feature Id='CoreFilesFeature2' Title='Install F# distribution files for .NET 2.0'
+               Description='Copy the .NET 2.0 relevant files to Program Files.' Level='1'>
+        <!-- note, feature level is 0 meaning off unless condition enables it -->
+        <Condition Level='0'>
+          NOT (FRAMEWORK20 = "50727-50727")
+        </Condition>
+        <ComponentGroupRef Id='CoreFiles2ComponentGroup' />
+<!--        <ComponentRef Id='FSharp.FSI.FileAssociations' />        -->
+      </Feature>
+
+      <Feature Id='GACFilesFeature2' Title='Install GAC DLLs for .NET 2.0'
+               Description='Install DLLs in the GAC for .NET 2.0.' Level='1'>
+        <Condition Level='0'>
+          NOT (FRAMEWORK20 = "50727-50727")
+        </Condition>
+        <ComponentGroupRef Id='GACFiles2ComponentGroup' />
+      </Feature>
+
+      <Feature Id='MSBuildFeature' Title='Install DLLs for MSBuild'
+                Description='Install DLLs for MSBuild' Level='1'>
+        <Condition Level='0'>
+          NOT (FRAMEWORK20 = "50727-50727")
+        </Condition>
+        <ComponentRef Id='SafeImports' />
+        <ComponentRef Id='MSBuild' />
+      </Feature>
+
+      <!--
+      <Feature Id='ProjectSystemFeature' Title='Install Registry Key'
+               Description='Install Registry Key.' Level='1'>
+        <Condition Level='0'>
+          NOT (VS90DEVENV)
+        </Condition>
+        <ComponentRef Id='InstalledProduct' />
+      </Feature>
+      
+      <Feature Id='ProjectTemplatesFeature' Title='Install VS Project Templates'
+               Description='Install Visual Studio Project Templates' Level='1'>
+        <Condition Level='0'>
+          NOT (VS90DEVENV)
+        </Condition>
+        <ComponentRef Id='ProjectTemplates' />
+      </Feature>
+-->
+<!--
+      
+      <Feature Id='ItemTemplatesFeature' Title='Install VS Item Templates'
+               Description='Install Visual Studio Item Templates' Level='1'>
+        <Condition Level='0'>
+          NOT (VS90DEVENV)
+        </Condition>
+        <ComponentRef Id='ItemTemplates' />
+      </Feature>
+-->
+      <!--
+      <Feature Id='NewScriptTemplatesFeature' Title='Install VS New File Templates'
+               Description='Install Visual Studio New File Templates' Level='1'>
+        <Condition Level='0'>
+          NOT (VS90DEVENV)
+        </Condition>
+        <ComponentRef Id='NewScriptItems' />
+      </Feature>
+-->
+      
+<!-- ADD THIS TO INSTALL PROGRAM MENU SHORTCUT ENTRIES
+      <Feature Id='Shortcuts' Title='Start menu shortcuts'
+               Description='Adds shortcuts to README, samples and documentation.' Level='1'>
+        <ComponentRef Id='FSharp.Shortcuts' />
+      </Feature>
+-->
+
+      <!-- TODO below is not quite right, lang service is part of installLocation -->
+      <Feature Id='InstallLocation' Title='Registry entries for location of compiler DLLs'
+               Description='Adds registry entries that indicate where the FSharp.Compiler.dll and fsc.exe binaries can be found on a target machine.' Level='1'>
+        <ComponentRef Id='FSharp.InstallLocation' />
+      </Feature>
+
+    </Feature>
+
+<!-- ENABLE THIS IF ANY VS PROJECT TEMPLATES OR ITEMS GET INSTALLED
+    <CustomAction Id='CA_VS90Setup'
+                  Property='VS90DEVENV'
+                  ExeCommand=' /setup'
+                  Execute='commit'
+                  Impersonate='no'
+                  Return='ignore'>
+    </CustomAction>
+-->
+    
+    <InstallExecuteSequence>
+      <RemoveRegistryValues/>
+      <RemoveFiles/>
+      <InstallFiles/>
+      <WriteRegistryValues/>
+      <!-- ENABLE THIS IF ANY VS PROJECT TEMPLATES OR ITEMS GET INSTALLED
+      <Custom Action='CA_VS90Setup'  After='MsiPublishAssemblies'></Custom>
+      -->
+    </InstallExecuteSequence>
+
+    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
+    <WixVariable Id="WixUILicenseRtf" Value="License.rtf" />
+
+    <UIRef Id="WixUI_InstallDir" />
+    <UIRef Id="WixUI_ErrorProgressText" />
+  </Product>
+</Wix>
diff --git a/src/SilverlightTester/App.xaml b/src/SilverlightTester/App.xaml
new file mode 100755
index 0000000..54f5cc2
--- /dev/null
+++ b/src/SilverlightTester/App.xaml
@@ -0,0 +1,8 @@
+<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
+             x:Class="SilverlightTester.App"
+             >
+    <Application.Resources>
+        
+    </Application.Resources>
+</Application>
diff --git a/src/SilverlightTester/App.xaml.cs b/src/SilverlightTester/App.xaml.cs
new file mode 100755
index 0000000..e3a5508
--- /dev/null
+++ b/src/SilverlightTester/App.xaml.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+namespace SilverlightTester
+{
+    public partial class App : Application
+    {
+
+        public App()
+        {
+            this.Startup += this.Application_Startup;
+            this.Exit += this.Application_Exit;
+            this.UnhandledException += this.Application_UnhandledException;
+
+            InitializeComponent();
+        }
+
+        private void Application_Startup(object sender, StartupEventArgs e)
+        {
+            this.RootVisual = new MainPage();
+        }
+
+        private void Application_Exit(object sender, EventArgs e)
+        {
+
+        }
+
+        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
+        {
+            // If the app is running outside of the debugger then report the exception using
+            // the browser's exception mechanism. On IE this will display it a yellow alert 
+            // icon in the status bar and Firefox will display a script error.
+            if (!System.Diagnostics.Debugger.IsAttached)
+            {
+
+                // NOTE: This will allow the application to continue running after an exception has been thrown
+                // but not handled. 
+                // For production applications this error handling should be replaced with something that will 
+                // report the error to the website and stop the application.
+                e.Handled = true;
+                Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
+            }
+        }
+
+        private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
+        {
+            try
+            {
+                string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
+                errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");
+
+                System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");");
+            }
+            catch (Exception)
+            {
+            }
+        }
+    }
+}
diff --git a/src/SilverlightTester/MainPage.xaml b/src/SilverlightTester/MainPage.xaml
new file mode 100755
index 0000000..ff12514
--- /dev/null
+++ b/src/SilverlightTester/MainPage.xaml
@@ -0,0 +1,13 @@
+<UserControl x:Class="SilverlightTester.MainPage"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    mc:Ignorable="d"
+    d:DesignHeight="389" d:DesignWidth="734">
+
+    <Grid x:Name="LayoutRoot" Background="White">
+        <Button Content="Run tests" Height="23" HorizontalAlignment="Left" Margin="15,10,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
+        <ListBox Height="350" Margin="5,39,12,0" Name="testResults" VerticalAlignment="Top" />
+    </Grid>
+</UserControl>
diff --git a/src/SilverlightTester/MainPage.xaml.cs b/src/SilverlightTester/MainPage.xaml.cs
new file mode 100755
index 0000000..efbfde9
--- /dev/null
+++ b/src/SilverlightTester/MainPage.xaml.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Reflection;
+using System.Threading;
+
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+namespace SilverlightTester
+{
+    public partial class MainPage : UserControl
+    {
+        public MainPage()
+        {
+            InitializeComponent();
+        }
+
+        private static void FindAndExecuteMethodWithAttribute(Type t, object instance, Type attributeType)
+        {
+            var methods =
+                    from mi in t.GetMethods(BindingFlags.Public)
+                    where mi.GetCustomAttributes(attributeType, false).Length > 0
+                    select mi;
+            var method = methods.FirstOrDefault();
+            if (method != null)
+                method.Invoke(instance, new object[0]);
+        }
+
+        private class Chainer
+        {
+            private readonly SynchronizationContext sc;
+
+            public Chainer(SynchronizationContext sc)
+            {
+                this.sc = sc;
+            }
+
+        }
+
+        private void Do(SynchronizationContext sc, IEnumerable<Tuple<string, Action>> actions, ref int failures)
+        {
+            foreach (var a in actions)
+            {
+                try
+                {
+                    a.Item2();
+                }
+                catch (Exception e)
+                {
+                    failures++;
+                    var exn = e is TargetInvocationException ? e.InnerException : e;
+                    var message = a.Item1 + " failed:" + exn.Message;
+                    sc.Post(state => { testResults.Items.Add(message); }, null);
+                    return;
+                }
+            }
+        }
+
+        private void OnRunTests(object sender, RoutedEventArgs e)
+        {           
+            testResults.Items.Clear();
+            testResults.Items.Add("Started running tests " + DateTime.Now);
+            var sc = SynchronizationContext.Current;
+            button1.IsEnabled = false;
+            ThreadPool.QueueUserWorkItem(x =>
+            {
+                var failures = 0;
+                var assembly = typeof(FSharp.PowerPack.Unittests.ArrayTests).Assembly;
+                var testFixtures =
+                        from type in assembly.GetExportedTypes()
+                        where type.GetCustomAttributes(typeof(NUnit.Framework.TestFixtureAttribute), true).Length > 0
+                        select type;
+                foreach (var fixture in testFixtures)
+                {
+                    var fixtureName = fixture.Name;
+                    if (fixture.GetCustomAttributes(typeof(NUnit.Framework.IgnoreAttribute), true).Length > 0)
+                    {
+                        sc.Post(state => { testResults.Items.Add(fixtureName + " IGNORED"); }, null);
+                        continue;
+                    }
+                    object o = null;
+                    List<Tuple<string, Action>> list = new List<Tuple<string, Action>>();
+                    list.Add(Tuple.Create<string, Action>(fixtureName + " activate", () => { o = Activator.CreateInstance(fixture); }));
+                    list.Add(Tuple.Create<string, Action>(fixtureName + "setup",
+                                () => { FindAndExecuteMethodWithAttribute(fixture, o, typeof(NUnit.Framework.TestFixtureSetUpAttribute)); }));
+                    list.AddRange(
+                        from mi in fixture.GetMethods()
+                        where mi.GetCustomAttributes(typeof(NUnit.Framework.TestAttribute), false).Length > 0
+                        select Tuple.Create<string, Action>(
+                            fixtureName + "." + mi.Name,
+                            () =>
+                            {
+                                FindAndExecuteMethodWithAttribute(fixture, o, typeof(NUnit.Framework.SetUpAttribute));
+                                try
+                                {
+                                    mi.Invoke(o, new object[0]);
+                                }
+                                finally
+                                {
+                                    FindAndExecuteMethodWithAttribute(fixture, o, typeof(NUnit.Framework.TearDownAttribute));
+                                }
+                                sc.Post(state => { testResults.Items.Add(fixtureName + "." + mi.Name + " passed."); }, null);
+                            }
+                            ));
+                    list.Add(Tuple.Create<string, Action>(fixtureName + "teardown",
+                                () => { FindAndExecuteMethodWithAttribute(fixture, o, typeof(NUnit.Framework.TestFixtureTearDownAttribute)); }));
+
+
+                    Do(sc, list, ref failures);
+                }
+                sc.Post((state => { button1.IsEnabled = true; testResults.Items.Add("Done. " + failures + " failure(s) seen"); }), null);
+            }
+            );
+        }
+
+        private void button1_Click(object sender, RoutedEventArgs e)
+        {
+            OnRunTests(sender, e);
+        }
+
+
+    }
+}
diff --git a/src/SilverlightTester/Properties/AppManifest.xml b/src/SilverlightTester/Properties/AppManifest.xml
new file mode 100755
index 0000000..a955232
--- /dev/null
+++ b/src/SilverlightTester/Properties/AppManifest.xml
@@ -0,0 +1,6 @@
+<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+>
+    <Deployment.Parts>
+    </Deployment.Parts>
+</Deployment>
diff --git a/src/SilverlightTester/Properties/AssemblyInfo.cs b/src/SilverlightTester/Properties/AssemblyInfo.cs
new file mode 100755
index 0000000..61ddf3f
--- /dev/null
+++ b/src/SilverlightTester/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("SilverlightTester")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("SilverlightTester")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
+[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("1858e1ed-c1c1-4259-b6b6-db4cbec05b98")]
+
+// 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/src/SilverlightTester/Properties/OutOfBrowserSettings.xml b/src/SilverlightTester/Properties/OutOfBrowserSettings.xml
new file mode 100755
index 0000000..8a11bb9
--- /dev/null
+++ b/src/SilverlightTester/Properties/OutOfBrowserSettings.xml
@@ -0,0 +1,10 @@
+<OutOfBrowserSettings ShortName="SilverlightTester Application" EnableGPUAcceleration="False" ShowInstallMenuItem="True">
+  <OutOfBrowserSettings.Blurb>SilverlightTester Application on your desktop; at home, at work or on the go.</OutOfBrowserSettings.Blurb>
+  <OutOfBrowserSettings.WindowSettings>
+    <WindowSettings Title="SilverlightTester Application" />
+  </OutOfBrowserSettings.WindowSettings>
+  <OutOfBrowserSettings.SecuritySettings>
+    <SecuritySettings ElevatedPermissions="Required" />
+  </OutOfBrowserSettings.SecuritySettings>
+  <OutOfBrowserSettings.Icons />
+</OutOfBrowserSettings>
\ No newline at end of file
diff --git a/src/SilverlightTester/SilverlightTester.csproj b/src/SilverlightTester/SilverlightTester.csproj
new file mode 100755
index 0000000..1760b6b
--- /dev/null
+++ b/src/SilverlightTester/SilverlightTester.csproj
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{09F44917-C9D1-4BCA-ABFE-128CB5A8DA6D}</ProjectGuid>
+    <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>SilverlightTester</RootNamespace>
+    <AssemblyName>SilverlightTester</AssemblyName>
+    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
+    <SilverlightApplication>true</SilverlightApplication>
+    <SupportedCultures>
+    </SupportedCultures>
+    <XapOutputs>true</XapOutputs>
+    <GenerateSilverlightManifest>true</GenerateSilverlightManifest>
+    <XapFilename>SilverlightTester.xap</XapFilename>
+    <SilverlightManifestTemplate>Properties\AppManifest.xml</SilverlightManifestTemplate>
+    <SilverlightAppEntry>SilverlightTester.App</SilverlightAppEntry>
+    <TestPageFileName>SilverlightTesterTestPage.html</TestPageFileName>
+    <CreateTestPage>true</CreateTestPage>
+    <ValidateXaml>true</ValidateXaml>
+    <EnableOutOfBrowser>true</EnableOutOfBrowser>
+    <OutOfBrowserSettingsFile>Properties\OutOfBrowserSettings.xml</OutOfBrowserSettingsFile>
+    <UsePlatformExtensions>false</UsePlatformExtensions>
+    <ThrowErrorsInValidation>true</ThrowErrorsInValidation>
+    <LinkedServerProject>
+    </LinkedServerProject>
+    <SignManifests>false</SignManifests>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <!-- This property group is only here to support building this project using the 
+       MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs 
+       to set the TargetFrameworkVersion to v3.5 -->
+  <PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>Bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>Bin\Release</OutputPath>
+    <DefineConstants>TRACE;SILVERLIGHT</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="..\..\Silverlight\$(SilverlightVersion)\$(Configuration)\bin\FSharp.Core.dll"/>
+    <Reference Include="..\..\Silverlight\$(SilverlightVersion)\$(Configuration)\bin\FSharp.PowerPack.dll"/>
+    <Reference Include="..\..\Silverlight\$(SilverlightVersion)\$(Configuration)\bin\FSharp.PowerPack.Compatibility.dll"/>
+    <Reference Include="..\..\Silverlight\$(SilverlightVersion)\$(Configuration)\bin\FSharp.PowerPack.Linq.dll"/>
+    <Reference Include="..\..\Silverlight\$(SilverlightVersion)\$(Configuration)\bin\FSharp.PowerPack.Unittests.dll"/>
+    <Reference Include="mscorlib" />
+    <Reference Include="System.Windows" />
+    <Reference Include="system" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Net" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Windows.Browser" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="App.xaml.cs">
+      <DependentUpon>App.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="MainPage.xaml.cs">
+      <DependentUpon>MainPage.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </ApplicationDefinition>
+    <Page Include="MainPage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Properties\AppManifest.xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Properties\OutOfBrowserSettings.xml" />
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <ProjectExtensions>
+    <VisualStudio>
+      <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
+        <SilverlightProjectProperties />
+      </FlavorProperties>
+    </VisualStudio>
+  </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/src/SilverlightTester/SilverlightTester.csproj.user b/src/SilverlightTester/SilverlightTester.csproj.user
new file mode 100755
index 0000000..6bf880c
--- /dev/null
+++ b/src/SilverlightTester/SilverlightTester.csproj.user
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ProjectExtensions>
+    <VisualStudio>
+      <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
+        <SilverlightProjectProperties>
+          <StartPageUrl>
+          </StartPageUrl>
+          <StartAction>OfflineApplication</StartAction>
+          <AspNetDebugging>True</AspNetDebugging>
+          <NativeDebugging>False</NativeDebugging>
+          <SQLDebugging>False</SQLDebugging>
+          <ExternalProgram>
+          </ExternalProgram>
+          <StartExternalURL>
+          </StartExternalURL>
+          <StartCmdLineArguments>
+          </StartCmdLineArguments>
+          <StartWorkingDirectory>
+          </StartWorkingDirectory>
+          <ShowWebRefOnDebugPrompt>True</ShowWebRefOnDebugPrompt>
+          <OutOfBrowserProjectToDebug>SilverlightTester</OutOfBrowserProjectToDebug>
+          <ShowRiaSvcsOnDebugPrompt>True</ShowRiaSvcsOnDebugPrompt>
+        </SilverlightProjectProperties>
+      </FlavorProperties>
+    </VisualStudio>
+  </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/src/SilverlightTester/SilverlightTester.sln b/src/SilverlightTester/SilverlightTester.sln
new file mode 100755
index 0000000..39326c4
--- /dev/null
+++ b/src/SilverlightTester/SilverlightTester.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightTester", "SilverlightTester.csproj", "{09F44917-C9D1-4BCA-ABFE-128CB5A8DA6D}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{09F44917-C9D1-4BCA-ABFE-128CB5A8DA6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{09F44917-C9D1-4BCA-ABFE-128CB5A8DA6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{09F44917-C9D1-4BCA-ABFE-128CB5A8DA6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{09F44917-C9D1-4BCA-ABFE-128CB5A8DA6D}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/src/Unittests/UnitTests.PowerPack.fsproj b/src/Unittests/UnitTests.PowerPack.fsproj
new file mode 100755
index 0000000..0711adf
--- /dev/null
+++ b/src/Unittests/UnitTests.PowerPack.fsproj
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup> <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot> </PropertyGroup> 
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets"/>
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>vTip</TargetFrameworkVersion>
+    <ReferenceVsAssemblies>true</ReferenceVsAssemblies>
+    <ProjectGuid>{9605601b-33f9-4806-a732-8e5067296dd7}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>PowerPack.UnitTests</RootNamespace>
+    <AssemblyName>PowerPack.UnitTests</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <Name>PowerPack.UnitTests</Name>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>3</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>3</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="nunit.core, Version=2.2.2.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+      <Name>nunit.core</Name>
+      <AssemblyName>nunit.core.dll</AssemblyName>
+      <HintPath>$(FSharpPowerPackSourcesRoot)\..\tools\nunit\nunit.core.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="nunit.extensions, Version=2.2.2.0, Culture=neutral, PublicKeyToken=null">
+      <Name>nunit.extensions</Name>
+      <AssemblyName>nunit.extensions.dll</AssemblyName>
+      <HintPath>$(FSharpPowerPackSourcesRoot)\..\tools\nunit\nunit.extensions.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="nunit.framework, Version=2.2.2.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+      <Name>nunit.framework</Name>
+      <AssemblyName>nunit.framework.dll</AssemblyName>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="LibraryTestFx.fs" />
+    <Compile Include="Microsoft.FSharp.Math\BigNumType.fs" /> 
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\FSharp.PowerPack\FSharp.PowerPack.fsproj">
+      <Name>FSharp.PowerPack</Name>
+      <Project>{649fa588-f02e-457c-9fcf-87e46407481f}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets"/>
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')"  />
+</Project>
\ No newline at end of file
diff --git a/src/assemblyinfo.Common.fs b/src/assemblyinfo.Common.fs
new file mode 100755
index 0000000..ad5a953
--- /dev/null
+++ b/src/assemblyinfo.Common.fs
@@ -0,0 +1,4 @@
+namespace Microsoft.FSharp
+[<assembly:System.Reflection.AssemblyVersion("2.0.0.1")>]
+[<assembly:System.Reflection.AssemblyFileVersion("2.0.0.1")>]
+do()
diff --git a/src/buildSilverlight.bat b/src/buildSilverlight.bat
new file mode 100755
index 0000000..d1d9f24
--- /dev/null
+++ b/src/buildSilverlight.bat
@@ -0,0 +1,16 @@
+
+cd FSharp.PowerPack
+msbuild /p:TargetFramework=Silverlight %1 %2 %3 %4 %5 %6 %7 %8 %9
+cd ..
+
+cd FSharp.PowerPack.Compatibility
+msbuild /p:TargetFramework=Silverlight %1 %2 %3 %4 %5 %6 %7 %8 %9
+cd ..
+
+cd FSharp.PowerPack.Linq
+msbuild /p:TargetFramework=Silverlight %1 %2 %3 %4 %5 %6 %7 %8 %9
+cd ..
+
+cd FSharp.PowerPack.Unittests
+msbuild /p:TargetFramework=Silverlight %1 %2 %3 %4 %5 %6 %7 %8 %9
+cd ..
diff --git a/src/fsppack.vs2008.sln b/src/fsppack.vs2008.sln
new file mode 100755
index 0000000..c1a25ca
--- /dev/null
+++ b/src/fsppack.vs2008.sln
@@ -0,0 +1,86 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D78E3B57-DAD1-4FE1-9DC8-84F7847B0C77}"
+	ProjectSection(SolutionItems) = preProject
+		setup\alternative-install-vs2008.bat = setup\alternative-install-vs2008.bat
+		fsppack-build.proj = fsppack-build.proj
+		..\Makefile = ..\Makefile
+		wix\product.wxs = wix\product.wxs
+		wix\script.fsx = wix\script.fsx
+		source-build-version = source-build-version
+		version = version
+		version-redirect = version-redirect
+	EndProjectSection
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack", "FSharp.PowerPack\FSharp.PowerPack.fsproj", "{649FA588-F02E-457C-9FCF-87E46407481F}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.CodeDom", "FSharp.Compiler.CodeDom\FSharp.Compiler.CodeDom.fsproj", "{9EF49218-FD64-43A8-922B-84B1FF576773}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsLex", "FsLex\FsLex.fsproj", "{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsYacc", "FsYacc\FsYacc.fsproj", "{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Linq", "FSharp.PowerPack.Linq\FSharp.PowerPack.Linq.fsproj", "{4C2ED03B-5ACE-427B-8285-AD333E60F35E}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Metadata", "FSharp.PowerPack.Metadata\FSharp.PowerPack.Metadata.fsproj", "{816CB737-0648-4889-8662-54484D42824D}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsHtmlDoc", "FsHtmlDoc\FsHtmlDoc.fsproj", "{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Build.Tasks", "FSharp.PowerPack.Build.Tasks\FSharp.PowerPack.Build.Tasks.fsproj", "{A9566921-4193-4EC8-83FB-F5A0DC257678}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Unittests", "FSharp.PowerPack.Unittests\FSharp.PowerPack.Unittests.fsproj", "{E2A0F944-E76E-4C53-B037-A050FDF7378A}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Compatibility", "FSharp.PowerPack.Compatibility\FSharp.PowerPack.Compatibility.fsproj", "{6FC3B299-23CB-4098-998D-06C014431807}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{649FA588-F02E-457C-9FCF-87E46407481F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{649FA588-F02E-457C-9FCF-87E46407481F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{649FA588-F02E-457C-9FCF-87E46407481F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{649FA588-F02E-457C-9FCF-87E46407481F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9EF49218-FD64-43A8-922B-84B1FF576773}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9EF49218-FD64-43A8-922B-84B1FF576773}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9EF49218-FD64-43A8-922B-84B1FF576773}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9EF49218-FD64-43A8-922B-84B1FF576773}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4C2ED03B-5ACE-427B-8285-AD333E60F35E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4C2ED03B-5ACE-427B-8285-AD333E60F35E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4C2ED03B-5ACE-427B-8285-AD333E60F35E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4C2ED03B-5ACE-427B-8285-AD333E60F35E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{816CB737-0648-4889-8662-54484D42824D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{816CB737-0648-4889-8662-54484D42824D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{816CB737-0648-4889-8662-54484D42824D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{816CB737-0648-4889-8662-54484D42824D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A9566921-4193-4EC8-83FB-F5A0DC257678}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A9566921-4193-4EC8-83FB-F5A0DC257678}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A9566921-4193-4EC8-83FB-F5A0DC257678}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A9566921-4193-4EC8-83FB-F5A0DC257678}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E2A0F944-E76E-4C53-B037-A050FDF7378A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E2A0F944-E76E-4C53-B037-A050FDF7378A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E2A0F944-E76E-4C53-B037-A050FDF7378A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E2A0F944-E76E-4C53-B037-A050FDF7378A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6FC3B299-23CB-4098-998D-06C014431807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6FC3B299-23CB-4098-998D-06C014431807}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6FC3B299-23CB-4098-998D-06C014431807}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6FC3B299-23CB-4098-998D-06C014431807}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/src/fsppack.vs2010.sln b/src/fsppack.vs2010.sln
new file mode 100755
index 0000000..3def66b
--- /dev/null
+++ b/src/fsppack.vs2010.sln
@@ -0,0 +1,130 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D78E3B57-DAD1-4FE1-9DC8-84F7847B0C77}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack", "FSharp.PowerPack\FSharp.PowerPack.fsproj", "{649FA588-F02E-457C-9FCF-87E46407481F}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fsharp.Compiler.CodeDom", "FSharp.Compiler.CodeDom\Fsharp.Compiler.CodeDom.fsproj", "{9EF49218-FD64-43A8-922B-84B1FF576773}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsLex", "FsLex\FsLex.fsproj", "{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsYacc", "FsYacc\FsYacc.fsproj", "{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Linq", "FSharp.PowerPack.Linq\FSharp.PowerPack.Linq.fsproj", "{4C2ED03B-5ACE-427B-8285-AD333E60F35E}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Metadata", "FSharp.PowerPack.Metadata\FSharp.PowerPack.Metadata.fsproj", "{816CB737-0648-4889-8662-54484D42824D}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsHtmlDoc", "FsHtmlDoc\FsHtmlDoc.fsproj", "{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Build.Tasks", "FSharp.PowerPack.Build.Tasks\FSharp.PowerPack.Build.Tasks.fsproj", "{A9566921-4193-4EC8-83FB-F5A0DC257678}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Parallel.Seq", "FSharp.PowerPack.Parallel.Seq\FSharp.PowerPack.Parallel.Seq.fsproj", "{24A845CD-B684-46FB-ABCA-979013F5015B}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Unittests", "FSharp.PowerPack.Unittests\FSharp.PowerPack.Unittests.fsproj", "{E2A0F944-E76E-4C53-B037-A050FDF7378A}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Compatibility", "FSharp.PowerPack.Compatibility\FSharp.PowerPack.Compatibility.fsproj", "{6FC3B299-23CB-4098-998D-06C014431807}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.PowerPack.Unittests.v40", "FSharp.PowerPack.Unittests.v40\FSharp.PowerPack.Unittests.v40.fsproj", "{1B749E89-2B1A-4443-A522-EEB348E01555}"
+EndProject
+Global
+	GlobalSection(TeamFoundationVersionControl) = preSolution
+		SccNumberOfProjects = 13
+		SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
+		SccTeamFoundationServer = https://tfs10.codeplex.com/
+		SccLocalPath0 = .
+		SccProjectUniqueName1 = FSharp.PowerPack\\FSharp.PowerPack.fsproj
+		SccProjectName1 = FSharp.PowerPack
+		SccLocalPath1 = FSharp.PowerPack
+		SccProjectUniqueName2 = FSharp.Compiler.CodeDom\\Fsharp.Compiler.CodeDom.fsproj
+		SccProjectName2 = FSharp.Compiler.CodeDom
+		SccLocalPath2 = FSharp.Compiler.CodeDom
+		SccProjectUniqueName3 = FsLex\\FsLex.fsproj
+		SccProjectName3 = FsLex
+		SccLocalPath3 = FsLex
+		SccProjectUniqueName4 = FsYacc\\FsYacc.fsproj
+		SccProjectName4 = FsYacc
+		SccLocalPath4 = FsYacc
+		SccProjectUniqueName5 = FSharp.PowerPack.Linq\\FSharp.PowerPack.Linq.fsproj
+		SccProjectName5 = FSharp.PowerPack.Linq
+		SccLocalPath5 = FSharp.PowerPack.Linq
+		SccProjectUniqueName6 = FSharp.PowerPack.Metadata\\FSharp.PowerPack.Metadata.fsproj
+		SccProjectName6 = FSharp.PowerPack.Metadata
+		SccLocalPath6 = FSharp.PowerPack.Metadata
+		SccProjectUniqueName7 = FsHtmlDoc\\FsHtmlDoc.fsproj
+		SccProjectName7 = FsHtmlDoc
+		SccLocalPath7 = FsHtmlDoc
+		SccProjectUniqueName8 = FSharp.PowerPack.Build.Tasks\\FSharp.PowerPack.Build.Tasks.fsproj
+		SccProjectName8 = FSharp.PowerPack.Build.Tasks
+		SccLocalPath8 = FSharp.PowerPack.Build.Tasks
+		SccProjectUniqueName9 = FSharp.PowerPack.Parallel.Seq\\FSharp.PowerPack.Parallel.Seq.fsproj
+		SccProjectName9 = FSharp.PowerPack.Parallel.Seq
+		SccLocalPath9 = FSharp.PowerPack.Parallel.Seq
+		SccProjectUniqueName10 = FSharp.PowerPack.Unittests\\FSharp.PowerPack.Unittests.fsproj
+		SccProjectName10 = FSharp.PowerPack.Unittests
+		SccLocalPath10 = FSharp.PowerPack.Unittests
+		SccProjectUniqueName11 = FSharp.PowerPack.Compatibility\\FSharp.PowerPack.Compatibility.fsproj
+		SccProjectName11 = FSharp.PowerPack.Compatibility
+		SccLocalPath11 = FSharp.PowerPack.Compatibility
+		SccProjectUniqueName12 = FSharp.PowerPack.Unittests.v40\\FSharp.PowerPack.Unittests.v40.fsproj
+		SccProjectName12 = FSharp.PowerPack.Unittests.v40
+		SccLocalPath12 = FSharp.PowerPack.Unittests.v40
+	EndGlobalSection
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{649FA588-F02E-457C-9FCF-87E46407481F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{649FA588-F02E-457C-9FCF-87E46407481F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{649FA588-F02E-457C-9FCF-87E46407481F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{649FA588-F02E-457C-9FCF-87E46407481F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9EF49218-FD64-43A8-922B-84B1FF576773}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9EF49218-FD64-43A8-922B-84B1FF576773}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9EF49218-FD64-43A8-922B-84B1FF576773}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9EF49218-FD64-43A8-922B-84B1FF576773}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BD2284A5-AA4D-442D-B4FB-E43B2FE9DD2A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DDD90630-1CDA-4CB3-9A0A-6A1253478C2D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4C2ED03B-5ACE-427B-8285-AD333E60F35E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4C2ED03B-5ACE-427B-8285-AD333E60F35E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4C2ED03B-5ACE-427B-8285-AD333E60F35E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4C2ED03B-5ACE-427B-8285-AD333E60F35E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{816CB737-0648-4889-8662-54484D42824D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{816CB737-0648-4889-8662-54484D42824D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{816CB737-0648-4889-8662-54484D42824D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{816CB737-0648-4889-8662-54484D42824D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{09C71C41-9A24-4842-96F7-9ED5D5E0DF3C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A9566921-4193-4EC8-83FB-F5A0DC257678}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A9566921-4193-4EC8-83FB-F5A0DC257678}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A9566921-4193-4EC8-83FB-F5A0DC257678}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A9566921-4193-4EC8-83FB-F5A0DC257678}.Release|Any CPU.Build.0 = Release|Any CPU
+		{24A845CD-B684-46FB-ABCA-979013F5015B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{24A845CD-B684-46FB-ABCA-979013F5015B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{24A845CD-B684-46FB-ABCA-979013F5015B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{24A845CD-B684-46FB-ABCA-979013F5015B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E2A0F944-E76E-4C53-B037-A050FDF7378A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E2A0F944-E76E-4C53-B037-A050FDF7378A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E2A0F944-E76E-4C53-B037-A050FDF7378A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E2A0F944-E76E-4C53-B037-A050FDF7378A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6FC3B299-23CB-4098-998D-06C014431807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6FC3B299-23CB-4098-998D-06C014431807}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6FC3B299-23CB-4098-998D-06C014431807}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6FC3B299-23CB-4098-998D-06C014431807}.Release|Any CPU.Build.0 = Release|Any CPU
+		{1B749E89-2B1A-4443-A522-EEB348E01555}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1B749E89-2B1A-4443-A522-EEB348E01555}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1B749E89-2B1A-4443-A522-EEB348E01555}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1B749E89-2B1A-4443-A522-EEB348E01555}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/src/fsppack.vs2010.vssscc b/src/fsppack.vs2010.vssscc
new file mode 100755
index 0000000..794f014
--- /dev/null
+++ b/src/fsppack.vs2010.vssscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/workyard/FsSrGen/FSharp.SRGen.Build.Tasks/FSharp.SRGen.Build.Tasks.fsproj b/workyard/FsSrGen/FSharp.SRGen.Build.Tasks/FSharp.SRGen.Build.Tasks.fsproj
new file mode 100755
index 0000000..a302ccf
--- /dev/null
+++ b/workyard/FsSrGen/FSharp.SRGen.Build.Tasks/FSharp.SRGen.Build.Tasks.fsproj
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..\..\..\src\</FSharpPowerPackSourcesRoot>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{c57db8be-806d-459c-8f6d-a65b907641ff}</ProjectGuid>
+    <OutputType>library</OutputType>
+    <RootNamespace>FSharp.SRGen.Build.Tasks</RootNamespace>
+    <AssemblyName>FSharp.SRGen.Build.Tasks</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Name>FSharp.SRGen.Build.Tasks</Name>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>3</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>3</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="FsSrGen.fs" />
+    <Content Include="FSharp.SRGen.targets">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Build.Framework" />
+    <Reference Include="Microsoft.Build.Utilities.v3.5" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+	     Other similar extension points exist, see Microsoft.Common.targets.
+	<Target Name="BeforeBuild">
+	</Target>
+	<Target Name="AfterBuild">
+	</Target>
+	-->
+</Project>
diff --git a/workyard/FsSrGen/FSharp.SRGen.Build.Tasks/FSharp.SRGen.targets b/workyard/FsSrGen/FSharp.SRGen.Build.Tasks/FSharp.SRGen.targets
new file mode 100755
index 0000000..5dc0b14
--- /dev/null
+++ b/workyard/FsSrGen/FSharp.SRGen.Build.Tasks/FSharp.SRGen.targets
@@ -0,0 +1,65 @@
+<!--
+***********************************************************************************************
+FSharp.SRGen.targets
+
+WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
+		  created a backup copy.  Incorrect changes to this file will make it
+		  impossible to load or build your projects from the command-line or the IDE.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+***********************************************************************************************
+-->
+
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <UsingTask TaskName="FsSrGen" AssemblyFile="FSharp.SRGen.Build.Tasks.dll"/>
+  <PropertyGroup>
+    <PrepareForBuildDependsOn>ProcessFsSrGen;$(PrepareForBuildDependsOn)</PrepareForBuildDependsOn>
+  </PropertyGroup>
+
+  <!-- Build FsSrGen files. -->
+  <Target
+		Name="CallFsSrGen"
+		Inputs="@(FsSrGen)"
+		Outputs="@(FsSrGen->'$(IntermediateOutputPath)%(Filename).fs');@(FsSrGen->'$(IntermediateOutputPath)%(Filename).resx')"
+		Condition="'@(FsSrGen)'!=''">
+    <!-- Create the output directory in case it doesn't exist yet -->
+    <MakeDir Directories="$(IntermediateOutputPath)"/>
+    <!-- Run the tool -->
+    <FsSrGen
+      InputFile="%(FsSrGen.FullPath)"
+      ToolPath="$(FsSrGenToolPath)"
+      OutputFsFile="$(IntermediateOutputPath)%(FsSrGen.Filename).fs"
+      OutputResxFile="$(IntermediateOutputPath)%(FsSrGen.Filename).resx"
+      >
+    </FsSrGen>
+  </Target>
+
+  <!-- Process FsSrGen rules. No 'Inputs' and 'Outputs' means this rule always runs if there is any @FsSrGen, even if up-to-date. -->
+  <Target
+		Name="ProcessFsSrGen"
+                DependsOnTargets="CallFsSrGen"
+		Condition="'@(FsSrGen)'!=''">
+    <!-- Make the outputs magically part of the project -->
+    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).fs">
+      <Output TaskParameter="Include" ItemName="CompileBefore"/>
+    </CreateItem>
+    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).resx"
+                AdditionalMetadata="ManifestResourceName=%(FsSrGen.Filename)">
+      <!-- Note AdditionalMetadata above; we need the name in the manifest to be Foo.resources and not e.g. obj.Debug.Foo.resources -->
+      <Output TaskParameter="Include" ItemName="EmbeddedResource"/>
+    </CreateItem>
+    <!-- Add them to the list of things under the IntermediateOutputPath that should be 'clean'ed -->
+    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).fs">
+      <Output TaskParameter="Include" ItemName="FileWrites"/>
+    </CreateItem>
+    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).resx">
+      <Output TaskParameter="Include" ItemName="FileWrites"/>
+    </CreateItem>
+  </Target>
+
+  <ItemGroup>
+    <AvailableItemName Include="FsSrGen">
+      <Visible>false</Visible>
+    </AvailableItemName>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/workyard/FsSrGen/FSharp.SRGen.Build.Tasks/FsSrGen.fs b/workyard/FsSrGen/FSharp.SRGen.Build.Tasks/FsSrGen.fs
new file mode 100755
index 0000000..39ffba0
--- /dev/null
+++ b/workyard/FsSrGen/FSharp.SRGen.Build.Tasks/FsSrGen.fs
@@ -0,0 +1,46 @@
+
+namespace Microsoft.FSharp.Build
+
+open System
+open Microsoft.Build.Framework
+open Microsoft.Build.Utilities
+
+type FsSrGen() =
+    inherit ToolTask()
+    let mutable inputFile  : string = null
+    let mutable toolPath : string = null
+    let mutable outputFsFile : string = null
+    let mutable outputResxFile : string = null
+    [<Required>]
+    member this.InputFile
+        with get ()  = inputFile
+        and  set (s) = inputFile <- s
+    [<Required>]
+    [<Output>]
+    member this.OutputFsFile
+        with get ()  = outputFsFile
+        and  set (s) = outputFsFile <- s
+    [<Required>]
+    [<Output>]
+    member this.OutputResxFile
+        with get ()  = outputResxFile
+        and  set (s) = outputResxFile <- s
+
+    // For targeting other versions
+    member this.ToolPath
+        with get ()  = toolPath
+        and  set (s) = toolPath <- s
+        
+    // ToolTask methods
+    override this.ToolName = "fssrgen.exe"
+
+    override this.GenerateFullPathToTool() =
+        System.IO.Path.Combine(toolPath, this.ToolExe)
+
+    override this.GenerateCommandLineCommands() =
+        let builder = new CommandLineBuilder()
+        builder.AppendSwitchIfNotNull(" ", inputFile)
+        builder.AppendSwitchIfNotNull(" ", outputFsFile)
+        builder.AppendSwitchIfNotNull(" ", outputResxFile)
+        let args = builder.ToString()
+        args
diff --git a/workyard/FsSrGen/FsSrGen/FsSrGen.fsproj b/workyard/FsSrGen/FsSrGen/FsSrGen.fsproj
new file mode 100755
index 0000000..c10153f
--- /dev/null
+++ b/workyard/FsSrGen/FsSrGen/FsSrGen.fsproj
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..\..\..\src\</FSharpPowerPackSourcesRoot>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{1e299bf5-3064-4366-91b4-59f4885d5667}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>FsSrGen</RootNamespace>
+    <AssemblyName>FsSrGen</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Name>FsSrGen</Name>
+    <OtherFlags>--standalone</OtherFlags>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>3</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>3</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="Program.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+	     Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
diff --git a/workyard/FsSrGen/FsSrGen/Program.fs b/workyard/FsSrGen/FsSrGen/Program.fs
new file mode 100755
index 0000000..cdb67ca
--- /dev/null
+++ b/workyard/FsSrGen/FsSrGen/Program.fs
@@ -0,0 +1,426 @@
+namespace FSSRGen
+
+module Implementation =
+    let JustPrintErr(filename, line, msg) =
+        printfn "%s(%d): error : %s" filename line msg
+        
+    /// Err(filename, line, msg)
+    let Err(filename, line, msg) =
+        JustPrintErr(filename, line, msg)
+        printfn "Note that the syntax of each line is one of these three alternatives:"
+        printfn "# comment"
+        printfn "ident,\"string\""
+        printfn "errNum,ident,\"string\""
+        failwithf "there were errors in the file '%s'" filename
+
+    let xmlBoilerPlateString = @"<?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>
+    </root>"
+
+
+
+
+    // The kinds of 'holes' we can do
+    type HoleType =
+        | Int = 0     // %d
+        | String = 1  // %s
+        | Float = 2   // %f
+
+    let HoleTypeToString this =    
+        match this with
+        | HoleType.Int -> "System.Int32"
+        | HoleType.String -> "System.String"
+        | HoleType.Float -> "System.Double"
+        | _ -> failwith "impossible"
+        
+    let ComputeHoles filename lineNum (txt:string) : HoleType[] * string =
+        // takes in a %d%s kind of string, returns array of HoleType and {0}{1} kind of string
+        let mutable i = 0
+        let holeNumber = ref 0
+        let holes = ref []  // reverse order
+        let sb = new System.Text.StringBuilder()
+        let AddHole holeType =
+            sb.Append(sprintf "{%d}" !holeNumber) |> ignore
+            holeNumber := !holeNumber + 1
+            holes := holeType :: !holes
+        while i < txt.Length do
+            if txt.[i] = '%' then
+                if i+1 = txt.Length then
+                    Err(filename, lineNum, "(at end of string) % must be followed by d, f, s, or %")
+                else
+                    match txt.[i+1] with
+                    | 'd' -> AddHole HoleType.Int
+                    | 'f' -> AddHole HoleType.Float
+                    | 's' -> AddHole HoleType.String
+                    | '%' -> sb.Append('%') |> ignore
+                    | c -> Err(filename, lineNum, sprintf "'%%%c' is not a valid sequence, only %%d %%f %%s or %%%%" c)
+                i <- i + 2
+            else
+                match txt.[i] with
+                | '{' -> sb.Append("{{") |> ignore
+                | '}' -> sb.Append("}}") |> ignore
+                | c -> sb.Append(c) |> ignore
+                i <- i + 1
+        (!holes |> List.rev |> List.toArray, sb.ToString())
+
+    let Unquote (s : string) =
+        if s.StartsWith("\"") && s.EndsWith("\"") then s.Substring(1, s.Length - 2)
+        else failwith "error message string should be quoted"
+
+    let ParseLine filename lineNum (txt:string) =
+        let mutable errNum = None
+        let identB = new System.Text.StringBuilder()
+        let mutable i = 0
+        // parse optional error number
+        if i < txt.Length && System.Char.IsDigit(txt.[i]) then
+            let numB = new System.Text.StringBuilder()
+            while i < txt.Length && System.Char.IsDigit(txt.[i]) do
+                numB.Append(txt.[i]) |> ignore
+                i <- i + 1
+            errNum <- Some(int (numB.ToString()))
+            if i = txt.Length || not(txt.[i] = ',') then
+                Err(filename, lineNum, sprintf "After the error number '%d' there should be a comma" errNum.Value)
+            // Skip the comma
+            i <- i + 1
+        // parse short identifier
+        if i < txt.Length && not(System.Char.IsLetter(txt.[i])) then
+            Err(filename, lineNum, sprintf "The first character in the short identifier should be a letter, but found '%c'" txt.[i])
+        while i < txt.Length && System.Char.IsLetterOrDigit(txt.[i]) do
+            identB.Append(txt.[i]) |> ignore
+            i <- i + 1
+        let ident = identB.ToString()
+        if ident.Length = 0 then
+            Err(filename, lineNum, "Did not find the short identifier")
+        else
+            if i = txt.Length || not(txt.[i] = ',') then
+                Err(filename, lineNum, sprintf "After the identifier '%s' there should be a comma" ident)
+            else
+                // Skip the comma
+                i <- i + 1
+                if i = txt.Length then
+                    Err(filename, lineNum, sprintf "After the identifier '%s' and comma, there should be the quoted string resource" ident)
+                else
+                    let str = 
+                        try
+                            System.String.Format(Unquote(txt.Substring(i)))  // Format turns e.g '\n' into that char, but also requires that we 'escape' curlies in the original .txt file, e.g. "{{"
+                        with 
+                            e -> Err(filename, lineNum, sprintf "Error calling System.String.Format (note that curly braces must be escaped, and there cannot be trailing space on the line): >>>%s<<< -- %s" (txt.Substring(i)) e.Message)
+                    let holes, netFormatString = ComputeHoles filename lineNum str
+                    (lineNum, (errNum,ident), str, holes, netFormatString)
+
+    let stringBoilerPlatePrefix = @"            
+open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
+open Microsoft.FSharp.Reflection
+open System.Reflection
+// (namespaces below for specific case of using the tool to compile FSharp.Core itself)
+open Microsoft.FSharp.Core
+open Microsoft.FSharp.Core.Operators
+open Microsoft.FSharp.Text
+open Microsoft.FSharp.Collections
+open Printf
+"
+    let StringBoilerPlate filename = @"            
+    // BEGIN BOILERPLATE        
+    static let resources = lazy (new System.Resources.ResourceManager(""" + filename + @""", System.Reflection.Assembly.GetExecutingAssembly()))
+
+    static let GetString(name:string) =        
+        let s = resources.Value.GetString(name, System.Globalization.CultureInfo.CurrentUICulture)
+#if DEBUG
+        if null = s then
+            System.Diagnostics.Debug.Assert(false, sprintf ""**RESOURCE ERROR**: Resource token %s does not exist!"" name)
+#endif
+        s
+
+    static let mkFunctionValue (tys: System.Type[]) (impl:obj->obj) = 
+        FSharpValue.MakeFunction(FSharpType.MakeFunctionType(tys.[0],tys.[1]), impl)
+        
+    static let funTyC = typeof<(obj -> obj)>.GetGenericTypeDefinition()  
+
+    static let isNamedType(ty:System.Type) = not (ty.IsArray ||  ty.IsByRef ||  ty.IsPointer)
+    static let isFunctionType (ty1:System.Type)  = 
+        isNamedType(ty1) && ty1.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(funTyC)
+
+    static let rec destFunTy (ty:System.Type) =
+        if isFunctionType ty then 
+            ty, ty.GetGenericArguments() 
+        else
+            match ty.BaseType with 
+            | null -> failwith ""destFunTy: not a function type"" 
+            | b -> destFunTy b 
+
+    static let buildFunctionForOneArgPat (ty: System.Type) impl = 
+        let _,tys = destFunTy ty 
+        let rty = tys.[1]
+        // PERF: this technique is a bit slow (e.g. in simple cases, like 'sprintf ""%x""') 
+        mkFunctionValue tys (fun inp -> impl rty inp)
+                
+    static let capture1 (fmt:string) i args ty (go : obj list -> System.Type -> int -> obj) : obj = 
+        match fmt.[i] with
+        | '%' -> go args ty (i+1) 
+        | 'd'
+        | 'f'
+        | 's' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
+        | _ -> failwith ""bad format specifier""
+        
+    // newlines and tabs get converted to strings when read from a resource file
+    // this will preserve their original intention    
+    static let postProcessString (s : string) =
+        s.Replace(""\\n"",""\n"").Replace(""\\t"",""\t"").Replace(""\\r"",""\r"").Replace(""\\\"""", ""\"""")
+        
+    static let createMessageString (messageString : string) (fmt : Printf.StringFormat<'T>) : 'T = 
+        let fmt = fmt.Value // here, we use the actual error string, as opposed to the one stored as fmt
+        let len = fmt.Length 
+
+        /// Function to capture the arguments and then run.
+        let rec capture args ty i = 
+            if i >= len ||  (fmt.[i] = '%' && i+1 >= len) then 
+                let b = new System.Text.StringBuilder()    
+                b.AppendFormat(messageString, [| for x in List.rev args -> x |]) |> ignore
+                box(b.ToString())
+            // REVIEW: For these purposes, this should be a nop, but I'm leaving it
+            // in incase we ever decide to support labels for the error format string
+            // E.g., ""<name>%s<foo>%d""
+            elif System.Char.IsSurrogatePair(fmt,i) then 
+               capture args ty (i+2)
+            else
+                match fmt.[i] with
+                | '%' ->
+                    let i = i+1 
+                    capture1 fmt i args ty capture
+                | _ ->
+                    capture args ty (i+1) 
+
+        (unbox (capture [] (typeof<'T>) 0) : 'T)
+
+    static let mutable swallowResourceText = false
+    
+    static let GetStringFunc((messageID : string),(fmt : Printf.StringFormat<'T>)) : 'T =
+        if swallowResourceText then
+            sprintf fmt
+        else
+            let mutable messageString = GetString(messageID)
+            messageString <- postProcessString messageString                            
+            createMessageString messageString fmt
+        
+    /// If set to true, then all error messages will just return the filled 'holes' delimited by ',,,'s - this is for language-neutral testing (e.g. localization-invariant baselines).
+    static member SwallowResourceText with get () = swallowResourceText
+                                      and set (b) = swallowResourceText <- b
+    // END BOILERPLATE        
+    "            
+
+    let RunMain(args:string array) =
+        let filename = System.IO.Path.GetFullPath(args.[0])  // TODO args validation
+        let outFilename = System.IO.Path.GetFullPath(args.[1])  // TODO args validation
+        let outXmlFilename = System.IO.Path.GetFullPath(args.[2])  // TODO args validation
+        try
+            let justfilename = System.IO.Path.GetFileNameWithoutExtension(filename)
+            if justfilename |> Seq.exists (fun c -> not(System.Char.IsLetterOrDigit(c))) then
+                Err(filename, 0, sprintf "The filename '%s' is not allowed; only letters and digits can be used, as the filename also becomes the namespace for the SR class" justfilename)
+
+            let lines = System.IO.File.ReadAllLines(filename) 
+                        |> Array.mapi (fun i s -> i,s) // keep line numbers
+                        |> Array.filter (fun (i,s) -> not(s.StartsWith("#")))  // filter out comments
+            let stringInfos = lines |> Array.map (fun (i,s) -> ParseLine filename i s)
+            // now we have array of (lineNum, ident, str, holes, netFormatString)  // str has %d, netFormatString has {0}
+            
+            // validate that all the idents are unique
+            let allIdents = new System.Collections.Generic.Dictionary<string,int>()
+            for (line,(_,ident),_,_,_) in stringInfos do
+                if allIdents.ContainsKey(ident) then
+                    Err(filename,line,sprintf "Identifier '%s' is already used previously on line %d - each identifier must be unique" ident allIdents.[ident])
+                allIdents.Add(ident,line)
+            
+            // validate that all the strings themselves are unique
+            let allStrs = new System.Collections.Generic.Dictionary<string,(int*string)>()
+            for (line,(_,ident),str,_,_) in stringInfos do
+                if allStrs.ContainsKey(str) then
+                    let prevLine,prevIdent = allStrs.[str]
+                    Err(filename,line,sprintf "String '%s' already appears on line %d with identifier '%s' - each string must be unique" str prevLine prevIdent)
+                allStrs.Add(str,(line,ident))
+            
+            use out = new System.IO.StreamWriter(outFilename)
+            fprintfn out "// This is a generated file; the original input is '%s'" filename
+            fprintfn out "namespace %s" justfilename
+            fprintfn out "%s" stringBoilerPlatePrefix
+            fprintfn out "type internal SR private() ="
+            fprintfn out "%s" (StringBoilerPlate justfilename)
+            // gen each resource method
+            stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) ->
+                let formalArgs = new System.Text.StringBuilder()
+                let actualArgs = new System.Text.StringBuilder()
+                let firstTime = ref true
+                let n = ref 0
+                formalArgs.Append("(") |> ignore
+                for hole in holes do
+                    if !firstTime then
+                        firstTime := false
+                    else
+                        formalArgs.Append(", ") |> ignore
+                        actualArgs.Append(" ") |> ignore
+                    formalArgs.Append(sprintf "a%d : %s" !n (HoleTypeToString hole)) |> ignore
+                    actualArgs.Append(sprintf "a%d" !n) |> ignore
+                    n := !n + 1
+                formalArgs.Append(")") |> ignore
+                fprintfn out "    /// %s" str
+                fprintfn out "    /// (Originally from %s:%d)" filename (lineNum+1)
+                let justPercentsFromFormatString = 
+                    (holes |> Array.fold (fun acc holeType -> 
+                        acc + match holeType with 
+                              | HoleType.Int -> ",,,%d" 
+                              | HoleType.Float -> ",,,%f" 
+                              | HoleType.String -> ",,,%s"
+                              | _ -> failwith "Impossible HoleType") "") + ",,,"
+                let errPrefix = match optErrNum with
+                                | None -> ""
+                                | Some(n) -> sprintf "%d, " n
+                fprintfn out "    static member %s%s = (%sGetStringFunc(\"%s\",\"%s\") %s)" ident (formalArgs.ToString()) errPrefix ident justPercentsFromFormatString (actualArgs.ToString())
+            )
+            fprintfn out ""
+            // gen validation method
+            fprintfn out "    /// Call this method once to validate that all known resources are valid; throws if not"
+            fprintfn out "    static member RunStartupValidation() ="
+            stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) ->
+                fprintfn out "        ignore(GetString(\"%s\"))" ident
+            )
+            fprintfn out "        ()"  // in case there are 0 strings, we need the generated code to parse
+            // gen to resx
+            let xd = new System.Xml.XmlDocument()
+            xd.LoadXml(xmlBoilerPlateString)
+            stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) ->
+                let xn = xd.CreateElement("data")
+                xn.SetAttribute("name",ident) |> ignore
+                xn.SetAttribute("xml:space","preserve") |> ignore
+                let xnc = xd.CreateElement("value")
+                xn.AppendChild(xnc) |> ignore
+                xnc.AppendChild(xd.CreateTextNode(netFormatString)) |> ignore
+                xd.LastChild.AppendChild(xn) |> ignore
+            )
+            xd.Save(outXmlFilename)
+            0
+        with 
+            e -> JustPrintErr(filename, 0, sprintf "An exception occurred when processing '%s': %s" filename e.Message)
+                 1
+
+namespace MainImpl
+
+module MainStuff =
+
+    [<EntryPoint>]
+    let Main(args) = FSSRGen.Implementation.RunMain(args)
diff --git a/workyard/charting/FSharp.PowerPack.Plot.Excel.fsproj b/workyard/charting/FSharp.PowerPack.Plot.Excel.fsproj
new file mode 100755
index 0000000..317cbde
--- /dev/null
+++ b/workyard/charting/FSharp.PowerPack.Plot.Excel.fsproj
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <ProjectGuid>{c01bdd2f-e2e3-41ac-9bbf-a7e640b341f7}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <OutputType>Library</OutputType>
+    <SchemaVersion>2.0</SchemaVersion>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <DocumentationFile>FSharp.PowerPack.Plot.Excel.xml</DocumentationFile>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="excel.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="Microsoft.Office.Interop.Excel.dll" />
+    <Reference Include="Microsoft.Office.Interop.Owc11.dll" />
+    <ProjectReference Include="FSharp.PowerPack.Plot.fsproj">
+      <Name>FSharp.PowerPack.Plot</Name>
+      <Project>{6196b0f8-caea-4cf1-af82-1b520f77fe44}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="FSharp.PowerPack.Plot.Neutral.fsproj">
+      <Name>FSharp.PowerPack.Plot.Neutral</Name>
+      <Project>{6196b0f8-caea-4cf1-af82-1b520f77fe44}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <Reference Include="FSharp.Core" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/workyard/charting/FSharp.PowerPack.Plot.Neutral.fsproj b/workyard/charting/FSharp.PowerPack.Plot.Neutral.fsproj
new file mode 100755
index 0000000..9de303d
--- /dev/null
+++ b/workyard/charting/FSharp.PowerPack.Plot.Neutral.fsproj
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <ProjectGuid>{9d35e207-2184-42b8-9e1f-c6e7d906fcd7}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <OutputType>Library</OutputType>
+    <AssemblyName>FSharp.PowerPack.Plot.Neutral</AssemblyName>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <DocumentationFile>FSharp.PowerPack.Plot.Neutral.xml</DocumentationFile>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="neutral.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\charting\FSharp.PowerPack.Plot.fsproj">
+      <Name>FSharp.PowerPack.Plot</Name>
+      <Project>{a05c919c-6e80-4dcb-81b5-a12295959386}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/workyard/charting/FSharp.PowerPack.Plot.Xceed.fsproj b/workyard/charting/FSharp.PowerPack.Plot.Xceed.fsproj
new file mode 100755
index 0000000..a096cba
--- /dev/null
+++ b/workyard/charting/FSharp.PowerPack.Plot.Xceed.fsproj
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <ProjectGuid>{476e2850-fce3-48bd-b14d-c0bd1e8dc529}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <OutputType>Library</OutputType>
+    <SchemaVersion>2.0</SchemaVersion>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <DocumentationFile>FSharp.PowerPack.Plot.Xceed.xml</DocumentationFile>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>    
+    <Compile Include="xceed.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="FSharp.Core" />
+    <Reference Include="Xceed.Chart">
+      <Name>Xceed.Chart</Name>
+      <AssemblyName>Xceed.Chart.dll</AssemblyName>
+      <HintPath>$(FSharpPowerPackSourcesRoot)\..\tools\Xceed\Bin\.NET\Xceed.Chart.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Chart.Core">
+      <Name>Xceed.Chart.Core</Name>
+      <AssemblyName>Xceed.Chart.Core.dll</AssemblyName>
+      <HintPath>$(FSharpPowerPackSourcesRoot)\..\tools\Xceed\Bin\.NET\Xceed.Chart.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Chart.Graphics2D">
+      <Name>Xceed.Chart.Graphics2D</Name>
+      <AssemblyName>Xceed.Chart.Graphics2D.dll</AssemblyName>
+      <HintPath>$(FSharpPowerPackSourcesRoot)\..\tools\Xceed\Bin\.NET\Xceed.Chart.Graphics2D.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Chart.GraphicsCore">
+      <Name>Xceed.Chart.GraphicsCore</Name>
+      <AssemblyName>Xceed.Chart.GraphicsCore.dll</AssemblyName>
+      <HintPath>$(FSharpPowerPackSourcesRoot)\..\tools\Xceed\Bin\.NET\Xceed.Chart.GraphicsCore.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Chart.GraphicsGL">
+      <Name>Xceed.Chart.GraphicsGL</Name>
+      <AssemblyName>Xceed.Chart.GraphicsGL.dll</AssemblyName>
+      <HintPath>$(FSharpPowerPackSourcesRoot)\..\tools\Xceed\Bin\.NET\Xceed.Chart.GraphicsGL.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Chart.Standard">
+      <Name>Xceed.Chart.Standard</Name>
+      <AssemblyName>Xceed.Chart.Standard.dll</AssemblyName>
+      <HintPath>$(FSharpPowerPackSourcesRoot)\..\tools\Xceed\Bin\.NET\Xceed.Chart.Standard.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Chart.UIControls">
+      <Name>Xceed.Chart.UIControls</Name>
+      <AssemblyName>Xceed.Chart.UIControls.dll</AssemblyName>
+      <HintPath>$(FSharpPowerPackSourcesRoot)\..\tools\Xceed\Bin\.NET\Xceed.Chart.UIControls.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Chart.Utilities">
+      <Name>Xceed.Chart.Utilities</Name>
+      <AssemblyName>Xceed.Chart.Utilities.dll</AssemblyName>
+      <HintPath>$(FSharpPowerPackSourcesRoot)\..\tools\Xceed\Bin\.NET\Xceed.Chart.Utilities.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\charting\FSharp.PowerPack.Plot.fsproj">
+      <Name>FSharp.PowerPack.Plot</Name>
+      <Project>{a05c919c-6e80-4dcb-81b5-a12295959386}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\charting\FSharp.PowerPack.Plot.Neutral.fsproj">
+      <Name>FSharp.PowerPack.Plot.Neutral</Name>
+      <Project>{9d35e207-2184-42b8-9e1f-c6e7d906fcd7}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/workyard/charting/FSharp.PowerPack.Plot.fsproj b/workyard/charting/FSharp.PowerPack.Plot.fsproj
new file mode 100755
index 0000000..b7894ca
--- /dev/null
+++ b/workyard/charting/FSharp.PowerPack.Plot.fsproj
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <ProjectGuid>{a05c919c-6e80-4dcb-81b5-a12295959386}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <OutputType>Library</OutputType>
+    <AssemblyName>FSharp.PowerPack.Plot</AssemblyName>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <DocumentationFile>FSharp.PowerPack.Plot.xml</DocumentationFile>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="plot.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="FSharp.Core" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/workyard/charting/excel.fs b/workyard/charting/excel.fs
new file mode 100755
index 0000000..7ea89ca
--- /dev/null
+++ b/workyard/charting/excel.fs
@@ -0,0 +1,595 @@
+
+module Microsoft.FSharp.Plot.Excel
+
+open System;
+open System.Drawing;
+open Microsoft.Office.Interop.Owc11
+open Microsoft.Office.Interop.Excel
+open System.Windows.Forms
+open Microsoft.FSharp.Plot
+open Microsoft.FSharp.Plot.Core // neutral plot datatypes
+
+let ConvertToObjectArray xs = Array.map box xs
+let RevertBackFromObjArray (xs:obj array) = Array.map unbox xs 
+
+type Plot2D() as self=
+    let updateEvent = new Event<bool>()
+    
+    let mutable m_name = ""
+    let mutable series : ChSeries =null 
+    let mutable m_bordercolor = Color.Empty
+    let mutable m_showlabels = false
+    abstract Create : ChSeries -> unit 
+    
+    member this.Update = updateEvent.Publish
+
+    /// Does Caption and Set Legend to True
+    override this.Create (e: ChSeries ) = 
+         series <- e
+         e.Caption <- m_name
+         if m_name <> "" then
+            e.Parent.HasLegend <- true
+         
+         let count = e.DataLabelsCollection.Count 
+         for i=0 to count - 1 do e.DataLabelsCollection.Delete(0)                        
+         if m_showlabels then e.DataLabelsCollection.Add() |> ignore
+            
+         if m_bordercolor <> Color.Empty then
+            e.Border.Color <- m_bordercolor.Name
+    
+    
+    member  this.update() = 
+                if series <> null then this.Create series
+                updateEvent.Trigger true   
+  
+    member this.Series 
+        with get () = series     
+                
+    
+    member this.Name 
+        with set(s) =   
+            m_name <- s
+            this.update()
+        and get() = m_name
+   
+    member this.BorderColor   
+        with get() = m_bordercolor
+        and set (c) = 
+            m_bordercolor <- c
+            this.update() 
+ 
+    member this.ShowLabels 
+        with get () = m_showlabels
+        and set (c) = m_showlabels <- c; this.update() 
+    
+    interface IPlot with
+        member t.BasePlot = self :> IPlot
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+type Bars (xys : seq<float * string>) = 
+        inherit Plot2D() 
+        let ys,labels = Seq.toArray xys |> Array.unzip
+        let mutable m_ys = ConvertToObjectArray ys
+        let mutable m_labels  = ConvertToObjectArray labels
+        let mutable m_color  = Color.Empty
+        let mutable m_alignment = Alignment.Vertical
+ 
+        override this.Create  (e : ChSeries) = 
+            base.Create(e)        
+            e.Type <- if m_alignment = Alignment.Vertical
+                      then ChartChartTypeEnum.chChartTypeColumnStacked
+                      else ChartChartTypeEnum.chChartTypeBarStacked
+            e.SetData(ChartDimensionsEnum.chDimValues,-1,m_ys)
+            e.SetData(ChartDimensionsEnum.chDimCategories, -1 , m_labels)            
+            
+            if m_color <>  Color.Empty then
+                e.Interior.Color <- m_color.Name
+            
+        member this.Alignment
+            with get()= m_alignment
+            and set (c)= m_alignment <- c ; this.update()
+            
+        member this.Color 
+            with set(c) = 
+                m_color <- c
+                this.update()
+            and get() = m_color
+                        
+        member this.Values 
+            with set(x:float[]) =
+                m_ys <- ConvertToObjectArray x
+                this.update()
+            and get() = RevertBackFromObjArray m_ys : float[]
+                
+        member this.Labels
+            with set (y:string[]) =
+                m_labels <- ConvertToObjectArray y
+                this.update()
+            and get() = RevertBackFromObjArray m_labels : string[]
+
+
+let RelevantMarkerStyle  (m:MarkerStyle) =
+    match m with
+        | MarkerStyle.Circle -> ChartMarkerStyleEnum.chMarkerStyleCircle
+        | MarkerStyle.Diamond -> ChartMarkerStyleEnum.chMarkerStyleDiamond
+        | MarkerStyle.None -> ChartMarkerStyleEnum.chMarkerStyleNone
+        | MarkerStyle.Plus -> ChartMarkerStyleEnum.chMarkerStylePlus
+        | MarkerStyle.Star -> ChartMarkerStyleEnum.chMarkerStyleStar
+        | MarkerStyle.Triangle -> ChartMarkerStyleEnum.chMarkerStyleTriangle
+        | MarkerStyle.X -> ChartMarkerStyleEnum.chMarkerStyleX
+        | _ -> ChartMarkerStyleEnum.chMarkerStyleDiamond
+                
+let RelevantLineStyle (l:LineStyle) =
+    match l with
+        | LineStyle.Solid  -> ChartLineDashStyleEnum.chLineSolid
+        | LineStyle.Dashed -> ChartLineDashStyleEnum.chLineDash
+        | LineStyle.Square -> ChartLineDashStyleEnum.chLineSquareDot
+        | LineStyle.DotDot -> ChartLineDashStyleEnum.chLineDashDotDot
+        | _ -> ChartLineDashStyleEnum.chLineRoundDot
+                    
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////   
+
+       
+type Lines (xys : seq<float*float>) = 
+        inherit Plot2D() 
+        let xs,ys = Seq.toArray xys |> Array.unzip
+        let n1, n2 = xs.Length , ys.Length
+        do assert (n1 = n2)
+      
+        let mutable m_linecolor = Color.Empty
+        let mutable m_linestyle = LineStyle.Solid
+        let mutable m_smooth = false
+        let mutable m_linesize = 1
+        
+        let arrange (xs:float array) (ys:float array) = 
+            let xsSorted = xs.Clone() :?> float array
+            System.Array.Sort<float>(xsSorted)
+            
+            let ysnew = Array.create ys.Length 0.
+            for i = 0 to xs.Length - 1 do         
+                let index= Array.findIndex (fun e -> e =xs.[i]   ) xsSorted
+                ysnew.[i] <- ys.[index]
+            done
+            xsSorted, ysnew
+        
+        let mutable m_markerColor = Color.Empty
+        
+        let mutable m_markersize =3
+        let mutable m_markerstyle = MarkerStyle.Diamond
+        
+        let xs, ys = arrange xs ys
+        let mutable m_xs = ConvertToObjectArray xs
+        let mutable m_ys = ConvertToObjectArray ys
+
+        override this.Create  (e : ChSeries) = 
+            base.Create(e)  
+            if m_smooth then e.Type <- ChartChartTypeEnum.chChartTypeSmoothLineStackedMarkers
+            else e.Type <- ChartChartTypeEnum.chChartTypeLineStackedMarkers
+            
+            e.Marker.Style <- RelevantMarkerStyle m_markerstyle
+            e.Marker.Size <- m_markersize
+            
+            if m_markerColor <> Color.Empty then
+                e.Interior.Color <- m_markerColor.Name
+            
+            e.Line.DashStyle <- RelevantLineStyle m_linestyle
+            
+            if m_linesize > 3 then 
+                e.Line.Weight <- LineWeightEnum.owcLineWeightThick
+            elif m_linesize >1 then e.Line.Weight <- LineWeightEnum.owcLineWeightMedium
+            else e.Line.Weight <- LineWeightEnum.owcLineWeightThin
+            
+            if m_linecolor <> Color.Empty then
+                e.Line.Color <- m_linecolor.Name
+                        
+            e.SetData(ChartDimensionsEnum.chDimValues,-1,m_ys)
+            e.SetData(ChartDimensionsEnum.chDimCategories,-1,m_xs)
+
+        member this.SmoothLine 
+            with get () = m_smooth
+            and set(c) = m_smooth<- c ; this.update()      
+            
+      
+        member this.LineColor  
+            with get() = m_linecolor
+            and set (c) = 
+                m_linecolor <- c
+                this.update()
+       
+        member this.MarkerColor  
+            with get() = m_markerColor
+            and set (c) = 
+                m_markerColor <- c
+                this.update()
+            
+        member this.LineStyle 
+            with get() = m_linestyle
+            and set(c) = 
+                m_linestyle <- c
+                this.update()
+        member this.LineSize 
+            with get () = float m_linesize
+            and set(c) = m_linesize <- int c
+                         this.update()   
+        member this.MarkerSize 
+            with get () = float m_markersize
+            and set(c)= 
+                m_markersize <- int c
+                this.update()
+                
+        member this.MarkerStyle 
+            with get() = m_markerstyle
+            and set(c) = 
+                m_markerstyle <- c
+                this.update()
+             
+        member this.XYValues 
+            with set (v:float[]*float[]) =
+                let x,y = v
+                let xs,ys = arrange x y
+                m_xs <- ConvertToObjectArray xs
+                m_ys <- ConvertToObjectArray ys
+                this.update()
+            and get() = 
+                let x = RevertBackFromObjArray m_xs : float[]
+                let y = RevertBackFromObjArray m_ys : float[]
+                x,y 
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+
+
+type Scatter(xys: seq<float*float>) = 
+        inherit Plot2D() 
+        let xs,ys = Seq.toArray xys |> Array.unzip
+        let n1, n2 = xs.Length , ys.Length
+        do assert (n1 = n2)
+        let mutable series = null : ChSeries
+        
+        let mutable m_name = System.String.Empty
+        
+        let mutable m_xs = ConvertToObjectArray xs
+        let mutable m_ys = ConvertToObjectArray ys
+        
+        let mutable m_markerColor = Color.Empty
+        let mutable m_markersize =3
+        let mutable m_markerstyle = MarkerStyle.Diamond
+  
+        override this.Create  (e : ChSeries) = 
+            base.Create(e)
+            e.Type <- ChartChartTypeEnum.chChartTypeScatterMarkers
+            
+            e.Marker.Style <- RelevantMarkerStyle m_markerstyle
+            e.Marker.Size <- m_markersize
+            
+            if m_markerColor <> Color.Empty then
+                e.Interior.Color <- m_markerColor.Name
+                      
+            e.SetData(ChartDimensionsEnum.chDimXValues,-1,m_xs)
+            e.SetData(ChartDimensionsEnum.chDimYValues,-1,m_ys)
+
+        member this.MarkerSize 
+            with get () = float  m_markersize
+            and set(c)= 
+                m_markersize <-int  c
+                this.update()
+                
+        member this.MarkerStyle 
+            with get() = m_markerstyle
+            and set(c) = 
+                m_markerstyle <- c
+                this.update()
+        
+        member this.MarkerColor  
+            with get() = m_markerColor
+            and set (c) = 
+                m_markerColor <- c
+                this.update()
+                     
+        member this.XYValues 
+            with set(v:float[]*float[]) =
+                let xs,ys = v
+                m_xs <- ConvertToObjectArray xs
+                m_ys <- ConvertToObjectArray ys
+                this.update()
+            and get() = 
+                let x = RevertBackFromObjArray m_xs : float[]
+                let y  = RevertBackFromObjArray m_ys : float[]
+                x,y 
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+
+type Stock(xs:float[],openY:float[],highY:float[],lowY:float[],closeY:float[]) = 
+    inherit Plot2D() 
+    let m_xs = ConvertToObjectArray xs
+    let m_openY = ConvertToObjectArray openY
+    let m_highY = ConvertToObjectArray highY
+    let m_lowY = ConvertToObjectArray lowY
+    let m_closeY = ConvertToObjectArray closeY
+    
+    let mutable m_linecolor = Color.Empty
+    let mutable m_barcolor  = Color.Empty
+    
+    new (xs:float[],highY:float[],lowY:float[],closeY:float[]) = 
+        new Stock(xs,[||] ,highY ,lowY,closeY) 
+    
+    override this.Create  (e : ChSeries) = 
+        base.Create e
+
+        if m_openY = [||] then      
+            e.Type <- ChartChartTypeEnum.chChartTypeStockHLC
+            
+        else 
+            e.Type <- ChartChartTypeEnum.chChartTypeStockOHLC
+            e.SetData(ChartDimensionsEnum.chDimOpenValues,-1,m_openY)
+                    
+        e.SetData(ChartDimensionsEnum.chDimCategories,-1,m_xs)
+        e.SetData(ChartDimensionsEnum.chDimHighValues,-1,m_highY)
+        e.SetData(ChartDimensionsEnum.chDimLowValues,-1,m_lowY)
+        e.SetData(ChartDimensionsEnum.chDimCloseValues,-1,m_closeY)
+        
+        if m_linecolor <> Color.Empty then e.Line.Color <- m_linecolor.Name
+        if m_barcolor <> Color.Empty then e.Interior.Color  <- m_barcolor.Name
+    member this.LineColor  
+        with get () = m_linecolor
+        and set (c) = 
+            m_linecolor <- c
+            this.update()
+        
+    member this.BarColor  
+        with get () = m_barcolor
+        and set (c) = 
+            m_barcolor <-c
+            this.update()
+
+
+
+type Pie(ys:float[],labels:string[]) = 
+    inherit Plot2D() 
+    
+    let mutable m_ys = ConvertToObjectArray ys
+    let mutable m_labels = ConvertToObjectArray labels
+    
+    let mutable m_explose = false
+    
+    override this.Create  (e : ChSeries) = 
+        base.Create e
+        if m_explose then         
+            e.Type <- ChartChartTypeEnum.chChartTypePieExploded
+            e.Explosion <- 3
+        else   e.Type <- ChartChartTypeEnum.chChartTypePie
+                            
+        e.SetData(ChartDimensionsEnum.chDimValues,-1,m_ys)
+        e.SetData(ChartDimensionsEnum.chDimCategories,-1,m_labels)
+    member this.Values 
+        with get() = RevertBackFromObjArray m_ys : float[]
+        and set (c :float[]) =  m_ys <- ConvertToObjectArray c;       this.update()
+    member this.Explose
+        with get () = m_explose
+        and set(c) = 
+            m_explose <- c
+            this.update()        
+    member this.Labels 
+        with get() = RevertBackFromObjArray m_labels : string[]
+        and set (c:string[]) = m_labels <- ConvertToObjectArray c; this.update()
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+
+
+  
+type Area(xs:float[], ys:float[]) =
+    inherit Plot2D() 
+    
+    let m_xs = ConvertToObjectArray xs
+    let m_ys = ConvertToObjectArray ys
+    
+    let mutable m_Color  = Color.Empty
+    
+    override this.Create  (e : ChSeries) = 
+        base.Create e
+        e.Type <- ChartChartTypeEnum.chChartTypeAreaStacked
+       
+        e.SetData(ChartDimensionsEnum.chDimValues,-1,m_ys)
+        e.SetData(ChartDimensionsEnum.chDimCategories,-1,m_xs)
+        
+        if m_Color  <> Color.Empty then e.Interior.Color <- m_Color .Name
+   
+    member this.Color  
+        with get () = m_Color 
+        and set (c) = m_Color  <- c
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////  
+
+
+type Chart2D() =
+        let panel = new Panel()
+        let acceptTypes tys (x:IPlot) = List.exists (fun (ty:System.Type) -> ty.IsAssignableFrom(x.GetType())) tys
+        let chartToolbar = new System.Windows.Forms.ToolStrip(Dock=DockStyle.Bottom)        
+        do panel.Controls.Add(chartToolbar)
+        let chartContainer = new ChartSpaceClass()        
+        let imageControl = new System.Windows.Forms.PictureBox(Dock =DockStyle.Fill)
+        let setPicturetoImage   (chSpace:ChartSpaceClass) w h =
+            use memImage = new System.IO.MemoryStream( chartContainer.GetPicture("gif",w,h):?> System.Byte[])
+            let image = new System.Drawing.Bitmap(memImage)
+            memImage.Close()
+            image
+        do panel.Controls.Add(imageControl)        
+        let refreshImage () = setPicturetoImage chartContainer imageControl.Width  (imageControl.Height- chartToolbar.Height)
+        
+        do imageControl.SizeChanged.Add(fun ev->  imageControl.Image <- refreshImage() )
+        
+        let btnSave = new System.Windows.Forms.ToolStripButton(Text ="&Save")
+        do btnSave.Click.Add( fun _  ->
+                        let saveDialog = new SaveFileDialog()
+                        saveDialog.Filter <- "gif (*.gif)|*.gif|jpg (*.jpg)|*.jpg|png (*.png)|*.png"
+                        if saveDialog.ShowDialog() = DialogResult.OK then
+                            let fileName = saveDialog.FileName
+                            let a = fileName.Split(".".ToCharArray())
+                            let filterName = a.[a.Length-1]
+                            chartContainer.ExportPicture(fileName,filterName,imageControl.Width,imageControl.Height)
+                            )
+        do chartToolbar.Items.Add(btnSave) |>ignore
+        
+        let refresh _ = imageControl.Image <- refreshImage()
+        do refresh()
+        let aChart =  chartContainer.Charts.Add(chartContainer.Charts.Count)
+        member this.Refresh () =   refresh()
+        interface IIChart with 
+            member this.HasLegend 
+                with get() = aChart.HasLegend
+                and set(c) = aChart.HasLegend <- c ;  refresh()
+                
+            member this.Title 
+                with set x = if System.String.IsNullOrEmpty(x) then aChart.HasTitle <- false
+                             else aChart.HasTitle <- true;  aChart.Title.Caption <- x  
+                             this.Refresh()
+                and get() = if aChart.HasTitle then aChart.Title.Caption
+                            else System.String.Empty
+        end 
+        
+        interface IChart with 
+            member this.Control = panel :> Control
+            member  this.Accepts(x) = acceptTypes  [typeof<Bars>;  typeof<Scatter>;typeof<Lines>;typeof<Stock>;typeof<Pie>;typeof<Area> ] x
+            member this.Add(x:IPlot) =
+                match x with
+                | :? Plot2D as plot -> 
+                    if (this :> IChart).Accepts plot then
+                        let chartSeries= aChart.SeriesCollection.Add(aChart.SeriesCollection.Count)
+                        plot.Create chartSeries
+                        plot.Update.Add refresh
+                        refresh()
+                    else printf "You tried to add an unsupported IChart object..\n"
+                | ty -> ()
+            member this.Context = [| |]        
+
+        member this.Chart = aChart   
+        member this.ChartContainer = chartContainer         
+     
+    
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+type ExcelChartFactory() =  
+    let acceptTypes tys (x:IPlot) = List.exists (fun (ty:System.Type) -> ty.IsAssignableFrom(x.GetType())) tys
+    interface IChartFactory  with
+     override this.Name     = "Excel Charts"
+     override this.Accepts(x) = acceptTypes  [typeof<Bars>;  typeof<Scatter>;typeof<Lines>;typeof<Stock>;typeof<Pie>;typeof<Area>] x
+     override this.Create() =  (new Chart2D() :> IChart) 
+    
+
+type ExcelChartProvider () = 
+    inherit ChartProvider()
+    let bar (plot :Bars)=
+      { new IBars with
+        member t.Alignment    with get() = plot.Alignment and set x = plot.Alignment <- x
+        member t.Color        with get() = plot.Color  and set x = plot.Color  <- x
+        member t.Labels       with get() = plot.Labels and set x = plot.Labels <- x
+        member t.Values       with get() = plot.Values and set x = plot.Values <- x
+        member t.BorderColor  with get() = plot.BorderColor  and set x = plot.BorderColor  <- x
+        member t.Name         with get() = plot.Name and set x = plot.Name <- x
+        member t.ShowLabels   with get() = plot.ShowLabels and set x = plot.ShowLabels <- x
+        member t.BasePlot = plot :> IPlot
+      }
+    let lines (plot : Lines) = 
+        { 
+            new ILines with
+            member t.LineColor     with get() = plot.LineColor  and set x = plot.LineColor  <- x
+            member t.LineStyle     with get() = plot.LineStyle and set x = plot.LineStyle <- x   
+            member t.LineSize      with get() = plot.LineSize and set x = plot.LineSize <- x
+            member t.MarkerColor   with get() = plot.MarkerColor  and set x = plot.MarkerColor  <- x
+            member t.MarkerSize    with get() = plot.MarkerSize and set x = plot.MarkerSize <- x
+            member t.MarkerStyle   with get() = plot.MarkerStyle and set x = plot.MarkerStyle <- x
+            member t.XYValues      with get() = plot.XYValues and set x = plot.XYValues <- x
+            member t.BorderColor   with get() = plot.BorderColor  and set x = plot.BorderColor  <- x
+            member t.Name          with get() = plot.Name and set x = plot.Name <- x
+            member t.ShowLabels    with get() = plot.ShowLabels and set x = plot.ShowLabels <- x
+            member t.BasePlot = plot :> IPlot
+        }
+    let scatter (plot : Scatter) = 
+        { 
+            new IScatter with
+            member t.MarkerColor   with get() = plot.MarkerColor  and set x = plot.MarkerColor  <- x
+            member t.MarkerSize    with get() = plot.MarkerSize and set x = plot.MarkerSize <- x   
+            member t.MarkerStyle   with get() = plot.MarkerStyle and set x = plot.MarkerStyle <- x
+            member t.XYValues      with get() = plot.XYValues and set x = plot.XYValues <- x
+            member t.BorderColor   with get() = plot.BorderColor  and set x = plot.BorderColor  <- x
+            member t.Name          with get() = plot.Name and set x = plot.Name <- x
+            member t.ShowLabels    with get() = plot.ShowLabels and set x = plot.ShowLabels <- x
+            member t.BasePlot = plot :> IPlot
+        }   
+    let stock (plot : Stock) = 
+        { 
+            new IStock with
+            member t.BarColor       with get() = plot.BarColor  and set x = plot.BarColor  <- x
+            member t.LineColor      with get() = plot.LineColor  and set x = plot.LineColor  <- x   
+            member t.BorderColor    with get() = plot.BorderColor  and set x = plot.BorderColor  <- x
+            member t.Name           with get() = plot.Name and set x = plot.Name <- x
+            member t.ShowLabels     with get() = plot.ShowLabels and set x = plot.ShowLabels <- x
+            member t.BasePlot = plot :> IPlot
+        }   
+    let pie (plot : Pie) = 
+        { 
+            new IPie with
+            member t.Explose       with get() = plot.Explose and set x = plot.Explose <- x
+            member t.Labels        with get() = plot.Labels and set x = plot.Labels  <- x   
+            member t.Values        with get() = plot.Values and set x = plot.Values <- x
+            member t.BorderColor   with get() = plot.BorderColor  and set x = plot.BorderColor <- x
+            member t.Name          with get() = plot.Name and set x = plot.Name <- x
+            member t.ShowLabels    with get() = plot.ShowLabels and set x = plot.ShowLabels <- x
+            member t.BasePlot = plot :> IPlot
+        } 
+    let area (plot : Area) = 
+        { 
+            new IArea with
+            member t.Color         with get() = plot.Color  and set x = plot.Color   <- x
+            member t.BorderColor   with get() = plot.BorderColor  and set x = plot.BorderColor  <- x   
+            member t.Name          with get() = plot.Name and set x = plot.Name <- x
+            member t.ShowLabels    with get() = plot.ShowLabels and set x = plot.ShowLabels<- x
+            member t.BasePlot = plot :> IPlot
+        }                
+    override this.Bars(args)        = bar(new Bars(args))
+    override this.Lines(args)      = lines(new Lines(args))
+    override this.Scatter(args)    = scatter(new Scatter(args))
+    override this.Stock (xs,openY,highY,lowY,closeY) 
+                                    = stock(new Stock(xs,openY,highY,lowY,closeY))
+    override this.Stock (xs,highY,lowY,closeY) 
+                                    = stock(new Stock(xs,highY,lowY,closeY))
+    override this.Pie(ys,labels)    = pie(new Pie(ys,labels))
+    override this.Area(xs,ys)       = area(new Area(xs,ys))
+
+#if extension
+type Microsoft.FSharp.Plot.Plotter.myplot with
+    member this.ExcelBars(args) = (new Bars(args) :> ExcelBars)
+    member this.ExcelLines(xs,ys) = (new Lines(xs,ys) :> ExcelLines)
+    member this.ExcelScatter(xs,ys) = (new Scatter(xs,ys) :> ExcelScatter)
+    member this.ExcelStock (xs,openY,highY,lowY,closeY) = (new Stock(xs,openY,highY,lowY,closeY) :> ExcelStock)
+    member this.ExcelStock (xs,highY,lowY,closeY) = (new Stock(xs,highY,lowY,closeY) :> ExcelStock)
+    member this.ExcelPie(ys,labels) = (new Pie(ys,labels) :> ExcelPie)
+    member this.ExcelArea(xs,ys)   = (new Area(xs,ys) :> ExcelArea)
+
+#endif
+
+let excelProvider = new ExcelChartProvider() :> ChartProvider
+//do Microsoft.FSharp.Plot.Interactive.Plot.addProvider (excelProvider)
+let RegisterProvider() = Microsoft.FSharp.Plot.Core.SetProvider excelProvider
+do  RegisterProvider()
+
+do Microsoft.FSharp.Plot.Interactive.addFactory (new ExcelChartFactory() :> IChartFactory)
diff --git a/workyard/charting/neutral.fs b/workyard/charting/neutral.fs
new file mode 100755
index 0000000..8e19941
--- /dev/null
+++ b/workyard/charting/neutral.fs
@@ -0,0 +1,119 @@
+module Microsoft.FSharp.Plot.Core
+
+open Microsoft.FSharp.Plot
+open System.Drawing
+
+type Alignment =
+    | Vertical = 0
+    | Horizontal =1 
+    
+type LineStyle =
+    | Solid  = 0
+    | Dashed = 1
+    | Square = 2
+    | DotDot = 3
+    
+type MarkerStyle =
+    | None      = 0
+    | Circle    = 1
+    | Diamond   = 2
+    | Star      = 3
+    | Triangle  = 4
+    | X         = 5
+    | Plus      = 6
+    
+type IBars =
+    abstract Alignment    : Alignment with get,set
+    abstract Color        : Color with get,set
+    abstract Labels       : string [] with get,set
+    abstract Values       : float []  with get,set
+    abstract BorderColor  : Color with get,set
+    abstract Name         : string with set, get
+    abstract ShowLabels   : bool with set, get
+    inherit IPlot
+
+type ILines =
+    abstract LineColor       : Color with get,set
+    abstract LineStyle       : LineStyle with get,set
+    abstract LineSize        : float with get,set
+    abstract MarkerColor     : Color with get,set
+    abstract MarkerSize      : float with get,set
+    abstract MarkerStyle     : MarkerStyle with get,set
+    abstract XYValues        : float[]*float[] with get,set
+    abstract BorderColor     : Color with get,set
+    abstract Name            : string with set, get
+    abstract ShowLabels      : bool with set, get
+    inherit IPlot
+
+type IScatter =
+    abstract MarkerColor     : Color with get,set
+    abstract MarkerSize      : float with get,set
+    abstract MarkerStyle     : MarkerStyle with get,set
+    abstract XYValues        : float [] * float [] with get,set
+    abstract BorderColor     : Color with get,set
+    abstract Name            : string with set, get
+    abstract ShowLabels      : bool with set, get
+    inherit IPlot
+
+type IStock =  
+    abstract BarColor        : Color with get,set
+    abstract LineColor       : Color with get,set
+    abstract BorderColor     : Color with get,set
+    abstract Name            : string with set, get
+    abstract ShowLabels      : bool with set, get
+    inherit IPlot
+
+type IPie =
+    abstract Explose     : bool with get,set
+    abstract Labels      : string [] with get,set
+    abstract Values      : float [] with get,set
+    abstract BorderColor : Color with get,set
+    abstract Name        : string with set, get
+    abstract ShowLabels  : bool with set, get
+    inherit IPlot
+  
+type IArea =
+    abstract Color       : Color with get,set
+    abstract BorderColor : Color with get,set
+    abstract Name        : string with set, get
+    abstract ShowLabels  : bool with set, get
+    inherit IPlot
+
+type IIChart =
+    abstract  HasLegend : bool with get,set
+    abstract  Title : string with get,set
+    inherit IChart 
+
+[<AbstractClass>]
+type ChartProvider ()= 
+    abstract Bars    : seq<float*string> -> IBars
+    abstract Lines   : seq<float*float> -> ILines
+    abstract Scatter : seq<float*float> -> IScatter
+    abstract Stock   : float[]*float[]*float[]*float[]*float[]-> IStock
+    abstract Stock   : float[]*float[]*float[]*float[]-> IStock
+    abstract Pie     : float[]* string[] -> IPie
+    abstract Area    : float[]*float[] -> IArea
+
+
+type myplot() =
+  class
+    // members added via extension methods
+  end
+
+let mutable CurrentProvider = None : ChartProvider option
+  
+let GetProvider() =
+  match CurrentProvider with
+  | Some p -> p
+  | None   -> let msg = "No plot provider has been registered.\nTry registering one? e.g.\n\nMicrosoft.FSharp.Plot.Xceed.RegisterProvider();;\nMicrosoft.FSharp.Plot.Excel.RegisterProvider();;\n\n"
+              printf "%s\n" msg
+              failwith msg
+let SetProvider p = CurrentProvider <- Some p
+
+let Bars(inp) = GetProvider().Bars(inp)
+let Lines(inp) = GetProvider().Lines(inp)
+let Scatter(inp) = GetProvider().Scatter(inp)
+let Stock (xs,openY,highY,lowY,closeY) = GetProvider().Stock(Seq.toArray xs,openY,highY,lowY,closeY)
+let Stock2 (xs,highY,lowY,closeY) = GetProvider().Stock(Seq.toArray xs,highY,lowY,closeY)
+let Pie(ys,labels) = GetProvider().Pie(Seq.toArray ys,labels)
+let Area(xs,ys)   = GetProvider().Area(Seq.toArray xs,Seq.toArray ys)    
\ No newline at end of file
diff --git a/workyard/charting/plot.fs b/workyard/charting/plot.fs
new file mode 100755
index 0000000..b09e461
--- /dev/null
+++ b/workyard/charting/plot.fs
@@ -0,0 +1,187 @@
+namespace Microsoft.FSharp.Plot
+open System
+open System.Drawing
+open System.Windows.Forms
+
+// Abstract objects that represent "plottable" items
+type IPlot = 
+    abstract BasePlot : IPlot // extend to array of IPlot (for compound plots)
+  
+// Control which can accept selected IPlot objects.
+type IChart = 
+    abstract Control : Control
+    abstract Accepts : IPlot -> bool
+    abstract Add     : IPlot -> unit
+    abstract Context : MenuItem[]
+
+// Each 
+type IChartFactory = 
+    abstract Name    : string
+    abstract Accepts : IPlot -> bool
+    abstract Create  : unit -> IChart
+
+
+// The window management functions for charts/plots.
+module Interactive =
+    
+    let menuItem str handler = 
+        let item = new MenuItem(str:string)
+        item.Click.Add(fun _ -> handler())
+        item
+
+    // should be a property for dynamic load
+    let factories = ref [] : IChartFactory list ref
+    let addFactory f = factories := !factories @ [f]   
+               
+    // Frames are container Controls in which to add ChartControls.
+    // Focus is the current/last IChart - where to add next plots where possible.
+
+    // naive next frame
+    // let nextFrame() = let form = new Form(Visible=true,Title="F# Plot Window") in form :> Control
+
+    // tabbing next frame
+    // 1. tabControl
+    let mutable tabControl = null : TabControl
+    let ensureTabControl() = 
+      if tabControl <> null && not tabControl.IsDisposed then
+        tabControl
+      else
+        let form = new Form(TopMost=true,Width=400,Height=400,Text="F# Plot Window")
+        let tab = new TabControl()
+        tabControl <- tab
+        form.Controls.Add(tab)
+        form.Show()
+        tab.Dock <- DockStyle.Fill
+        let deleteSelected _    = tab.SelectedTab.Dispose()
+        let deleteNonSelected _ = let keep = tab.SelectedTab
+                                  let pages = tab.Controls |> Seq.cast : TabPage seq 
+                                  pages |> Seq.toArray |> Array.iter (fun page -> if page <> keep then page.Dispose())
+        tab.ContextMenu <- new ContextMenu [| menuItem "Delete selected tab"         deleteSelected;
+                                              menuItem "Delete un-selected tab" deleteNonSelected;
+                                           |]
+        tab
+        
+    type myTabPage(chart : IChart) = 
+        inherit TabPage()
+        let mutable m_chart = chart
+        member this.Chart 
+            with get() = m_chart
+            and set ch = m_chart <- ch
+    
+    let mutable pageNumber = 0    
+    let nextFrame (ch) = 
+      let tab2 = ensureTabControl()  
+      let page = new myTabPage(ch)
+      pageNumber <- pageNumber + 1
+      page.Text <- sprintf "P%d" pageNumber
+      let () = tab2.Controls.Add(page)
+      tab2.SelectTab(page)
+      (page :> Control)
+
+    //let mutable focus = ((new TextChartControl() :>IChart) : IChart) // dummy value
+    //do  focus.Control.Dispose()
+    let setFocus x = () // focus <- x
+    
+    let plot(pl:'a :> IPlot) =
+        let p = pl.BasePlot
+        match !factories |> List.tryFind (fun fac -> fac.Accepts p) with
+        | None     -> printf "Sorry, not accepted by a registered charting engine\n"; failwith "unknown plot"
+        | Some fac -> let chart = fac.Create()
+                      let frame = nextFrame(chart)
+                      frame.Controls.Add(chart.Control)
+                      chart.Control.Dock <- DockStyle.Fill
+                      chart.Add p
+                      let items =                       
+                        [| new MenuItem("-");
+                           menuItem "Delete" (fun _ -> frame.Dispose())
+                        |]
+                      frame.ContextMenu <- new ContextMenu(Array.append chart.Context items)
+                      setFocus chart
+                      (pl : 'a)
+    
+    open System.Windows.Forms
+    let chart(ch : 'a :> IChart) =      
+      let frame = nextFrame(ch)
+      frame.Controls.Add(ch.Control)
+      ch.Control.Dock <- DockStyle.Fill
+      let items =
+        [| new MenuItem("-");
+           menuItem "Delete" (fun _ -> frame.Dispose())
+        |]
+      frame.ContextMenu <- new ContextMenu(Array.append ch.Context items)
+      setFocus ch
+      (ch : 'a)
+
+    let multiplot(parray : IPlot array) = 
+        let myTab = ensureTabControl() 
+        for p in parray do
+            let tabPageList : myTabPage list = myTab.Controls  |> Seq.cast |> Seq.toList 
+            let existingTab = tabPageList |> List.tryFind(fun c -> c.Chart.Accepts p)   
+            match existingTab with
+                | Some(c) -> c.Chart.Add p
+                | _       -> plot p |> ignore; ()
+
+    let replot(p:'a :> IPlot) = 
+        let myTab = ensureTabControl()
+        if myTab.TabCount > 0 then
+            let page = myTab.Controls.Item(myTab.SelectedIndex) :?> myTabPage
+            if page.Chart.Accepts p then
+                page.Chart.Add p
+                (p:'a)
+            else
+                plot p
+        else plot p
+     
+    type MultiChartControl(tc : TableLayoutPanel) = 
+        let table = tc
+        interface IChart with
+            override this.Control = table :> Control
+            override this.Accepts(x) = false // denies all
+            override this.Add(x:IPlot) = ()
+            override this.Context = [| |]        
+        
+    let subplot(parray : IPlot array) = 
+        let calcRowsColumns len = 
+            let rows = int (sqrt (float len) )
+            let cols = if (len % rows) > 0 then (len / rows) + 1
+                       else len / rows
+            rows,cols
+        
+        let r, c = calcRowsColumns parray.Length
+        let myTab = ensureTabControl()
+        
+        let table = new TableLayoutPanel()
+        table.Dock <- DockStyle.Fill
+        table.RowCount <- r
+        table.ColumnCount <- c
+        
+        
+        let arrangeRowsCols (tbl : TableLayoutPanel)= 
+            tbl.RowStyles.Clear()
+            tbl.ColumnStyles.Clear()
+            let rows = tbl.RowCount
+            let cols = tbl.ColumnCount
+              
+            for i=0 to tbl.RowCount - 1 do 
+                tbl.RowStyles.Add(new RowStyle(SizeType.Percent, float32 (100/rows))) |>ignore
+            for i=0 to tbl.ColumnCount - 1 do
+                tbl.ColumnStyles.Add(new ColumnStyle(SizeType.Percent , float32 (100 / cols))) |>ignore
+        
+        arrangeRowsCols table
+        let multiChart = new MultiChartControl(table)
+        let frame = nextFrame(multiChart)
+        frame.Controls.Add table
+        
+        Array.iter (fun p ->
+                    match !factories |> List.tryFind (fun fac -> fac.Accepts p) with
+                        | None     -> printf "Sorry, %A not accepted by a registered charting engine\n" p
+                        | Some fac ->   let chart = fac.Create()                                
+                                        chart.Control.Dock <- DockStyle.Fill
+                                        chart.Add p
+                                        table.Controls.Add chart.Control
+                                        setFocus chart) parray
+        
+
+
+   
+    
diff --git a/workyard/charting/xceed.fs b/workyard/charting/xceed.fs
new file mode 100755
index 0000000..1c9a91c
--- /dev/null
+++ b/workyard/charting/xceed.fs
@@ -0,0 +1,812 @@
+
+
+module Microsoft.FSharp.Plot.Xceed
+
+
+#nowarn "47"
+#nowarn "54"
+
+let AssertSameSize (arrs: (_ array) list) =
+  match arrs with
+  | [] -> ()
+  | arr::arrs -> assert (arrs |> List.forall (fun arr2 -> arr2.Length = arr.Length))
+
+open Microsoft.FSharp.Plot
+open Microsoft.FSharp.Plot.Core // neutral plot datatypes
+open Xceed.Chart.Standard
+open Xceed.Chart.GraphicsCore
+open Xceed.Chart
+open Xceed.Chart.Core
+open System.Windows.Forms
+open System.Drawing
+
+//! INDEX: dialog for users to get sitelic xceed developer license key
+
+let addControl (c:Control) (f:#Control) = f.Controls.Add(c); f
+
+let groupBox (a:Control) (box:GroupBox)  = 
+    box.Controls.Add a  
+    box
+
+let keyDialog key handler = 
+    let xceedURL = "http://itwebtools/sitelic/resources/subpages/install.asp?productid=168&ptype=77"
+    let input = new TextBox(Text=key,Dock= DockStyle.Fill)
+    let wb    = new WebBrowser(Dock= DockStyle.Fill)
+    let table = new TableLayoutPanel(Dock= DockStyle.Fill) 
+    let box1 = new GroupBox(Text="Enter Xceed Chart 4.1 for .NET license key, then press enter" ,
+                            Dock= DockStyle.Fill,
+                            Height=48) |> addControl input
+    let box2 = new GroupBox(Text="Accept conditions of use to obtain license key (CorpNet only)" ,
+                            Dock= DockStyle.Fill) |> addControl wb
+    table.Controls.Add(box1,column=0,row=0)
+    table.Controls.Add(box2,column=0,row=1)
+    let form = new Form(Width=600,Height=600,Text="F# Plotting Xceed license initialisation (CorpNet only)") |> addControl table
+    wb.Navigate xceedURL
+    input.KeyPress.Add(fun args -> if args.KeyChar = '\013' then
+                                    let key = input.Text.Trim()
+                                    form.Dispose()                         
+                                    form.DialogResult <- DialogResult.OK
+                                    handler key)
+    form.ShowDialog()
+
+let keyName  =  let userRoot = @"HKEY_CURRENT_USER"
+                let subkey   = @"Software\Microsoft Research\FSharp\Plotting"
+                userRoot + "\\" + subkey   
+
+let readKey() = match Microsoft.Win32.Registry.GetValue(keyName,"Key41","") with
+                | :? string as key -> key
+                | _ -> ""
+let writeKey key = Microsoft.Win32.Registry.SetValue(keyName,"Key41",key)
+
+let GetKey() = 
+    keyDialog (readKey()) writeKey |> ignore
+
+let MenuItemToggle description v0 handler =
+    let mi = new MenuItem(Text=description,Checked=v0)  
+    mi.Click.Add(fun _ -> mi.Checked <- not mi.Checked; handler mi.Checked)
+    mi
+
+let license() = 
+    let key = readKey()
+    let key = if key = "" then GetKey(); readKey() else key
+    Xceed.Chart.Licenser.LicenseKey <- key
+
+[<AbstractClass>]
+type Plot2D() as self =
+    let updateFire,(updateEvent : IEvent<_>) = 
+        let e = new Event<_>()
+        e.Trigger, e.Publish
+    let mutable alignment = Alignment.Vertical
+    abstract Series : SeriesBase
+    abstract DimensionPreference : AxisScaleMode option array // internal - option preferences on dimension scales
+    member this.Update = updateEvent : bool IEvent
+    member this.UpdateFire() = updateFire true
+    member this.Name 
+        with get () = this.Series.Name 
+        and set (c) = this.Series.Name <- c ; this.UpdateFire |> ignore
+    member this.Alignment 
+        with get() = alignment 
+        and set(c) = alignment <- c ; this.UpdateFire()
+    interface IPlot with
+      member t.BasePlot = self :> IPlot
+
+type Bars(xys : seq<float * string>) as self = 
+    inherit Plot2D() 
+    let ys,labels = Seq.toArray xys |> Array.unzip
+    let series = new BarSeries(Name="Bar data")
+    do  series.DataLabels.Mode <- DataLabelsMode.None
+    do  Array.iter2 (fun x lab -> series.Add(x,lab)) ys labels
+    let update() = self.UpdateFire()
+    override this.Series = (series :> SeriesBase)
+
+    override this.DimensionPreference = [| None; None; None |]
+    member this.BSeries = series
+    
+    member this.Color  
+        with set (c) = series.BarFillEffect.SetSolidColor(c) ; update()
+        and get() = series.BarFillEffect.Color
+        
+    member this.Labels 
+        with get () = 
+            let labs : string list = series.Labels |> Seq.cast |> Seq.toList
+            List.toArray labs
+        and set (c) = series.Labels.Clear();  Array.iter (fun x ->   series.Labels.Add(box x) |> ignore) c
+                      update()
+                      
+    member this.BorderColor 
+        with set(c) = series.BarBorder.Color <- c; update()
+        and get () = series.BarBorder.Color 
+        
+    member this.ShowLabels
+        with get () = series.DataLabels.Mode  = DataLabelsMode.Every
+        and set(c) =  if c then series.DataLabels.Mode <- DataLabelsMode.Every
+                      else series.DataLabels.Mode <- DataLabelsMode.None
+                      update()
+        
+    
+    member this.Values
+        with set (c) = series.Values.Clear(); series.Values.FillFromEnumerable c; update()
+        and get() = let vals : float list = series.Values |> Seq.cast |> Seq.toList
+                    List.toArray vals
+                                
+
+  
+type HighLow(xys : seq<float*float*float>) as self = 
+    inherit Plot2D() 
+    let xys = Seq.toArray xys
+    let xs = Array.map (fun (x,y,z) -> x) xys
+    let ys0 = Array.map (fun (x,y,z) -> y) xys
+    let ys1 = Array.map (fun (x,y,z) -> z) xys
+    let series = new HighLowSeries(Name = "High Low data")
+    let n1,n2,n3 = xs.Length,ys0.Length,ys1.Length
+    do  Array.iteri (fun i x -> series.AddHighLow(ys0.[i],ys1.[i],x)) xs    
+    do  series.DataLabels.Mode <- DataLabelsMode.None
+    do  series.UseXValues <- true
+    let update() = self.UpdateFire()
+    override this.Series = (series :> SeriesBase)  
+    //member this.Size  with set(s) = series.Size <- float32 s; update()
+    member this.Color with set(c) = series.LowFillEffect.Color <- c; series.HighFillEffect.Color <- c; update()
+    member this.LowColor with set(c) = series.LowFillEffect.Color <- c; update()
+    member this.HighColor with set(c) = series.HighFillEffect.Color <- c; update()
+    member this.Highs with set(x:float seq) = series.HighValues.FillFromEnumerable x; update()
+    member this.Lows  with set(x:float seq) = series.HighValues.FillFromEnumerable x; update()
+ //   [<OverloadID("2")>]
+//    new (xs:float[],lowFun,highFun) = new HighLow(xs,Array.map lowFun xs,Array.map highFun xs)
+    override this.DimensionPreference = [| None; None; Some AxisScaleMode.Numeric |]
+  
+type Points(xys: seq<float*float>) as self = 
+    inherit Plot2D() 
+    let xs,ys = Seq.toArray xys |> Array.unzip
+    let n1,n2 = xs.Length,ys.Length
+    do  assert(n1=n2)
+    let series = new PointSeries(Name = "Points")
+    do  series.UseXValues <- true
+    do  Array.iter2 (fun x y -> series.AddXY(y,x)) xs ys
+    do  series.Size <- 2.0f
+    do  series.PointBorder.Width <- 0
+    do  series.DataLabels.Mode <- DataLabelsMode.None
+    let update() = self.UpdateFire()
+    member this.DataLabels with set(x) = series.DataLabels.Mode <- x; update() // REVIEW: abstract
+    member this.Color      with set(x) = series.PointFillEffect.Color <- x; update()
+    member this.Style      with set(x) = series.PointStyle <- x; update() // REVIEW: abstract
+    member this.Size       with set(x)  = series.Size <- float32 x; update()
+    override this.Series = (series :> SeriesBase)
+    override this.DimensionPreference = [| None; None; Some AxisScaleMode.Numeric |]
+    
+    member this.SSeries = series
+    
+    member this.MarkerColor  
+        with get() = series.PointFillEffect.Color
+        and set(c) = series.PointFillEffect.Color <- c
+    member this.MarkerStyle 
+        with get () = match series.Markers.Style with
+                        | PointStyle.Star           -> MarkerStyle.Star
+                        | PointStyle.Pyramid        -> MarkerStyle.Triangle
+                        | PointStyle.Cross          -> MarkerStyle.Plus
+                        | PointStyle.Ellipse        -> MarkerStyle.Circle
+                        | PointStyle.DiagonalCross  -> MarkerStyle.X
+                        | PointStyle.InvertedPyramid-> MarkerStyle.Diamond
+                        | _ -> MarkerStyle.None
+        and set (c) = series.Markers.Style <- 
+                        match c with
+                          |  MarkerStyle.Star       ->  PointStyle.Star           
+                          |  MarkerStyle.Triangle   ->  PointStyle.Pyramid        
+                          |  MarkerStyle.Plus       ->  PointStyle.Cross          
+                          |  MarkerStyle.Circle     ->  PointStyle.Ellipse        
+                          |  MarkerStyle.X          ->  PointStyle.DiagonalCross  
+                          |  MarkerStyle.Diamond    ->  PointStyle.InvertedPyramid
+                          | _                       ->  PointStyle.Bar
+                      update()  
+    
+    member this.MarkerSize 
+        with get() = float series.Size (*.Markers.Width*)
+        and set(c) = series.Size <- float32 c; (*series.Markers.Width <- float32 c; *) update()
+    
+    member this.BorderColor 
+        with set(c) = series.PointBorder.Color <- c; update()
+        and get () = series.PointBorder.Color 
+          
+    member this.ShowLabels
+        with get () = series.DataLabels.Mode  = DataLabelsMode.Every
+        and set(c) =  if c then series.DataLabels.Mode <- DataLabelsMode.Every
+                      else series.DataLabels.Mode <- DataLabelsMode.None
+                      update()
+                      
+    member this.XYValues     
+        with get() = let xvals : float list = series.XValues |> Seq.cast |> Seq.toList
+                     let yvals : float list = series.Values |> Seq.cast |> Seq.toList
+                     ( (List.toArray xvals) , (List.toArray yvals) )
+        and set(c) = let xs,ys = c
+                     series.Values.Clear() ; series.XValues.Clear()
+                     Array.iter2 (fun x y -> series.AddXY(y,x)) xs ys
+                     update()                    
+            
+
+  
+type Lines(xys: seq<float*float>) as self = 
+    inherit Plot2D() 
+    let xs,ys = Seq.toArray xys |> Array.unzip
+    let n1,n2 = xs.Length,ys.Length 
+    do  assert(n1=n2)
+    let series = new LineSeries(Name = "Lines")
+    do  series.UseXValues <- true
+    do  Array.iter2 (fun x y -> series.AddXY(y,x)) xs ys
+    do  series.LineStyle <- LineSeriesStyle.Line
+    do  series.LineWidth <- 0.1f
+    do  series.LineBorder.Width <- 1
+    do  series.DataLabels.Mode <- DataLabelsMode.None
+    let update() = self.UpdateFire()
+    
+    override this.Series = (series :> SeriesBase)
+    override this.DimensionPreference = [| None; None; Some AxisScaleMode.Numeric |]
+    
+    member this.LSeries = series
+    
+    member this.LineColor  
+        with set(c) = series.LineFillEffect.Color <- c; update()
+        and get () = series.LineFillEffect.Color
+    member this.LineStyle
+        with get() = match series.LineBorder.Pattern with
+                        | LinePattern.Dash      -> LineStyle.Dashed
+                        | LinePattern.Solid     -> LineStyle.Solid
+                        | LinePattern.DashDot   -> LineStyle.Square 
+                        | LinePattern.DashDotDot->  LineStyle.DotDot
+                        | _ -> LineStyle.Solid
+        and set(c) =   series.LineBorder.Pattern <-
+                         match c with
+                            | LineStyle.Dashed -> LinePattern.Dash      
+                            | LineStyle.Solid  -> LinePattern.Solid     
+                            | LineStyle.Square -> LinePattern.DashDot   
+                            | LineStyle.DotDot -> LinePattern.DashDotDot
+                            | _  -> LinePattern.Solid  
+                       update()
+    member this.LineSize 
+        with get() = float series.LineWidth       
+        and set(c) = series.LineWidth <- float32 c ; update()
+    member this.MarkerColor  
+        with get() = series.Markers.FillEffect.Color
+        and set(c) = series.Markers.FillEffect.Color <- c ; update()   
+    
+    member this.MarkerStyle 
+        with get () = match series.Markers.Style with
+                        | PointStyle.Star           -> MarkerStyle.Star
+                        | PointStyle.Pyramid        -> MarkerStyle.Triangle
+                        | PointStyle.Cross          -> MarkerStyle.Plus
+                        | PointStyle.Ellipse        -> MarkerStyle.Circle
+                        | PointStyle.DiagonalCross  -> MarkerStyle.X
+                        | PointStyle.InvertedPyramid-> MarkerStyle.Diamond
+                        | _ -> MarkerStyle.None
+        and set (c) = series.Markers.Style <- 
+                        match c with
+                          |  MarkerStyle.Star       ->  PointStyle.Star           
+                          |  MarkerStyle.Triangle   ->  PointStyle.Pyramid        
+                          |  MarkerStyle.Plus       ->  PointStyle.Cross          
+                          |  MarkerStyle.Circle     ->  PointStyle.Ellipse        
+                          |  MarkerStyle.X          ->  PointStyle.DiagonalCross  
+                          |  MarkerStyle.Diamond    ->  PointStyle.InvertedPyramid
+                          | _                       ->  PointStyle.Bar
+                      update()  
+    
+    member this.MarkerSize 
+        with get() = float series.Markers.Width
+        and set(c) = series.Markers.Width <- (float32 c) ; update()
+    member this.ShowLabels
+        with get () = series.DataLabels.Mode  = DataLabelsMode.Every
+        and set(c) =  if c then series.DataLabels.Mode <- DataLabelsMode.Every
+                      else series.DataLabels.Mode <- DataLabelsMode.None
+                      update()                     
+        
+    member this.BorderColor  
+        with get() = series.LineBorder.Color
+        and set(c) = series.LineBorder.Color <- c ; update()   
+    
+    member this.XYValues     
+        with get() = let xvals : float list = series.XValues |> Seq.cast |> Seq.toList
+                     let yvals : float list = series.Values |> Seq.cast |> Seq.toList
+                     ( (List.toArray xvals) , (List.toArray yvals) )
+        and set(c) = let xs,ys = c
+                     series.Values.Clear() ; series.XValues.Clear()
+                     Array.iter2 (fun x y -> series.AddXY(y,x)) xs ys
+                     update()
+                     
+  
+type Stock(xs:float[],openY:float[],highY:float[],lowY:float[],closeY:float[]) as self = 
+    inherit Plot2D() 
+
+    let series = new StockSeries()
+    
+    do  AssertSameSize [xs;openY;lowY;highY;closeY]
+    do  Array.iteri (fun i x -> series.AddStock(openY.[i],highY.[i],lowY.[i],closeY.[i],x)) xs    
+    do  series.DataLabels.Mode <- DataLabelsMode.None
+    do  series.UseXValues <- true
+    let update() = self.UpdateFire()
+    override this.Series = (series :> SeriesBase)  
+    //member this.Size  with set(s) = series.Size <- float32 s; update()
+    member this.CandleWidth with set(c) = series.CandleWidth <- float32 c; update()
+    
+    new (xs:float[],highY:float[],lowY:float[],closeY:float[]) = 
+        new Stock(xs,[||] ,highY ,lowY,closeY) 
+    new (xs:float[], (openY : float->float), (highY : float->float),lowY,closeY) = new Stock(xs,Array.map openY xs,Array.map highY xs,Array.map lowY xs,Array.map closeY xs)
+    override this.DimensionPreference = [| None; None; Some AxisScaleMode.Numeric |]
+  
+    member this.StockSeries = series
+    member this.BarColor 
+       with get () =  series.DownFillEffect.Color
+       and set(c) = series.DownFillEffect.Color <- c ; update() 
+    member this.LineColor 
+       with get () =  series.UpFillEffect.Color
+       and set(c) = series.UpFillEffect.Color <- c ;series.DownFillEffect.Color <- c; update()              
+    member this.BorderColor 
+        with get () = series.UpFillEffect.Color
+        and set(c) = series.UpFillEffect.Color <- c ; update()  
+    member this.ShowLabels
+        with get () = series.DataLabels.Mode  = DataLabelsMode.Every
+        and set(c) =  if c then series.DataLabels.Mode <- DataLabelsMode.Every
+                      else series.DataLabels.Mode <- DataLabelsMode.None
+                      update()                     
+
+  
+type Pie(ys:float[],xplodeList : int[], labels:string[]) as self = 
+    inherit Plot2D() 
+    let series = new PieSeries()
+    let explode =  xplodeList
+    do  Array.iter2 (fun x lab -> series.Add(x,lab); series.Detachments.Add(0 :> obj) |> ignore) ys labels
+    do    Array.iteri (fun index x -> series.Detachments.set_Item(index,x)  |> ignore ) explode
+    let update() = self.UpdateFire()
+    override this.Series = (series :> SeriesBase)
+  
+    new (ys) = new Pie(ys,Array.map (fun y -> 0) ys, Array.map (fun y -> "") ys)
+    
+    new(ys, labels:string[]) = 
+        new Pie(ys,Array.map (fun y -> 2) ys,labels)  //then
+      
+    member this.Detach(i : int, x : int) = 
+        series.Detachments.set_Item(i,x)
+    member this.ResetDetach() = 
+        Array.iteri (fun index x -> series.Detachments.set_Item(index,0)  |> ignore ) explode
+    override this.DimensionPreference = [| None; None; Some AxisScaleMode.Numeric |]    
+    member this.PieSeries = series
+    member this.Explose 
+       with get () = series.Detachments.Count > 0
+       and set(c) = 
+        if c then
+            let arrobj = Array.create (series.Values.Count) (new obj())
+            Array.iter (fun e-> series.Detachments.Add(arrobj)|> ignore ) arrobj
+        else series.Detachments.Clear()
+        update()
+        
+    member this.Values
+        with set (c : float[]) = series.Values.Clear(); series.Values.FillFromEnumerable c; update()
+        and get() = let vals : float list = series.Values |> Seq.cast |> Seq.toList
+                    List.toArray vals
+    member this.Labels
+        with set (c : string[]) = series.Labels.Clear(); series.Labels.FillFromEnumerable c; update()
+        and get() = let vals : string list = series.Labels |> Seq.cast |> Seq.toList
+                    List.toArray vals
+    member this.ShowLabels
+        with get () = series.DataLabels.Mode  = DataLabelsMode.Every
+        and set(c) =  if c then series.DataLabels.Mode <- DataLabelsMode.Every
+                      else series.DataLabels.Mode <- DataLabelsMode.None
+                      update()                     
+    member this.BorderColor 
+        with get () = series.PieBorder.Color
+        and set(c) = series.PieBorder.Color <- c ; update()  
+    
+
+  
+  
+type Area(xs:float[], ys:float[]) as self =
+        inherit Plot2D() 
+        let n1,n2 = xs.Length,ys.Length
+        do  assert(n1=n2)
+        let series = new AreaSeries()
+        do  series.UseXValues <- true
+        do  Array.iter2 (fun x y -> series.AddXY(x,y)) xs ys
+        let update() = self.UpdateFire()
+        override this.Series = (series :> SeriesBase)
+        override this.DimensionPreference = [| None; None; Some AxisScaleMode.Numeric |]
+         
+        member this.AreaSeries = series
+        member this.DataLabels 
+            with set(x) = series.DataLabels.Mode <- x
+            and get() = series.DataLabels.Mode
+        
+        member this.LineStyle 
+            with set(value) = series.Appearance.LineMode <- value
+            and get () = series.Appearance.LineMode 
+
+        member this.EdgeDisplay
+            with set(value) = series.DropLines <-value
+            and get()= series.DropLines
+        member this.BorderColor 
+            with get()=  series.AreaBorder.Color
+            and set (value) = 
+                series.AreaBorder.Color <- value; update()
+                
+        member this.Color  
+            with set(value) = series.AreaFillEffect.SetSolidColor(value) ; update()
+            and get() = series.AreaFillEffect.Color
+        member this.ShowLabels
+            with get () = series.DataLabels.Mode  = DataLabelsMode.Every
+            and set(c) =  if c then series.DataLabels.Mode <- DataLabelsMode.Every
+                          else series.DataLabels.Mode <- DataLabelsMode.None
+                          update()                     
+    
+                                 
+    
+type Chart2D() =
+    do license()
+    let panel = new Panel()
+    do panel.Dock <- DockStyle.Fill
+    let toolbar = new ChartToolbarControl(Dock=DockStyle.Top)
+    do  panel.Controls.Add(toolbar)
+    let myChart = new ChartControl(Height=panel.Height-toolbar.Height,
+                                   Location=new Point(0,toolbar.Height),
+                                   Width=panel.Width,
+                                   Dock=DockStyle.Bottom,
+                                   Anchor = (AnchorStyles.Right ||| AnchorStyles.Left ||| AnchorStyles.Top ||| AnchorStyles.Bottom))
+    do  panel.Controls.Add(myChart)
+    
+    do  toolbar.ChartControl <- myChart
+    let arrButtons = new ChartToolbarButtonsArray(toolbar)
+    do  List.iter (arrButtons.Add >> ignore)
+          [ChartToolbarButtons.ImageExport; ChartToolbarButtons.Print;     ChartToolbarButtons.Separator;
+           ChartToolbarButtons.MouseOffset; ChartToolbarButtons.MouseZoom; ChartToolbarButtons.Separator;
+           ChartToolbarButtons.ChartEditor; 
+          ]
+    do  toolbar.ButtonsConfig <- arrButtons    
+    let showToolbar flag =
+        toolbar.Visible <- flag
+        let barHeight = if flag then toolbar.Height else 0
+        myChart.Location <- Point(0,barHeight)
+        myChart.Height   <- panel.Height-barHeight
+
+    do myChart.InteractivityOperations.Add(new TrackballDragOperation()) |> ignore
+    do myChart.Settings.EnableAntialiasing <- false
+
+    let header = myChart.Labels.AddHeader("Chart2D")        
+
+    let aChart = myChart.Charts.get_Item(0)    
+    
+    do aChart.Wall(ChartWallType.Floor).Width <- 0.01f
+    do aChart.Wall(ChartWallType.Back ).Width <- 0.01f
+    do aChart.Wall(ChartWallType.Left ).Width <- 0.01f
+    do aChart.View.SetPredefinedProjection(PredefinedProjection.PerspectiveTilted)
+    do aChart.LightModel.SetPredefinedScheme(LightScheme.ShinyTopLeft)
+    let refresh _ = myChart.Refresh(); Application.DoEvents()
+    let showHeader = function 
+      | true  -> myChart.Labels.Add(header)    |> ignore; refresh()
+      | false -> myChart.Labels.Remove(header) |> ignore; refresh()
+    let showLegend = function 
+      | true  -> myChart.Legends.Item(0).Mode <- LegendMode.Automatic; refresh()  // always have Item(0) ??
+      | false -> myChart.Legends.Item(0).Mode <- LegendMode.Disabled;  refresh()
+
+    let acceptTypes tys (x:IPlot) = List.exists (fun (ty:System.Type) -> ty.IsAssignableFrom(x.GetType())) tys
+    
+    interface IChart with
+        member this.Control = panel :> Control
+        member  this.Accepts(x) = acceptTypes [typeof<Bars>; typeof<HighLow>; typeof<Points>;typeof<Lines>;typeof<Stock>;typeof<Pie>;typeof<Area>] x // somebody needs to call this
+        member this.Add(x:IPlot) =
+            match x with
+            | :? Plot2D as plot -> 
+                if (this :> IChart).Accepts plot then
+                    aChart.Series.Add(plot.Series) |> ignore;  // add series to chart
+                    plot.Update.Add refresh;                   // listen to update events from plot      
+                    Array.iteri (fun i pref ->
+                              match pref with
+                                 | None -> ()                                     // no pref for dimension i
+                                 | Some mode -> aChart.Axis(2).ScaleMode <- mode) // set pref...
+                       plot.DimensionPreference
+                    refresh()
+                else printf "You tried to add an unsupported IChart object..\n"
+            | ty -> ()
+        member this.Context = [| MenuItemToggle "Show Toolbar" true showToolbar;
+                                 MenuItemToggle "Show Header"  true showHeader;
+                                 MenuItemToggle "Show Legend"  true showLegend;
+                              |]        
+    member this.Added(plot:Plot2D) =       
+        (this :> IChart).Add(plot) 
+        plot
+    member this.Title with set x = header.Text <- x; refresh()
+    member this.Refresh() = myChart.Refresh()
+    member this.Chart = aChart // expose
+    member this.Width  with set x = aChart.Width  <- float32 x // demo required
+    member this.Height with set x = aChart.Height <- float32 x // demo required
+    member this.ChartControl = myChart // expose
+    member this.ScaleNumeric() = 
+        this.Chart.Axis(2).ScaleMode <- AxisScaleMode.Numeric
+    member this.Header  with set(x) = showHeader x; refresh() 
+    member this.Toolbar with set(x) = showToolbar x; refresh() 
+
+type XCeedChartFactory() = 
+    let acceptTypes tys (x:IPlot) = List.exists (fun (ty:System.Type) -> ty.IsAssignableFrom(x.GetType())) tys
+    interface IChartFactory  with
+        override this.Name     = "XCeed Charts"
+        override this.Accepts(x) = acceptTypes [typeof<ILines>; typeof<Bars>; typeof<HighLow>; typeof<Points>;typeof<Lines>;typeof<Stock>;typeof<Pie>;typeof<Area>] x
+        override this.Create() =  (new Chart2D() :> IChart) // ask xceed provider later
+
+
+[<AbstractClass>]
+type Plot3D() as self =
+    let updateFire,updateEvent = 
+        let e = new Event<_>() in
+        e.Trigger, e.Publish
+    
+    
+    abstract Series : SeriesBase
+    abstract DimensionPreference : AxisScaleMode option array // internal - option preferences on dimension scales
+    member this.Update = updateEvent : bool IEvent
+    member this.UpdateFire() = updateFire true
+
+    interface IPlot with
+      member t.BasePlot = self :> IPlot
+  
+/// X-Y scatter plot
+type Points3D(xs:float[],ys:float[],zs:float[]) as self = 
+    inherit Plot3D() 
+    do  AssertSameSize [xs;ys;zs]
+    let series = new PointSeries(Name="Points")
+    do  series.UseXValues <- true
+    do  series.UseZValues <- true
+    do  Array.iteri (fun i x -> series.AddPoint(ys.[i],x,zs.[i])) xs
+    do  series.Size <- 2.0f
+    do  series.PointBorder.Width <- 0
+    do  series.DataLabels.Mode <- DataLabelsMode.None
+    let update() = self.UpdateFire()
+    member this.Name       with set(s) = series.Name <- s; update()
+    member this.DataLabels with set(x) = series.DataLabels.Mode <- x; update() // REVIEW: abstract
+    member this.Color      with set(x) = series.PointFillEffect.Color <- x; update()
+    member this.Style      with set(x) = series.PointStyle <- x; update() // REVIEW: abstract
+    member this.Size       with set(x)  = series.Size <- float32 x; update()
+    override this.Series = (series :> SeriesBase)
+    override this.DimensionPreference = [| None; None; Some AxisScaleMode.Numeric |]
+  
+type Lines3D(xs:float[],ys:float[],zs:float[]) as self = 
+    inherit Plot3D() 
+    do  AssertSameSize [xs;ys;zs]
+    let series = new LineSeries(Name="Lines")
+    do  series.UseXValues <- true
+    do  series.UseZValues <- true
+    do  Array.iteri (fun i x -> series.AddXYZ(ys.[i],x,zs.[i])) xs     
+    do  series.LineStyle <- LineSeriesStyle.Line
+    do  series.LineWidth <- 0.1f
+    do  series.LineBorder.Width <- 1
+    do  series.DataLabels.Mode <- DataLabelsMode.None
+    let update() = self.UpdateFire()
+    member this.Name       with set(s) = series.Name <- s; update()
+    member this.DataLabels with set(x) = series.DataLabels.Mode <- x; update() // REVIEW: abstract
+    member this.Color      with set(x) = series.LineFillEffect.Color <- x; update()
+    member this.Style      with set(x) = series.LineStyle <- x; update() // REVIEW: abstract
+    member this.Size       with set(x) = series.LineWidth <- float32 x; update()
+    override this.Series = (series :> SeriesBase)
+    override this.DimensionPreference = [| None; None; Some AxisScaleMode.Numeric |]
+
+
+type SurfaceGrid3D(xs:float[],ys:float[],f : int -> int -> float) = 
+    inherit Plot3D()
+    let n1,n2 = xs.Length,ys.Length
+    let grid = seq {for i in 0 .. n1-1 do for j in 0 .. n2-1 do yield i,j}
+    let gridSurfaceSeries = new GridSurfaceSeries(Name="Surface Grid")
+    do gridSurfaceSeries.Data.SetGridSize(n1,n2)
+    do grid |> Seq.iter (fun (i,j) -> gridSurfaceSeries.Data.SetValue(i,j,f i j))
+    override this.Series = (gridSurfaceSeries :> SeriesBase)
+    override this.DimensionPreference = [| None; None; Some AxisScaleMode.Numeric; Some AxisScaleMode.Numeric;  |]            
+    member   this.Flat with set(x) = gridSurfaceSeries.DrawFlat <- x
+    new (xs:float[],ys:float[],f : float -> float -> float) = new SurfaceGrid3D(xs,ys,fun i j -> f xs.[i] ys.[j])
+
+
+type SurfaceMesh3D(xs:float[],ys:float[],f) as self =
+    inherit Plot3D()
+    let n1,n2 = xs.Length,ys.Length
+    let grid = seq {for i in 0 .. n1-1 do for j in 0 .. n2-1 do yield i,j}
+
+    let meshSurfaceSeries = new MeshSurfaceSeries(Name = "Surface Mesh")
+    do  meshSurfaceSeries.Data.SetGridSize(n1,n2)
+    let setSurface f = 
+      let eval i j = f xs.[i] ys.[j] : float
+      grid |> Seq.iter (fun (i,j) -> meshSurfaceSeries.Data.SetValue(i,j,eval i j,xs.[i],ys.[j]))
+    do setSurface f
+    let update() = self.UpdateFire()
+    override this.Series = (meshSurfaceSeries :> SeriesBase)
+    override this.DimensionPreference = [| None; Some AxisScaleMode.Numeric; Some AxisScaleMode.Numeric;  |]
+    member   this.Transparency with set(x) = meshSurfaceSeries.FillEffect.SetTransparencyPercent(x)
+    member   this.Flat with set(x) = meshSurfaceSeries.DrawFlat <- x
+    member   this.Surface with set(f) = setSurface f; update()
+
+
+type Chart3D() =
+    do license()
+    let panel  = new Panel()
+    let toolbar = new ChartToolbarControl(Dock=DockStyle.Top)
+    do  panel.Controls.Add(toolbar)
+    let myChart = new ChartControl(Height=panel.Height-toolbar.Height,
+                                   Location=new Point(0,toolbar.Height),
+                                   Width=panel.Width,
+                                   Dock=DockStyle.Bottom,
+                                   Anchor = (AnchorStyles.Right ||| AnchorStyles.Left ||| AnchorStyles.Top ||| AnchorStyles.Bottom))
+    do  panel.Controls.Add(myChart)
+    
+    do  toolbar.ChartControl <- myChart
+    let arrButtons = new ChartToolbarButtonsArray(toolbar)
+    do  List.iter (arrButtons.Add >> ignore)
+          [ChartToolbarButtons.ImageExport; ChartToolbarButtons.Print;     ChartToolbarButtons.Separator;
+           ChartToolbarButtons.MouseTrackball; ChartToolbarButtons.MouseOffset; ChartToolbarButtons.MouseZoom; ChartToolbarButtons.Separator;
+           ChartToolbarButtons.ChartEditor; 
+           //ChartToolbarButtons.RenderDevice
+          ]
+    do  toolbar.ButtonsConfig <- arrButtons    
+    let showToolbar flag = // same code as Chart2D
+      toolbar.Visible <- flag
+      let barHeight = if flag then toolbar.Height else 0
+      myChart.Location <- Point(0,barHeight)
+      myChart.Height   <- panel.Height-barHeight   
+
+    do myChart.Settings.RenderDevice <- RenderDevice.OpenGL // for 3D
+    do myChart.InteractivityOperations.Add(new TrackballDragOperation()) |> ignore
+    do myChart.Settings.EnableAntialiasing <- false
+
+    let header = myChart.Labels.AddHeader("Chart3D")              
+    let aChart = myChart.Charts.get_Item(0)
+    
+    do aChart.Depth  <- 40.0f
+    do aChart.Width  <- 40.0f
+    do aChart.Height <- 40.0f
+    
+    do aChart.Wall(ChartWallType.Floor).Width <- 0.01f
+    do aChart.Wall(ChartWallType.Back ).Width <- 0.01f
+    do aChart.Wall(ChartWallType.Left ).Width <- 0.01f
+    do aChart.View.SetPredefinedProjection(PredefinedProjection.PerspectiveTilted)
+    do aChart.LightModel.SetPredefinedScheme(LightScheme.ShinyTopLeft)
+    let refresh _ = myChart.Refresh()
+    let showHeader = function 
+      | true  -> myChart.Labels.Add(header)    |> ignore; refresh()
+      | false -> myChart.Labels.Remove(header) |> ignore; refresh()
+    let showLegend = function 
+      | true  -> myChart.Legends.Item(0).Mode <- LegendMode.Automatic; refresh()  // always have Item(0) ??
+      | false -> myChart.Legends.Item(0).Mode <- LegendMode.Disabled;  refresh()
+
+    let acceptTypes tys (x:IPlot) = List.exists (fun (ty:System.Type) -> ty.IsAssignableFrom(x.GetType())) tys
+                
+    member this.Add(plot:Plot3D) =
+      aChart.Series.Add(plot.Series) |> ignore;  // add series to chart
+      plot.Update.Add refresh;                   // listen to update events from plot      
+      Array.iteri (fun i pref -> match pref with
+                                 | None -> ()                                     // no pref for dimension i
+                                 | Some mode -> aChart.Axis(i).ScaleMode <- mode) // set pref...
+                   plot.DimensionPreference
+      let axD = aChart.Axis(StandardAxis.Depth) in axD.ScaleMode <- AxisScaleMode.Numeric // what number axis is this?
+      refresh()
+    member this.Added(plot:Plot3D) = this.Add(plot); plot
+    member this.Title with set x = header.Text <- x; refresh()
+    member this.Refresh() = myChart.Refresh()
+    member this.Chart = aChart // expose
+    member this.ChartControl = myChart // expose  
+        
+    interface IChart with
+        member this.Control = panel :> Control
+        member  this.Accepts(x) = acceptTypes [typeof<Points3D>;typeof<Lines3D>;typeof<SurfaceGrid3D>;typeof<SurfaceMesh3D>] x // somebody needs to call this
+        member this.Add(x:IPlot) =
+            match x with
+                | :? Plot3D as plot -> 
+                    if (this :> IChart).Accepts plot then
+                        aChart.Series.Add(plot.Series) |> ignore;  // add series to chart
+                        plot.Update.Add refresh;                   // listen to update events from plot      
+                        Array.iteri (fun i pref ->
+                                  match pref with
+                                     | None -> ()                                     // no pref for dimension i
+                                     | Some mode -> aChart.Axis(i).ScaleMode <- mode) // set pref...
+                           plot.DimensionPreference
+                        let axD = aChart.Axis(StandardAxis.Depth) in axD.ScaleMode <- AxisScaleMode.Numeric // what number axis is this?
+                        refresh()
+                    else printf "You tried to add an unsupported IChart object..\n"
+                | ty -> ()  
+        member this.Context = [| MenuItemToggle "Show Toolbar" true showToolbar;
+                                 MenuItemToggle "Show Header"  true showHeader;
+                                 MenuItemToggle "Show Legend"  true showLegend;                                 
+                              |]        
+
+type XCeedChart3DFactory() = 
+    let acceptTypes tys (x:IPlot) = List.exists (fun ty -> ty = x.GetType()) tys
+    interface IChartFactory  with
+        override this.Name     = "XCeed Charts 2D"
+        override this.Accepts(x) = acceptTypes [typeof<Points3D>;typeof<Lines3D>;typeof<SurfaceGrid3D>;typeof<SurfaceMesh3D>] x
+        override this.Create() =  (new Chart3D() :> IChart) // ask xceed provider later
+
+(*let x= Bars(xs)
+let y = new Bars(args) :> XceedBarsx*)
+
+
+#if extension 
+type Microsoft.FSharp.Plot.Interactive.myplot with
+    member this.XceedBars(args) = (new Bars(args) :> XceedBars)
+    member this.XceedLines(args) = (new Lines(args) :> XceedLines)
+    member this.XceedPoints(args) = (new Points(args) :> XceedPoints)
+    member this.XceedStock (xs,openY:float[],highY,lowY,closeY) = (new Stock(xs,openY,highY,lowY,closeY) :> XceedStock)
+    member this.XceedStock (xs,highY,lowY,closeY) = (new Stock(xs,highY,lowY,closeY) :> XceedStock)
+    member this.XceedPie(ys,labels) = (new Pie(ys,labels) :> XceedPie)
+    member this.XceedArea(xs,ys)   = (new Area(xs,ys) :> XceedArea)
+
+#endif 
+
+
+type XceedChartProvider () = 
+    inherit ChartProvider()
+    let bar (plot :Bars)=
+        { new IBars with
+          member t.Alignment    with get() = plot.Alignment and set x = plot.Alignment <- x
+          member t.Color        with get() = plot.Color  and set x = plot.Color  <- x
+          member t.Labels       with get() = plot.Labels and set x = plot.Labels <- x
+          member t.Values       with get() = plot.Values and set x = plot.Values <- x
+          member t.BorderColor  with get() = plot.BorderColor  and set x = plot.BorderColor  <- x
+          member t.Name         with get() = plot.Name and set x = plot.Name <- x
+          member t.ShowLabels   with get() = plot.ShowLabels and set x = plot.ShowLabels <- x        
+          member t.BasePlot = plot :> IPlot
+        }
+    let lines (plot : Lines) = 
+        { new ILines with
+            member t.LineColor     with get() = plot.LineColor  and set x = plot.LineColor  <- x
+            member t.LineStyle     with get() = plot.LineStyle and set x = plot.LineStyle <- x   
+            member t.LineSize      with get() = plot.LineSize and set x = plot.LineSize <- x
+            member t.MarkerColor   with get() = plot.MarkerColor  and set x = plot.MarkerColor  <- x
+            member t.MarkerSize    with get() = plot.MarkerSize and set x = plot.MarkerSize <- x
+            member t.MarkerStyle   with get() = plot.MarkerStyle and set x = plot.MarkerStyle <- x
+            member t.XYValues      with get() = plot.XYValues and set x = plot.XYValues <- x
+            member t.BorderColor   with get() = plot.BorderColor  and set x = plot.BorderColor  <- x
+            member t.Name          with get() = plot.Name and set x = plot.Name <- x
+            member t.ShowLabels    with get() = plot.ShowLabels and set x = plot.ShowLabels <- x
+            member t.BasePlot = plot :> IPlot
+        }
+    let scatter (plot : Points) = 
+        { new IScatter with
+            member t.MarkerColor   with get() = plot.MarkerColor  and set x = plot.MarkerColor  <- x
+            member t.MarkerSize    with get() = plot.MarkerSize and set x = plot.MarkerSize <- x   
+            member t.MarkerStyle   with get() = plot.MarkerStyle and set x = plot.MarkerStyle <- x
+            member t.XYValues      with get() = plot.XYValues and set x = plot.XYValues <- x
+            member t.BorderColor   with get() = plot.BorderColor  and set x = plot.BorderColor  <- x
+            member t.Name          with get() = plot.Name and set x = plot.Name <- x
+            member t.ShowLabels    with get() = plot.ShowLabels and set x = plot.ShowLabels <- x
+            member t.BasePlot = plot :> IPlot
+        }   
+    let stock (plot : Stock) = 
+        { new IStock with
+            member t.BarColor       with get() = plot.BarColor  and set x = plot.BarColor  <- x
+            member t.LineColor      with get() = plot.LineColor  and set x = plot.LineColor  <- x   
+            member t.BorderColor    with get() = plot.BorderColor  and set x = plot.BorderColor  <- x
+            member t.Name           with get() = plot.Name and set x = plot.Name <- x
+            member t.ShowLabels     with get() = plot.ShowLabels and set x = plot.ShowLabels <- x
+            member t.BasePlot = plot :> IPlot
+        }   
+    let pie (plot : Pie) = 
+        { new IPie with
+            member t.Explose       with get() = plot.Explose and set x = plot.Explose <- x
+            member t.Labels        with get() = plot.Labels and set x = plot.Labels  <- x   
+            member t.Values        with get() = plot.Values and set x = plot.Values <- x
+            member t.BorderColor   with get() = plot.BorderColor  and set x = plot.BorderColor <- x
+            member t.Name          with get() = plot.Name and set x = plot.Name <- x
+            member t.ShowLabels    with get() = plot.ShowLabels and set x = plot.ShowLabels <- x
+            member t.BasePlot = plot :> IPlot
+        } 
+    let area (plot : Area) = 
+        { new IArea with
+            member t.Color         with get() = plot.Color  and set x = plot.Color   <- x
+            member t.BorderColor   with get() = plot.BorderColor  and set x = plot.BorderColor  <- x   
+            member t.Name          with get() = plot.Name and set x = plot.Name <- x
+            member t.ShowLabels    with get() = plot.ShowLabels and set x = plot.ShowLabels<- x
+            member t.BasePlot = plot :> IPlot
+        }                
+    override this.Bars(args)        = bar(new Bars(args))
+    override this.Lines(args)      = lines(new Lines(args))
+    override this.Scatter(args)    = scatter(new Points(args))
+    override this.Stock (xs,openY,highY,lowY,closeY) 
+                                    = stock(new Stock(xs,openY,highY,lowY,closeY))
+    override this.Stock (xs,highY,lowY,closeY) 
+                                    = stock(new Stock(xs,highY,lowY,closeY))
+    override this.Pie(ys,labels)    = pie(new Pie(ys,labels))
+    override this.Area(xs,ys)       = area(new Area(xs,ys))
+
+let xceedProvider = new XceedChartProvider() :> ChartProvider
+let RegisterProvider() = Microsoft.FSharp.Plot.Core.SetProvider xceedProvider
+do  RegisterProvider()
+
+do Microsoft.FSharp.Plot.Interactive.addFactory (new XCeedChartFactory()   :> IChartFactory);
+do Microsoft.FSharp.Plot.Interactive.addFactory (new XCeedChart3DFactory() :> IChartFactory);
diff --git a/workyard/linq/FSharp.PowerPack.Linq/Assembly.fs b/workyard/linq/FSharp.PowerPack.Linq/Assembly.fs
new file mode 100644
index 0000000..fb5d3a2
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/Assembly.fs
@@ -0,0 +1,8 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp
+
+//[<assembly: System.Security.SecurityTransparent>]
+[<assembly: AutoOpen("Microsoft.FSharp")>]
+[<assembly: AutoOpen("Microsoft.FSharp")>]
+do()
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj b/workyard/linq/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj
new file mode 100644
index 0000000..b5dab3a
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{4c2ed03b-5ace-427b-8285-ad333e60f35e}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>FSharp.PowerPack.Linq</AssemblyName>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <DocumentationFile>FSharp.PowerPack.Linq.xml</DocumentationFile>
+    <NoWarn>$(NoWarn);9</NoWarn>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DefineConstants>TRACE;DEBUG;WITHOUT</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <!-- References -->
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+  </ItemGroup>
+  <!-- Files -->
+  <ItemGroup>
+    <Compile Include="..\assemblyinfo.Common.fs">
+      <Link>assemblyinfo.Common.fs</Link>
+    </Compile>
+    <Compile Include="assemblyinfo.FSharp.PowerPack.Linq.dll.fs">
+      <Link>assemblyinfo.FSharp.PowerPack.Linq.dll.fs</Link>
+    </Compile>
+    <Compile Include="FuncConvertExtensions.fsi" />
+    <Compile Include="FuncConvertExtensions.fs" />
+    <Compile Include="MutableTuple.fs" />
+    <Compile Include="Linq.fsi" />
+    <Compile Include="Linq.fs" />
+    <Compile Include="QueryExtensions.fs" />
+    <Compile Include="LinqQueries.fsi" />
+    <Compile Include="LinqQueries.fs" />
+    <Compile Include="Assembly.fs" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Condition="'$(TargetFramework)'=='Silverlight'" Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.Common.targets" />
+</Project>
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj.vspscc b/workyard/linq/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj.vspscc
new file mode 100644
index 0000000..b6d3289
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/workyard/linq/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.xml b/workyard/linq/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.xml
new file mode 100644
index 0000000..9986ab6
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/FSharp.PowerPack.Linq.xml
@@ -0,0 +1,959 @@
+<?xml version="1.0" encoding="utf-8"?>
+<doc>
+<assembly><name>FSharp.PowerPack.Linq</name></assembly>
+<members>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="M:Microsoft.FSharp.Linq.QuotationEvaluator.ToLinqExpression(Microsoft.FSharp.Quotations.FSharpExpr)">
+<summary>
+ Convert the quotation expression to LINQ expression trees
+
+ This operation will only succeed for a subset of quotation expressions.
+
+ Exceptions: InvalidArgumentException will be raised if the input expression is
+ not in the subset that can be converted to a LINQ expression tree
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="M:Microsoft.FSharp.Linq.QuotationEvaluator.EvaluateUntyped(Microsoft.FSharp.Quotations.FSharpExpr)">
+<summary>
+ Compile the quotation expression by first converting to LINQ expression trees
+
+ Exceptions: InvalidArgumentException will be raised if the input expression is
+ not in the subset that can be converted to a LINQ expression tree
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QuotationEvaluator.Evaluate``1(Microsoft.FSharp.Quotations.FSharpExpr{``0})">
+<summary>
+ Evaluate the quotation expression by first converting to LINQ expression trees
+
+ Exceptions: InvalidArgumentException will be raised if the input expression is
+ not in the subset that can be converted to a LINQ expression tree
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QuotationEvaluator.CompileUntyped(Microsoft.FSharp.Quotations.FSharpExpr)">
+<summary>
+ Compile the quotation expression by first converting to LINQ expression trees
+
+ Exceptions: InvalidArgumentException will be raised if the input expression is
+ not in the subset that can be converted to a LINQ expression tree
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QuotationEvaluator.Compile``1(Microsoft.FSharp.Quotations.FSharpExpr{``0})">
+<summary>
+ Compile the quotation expression by first converting to LINQ expression trees
+
+ Exceptions: InvalidArgumentException will be raised if the input expression is
+ not in the subset that can be converted to a LINQ expression tree
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="M:Microsoft.FSharp.Linq.ExtraHashCompare.GenericNotEqualIntrinsic``1(``0,``0)">
+<summary>
+ An intrinsic for compiling <c>&lt;@ x <> y @&gt;</c> to expression trees
+</summary>
+</member>
+<member name="T:Microsoft.FSharp.Linq.ExtraHashCompare">
+
+</member>
+<member name="M:Microsoft.FSharp.Linq.QueryModule.groupJoin``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},Microsoft.FSharp.Core.FSharpFunc`2{``0,``2},Microsoft.FSharp.Core.FSharpFunc`2{``1,``2},Microsoft.FSharp.Core.FSharpFunc`2{``0,Microsoft.FSharp.Core.FSharpFunc`2{System.Collections.Generic.IEnumerable{``1},``3}})">
+<summary>
+ This join operator implements the LINQ GroupJoin operator and the <c>query</c> convertor recognises it as such
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QueryModule.join``4(System.Collections.Generic.IEnumerable{``0},System.Collections.Generic.IEnumerable{``1},Microsoft.FSharp.Core.FSharpFunc`2{``0,``2},Microsoft.FSharp.Core.FSharpFunc`2{``1,``2},Microsoft.FSharp.Core.FSharpFunc`2{``0,Microsoft.FSharp.Core.FSharpFunc`2{``1,``3}})">
+<summary>
+ This join operator corresponds to the LINQ Join operator and the <c>query</c> convertor recognises it as such
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QueryModule.groupBy``2(Microsoft.FSharp.Core.FSharpFunc`2{``0,``1},System.Collections.Generic.IEnumerable{``0})">
+<summary>
+ When used in queries, this operator corresponds to the LINQ Join operator and the <c>query</c> convertor recognises it as such
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QueryModule.maxBy``2(Microsoft.FSharp.Core.FSharpFunc`2{``0,``1},System.Collections.Generic.IEnumerable{``0})">
+<summary>
+ When used in queries, this operator corresponds to the LINQ Max operator and the <c>query</c> convertor recognises it as such
+ It differs in return type from <c>Seq.maxBy</c>
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QueryModule.minBy``2(Microsoft.FSharp.Core.FSharpFunc`2{``0,``1},System.Collections.Generic.IEnumerable{``0})">
+<summary>
+ When used in queries, this operator corresponds to the LINQ Min operator and the <c>query</c> convertor recognises it as such
+ It differs in return type from <c>Seq.minBy</c>
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QueryModule.contains``1(``0,System.Collections.Generic.IEnumerable{``0})">
+<summary>
+ When used in queries, this operator corresponds to the LINQ Contains operator and the <c>query</c> convertor recognises it as such
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QueryModule.query``1(Microsoft.FSharp.Quotations.FSharpExpr{``0})">
+<summary>
+ Evaluate the quotation expression by first converting to a LINQ expression tree
+ making use of IQueryable operators and then executing expression tree
+
+ Exceptions: <c>InvalidArgumentException</c> will be raised if the input expression is
+ not in the subset that can be converted to a LINQ expression tree
+</summary>
+</member>
+<member name="T:Microsoft.FSharp.Linq.QueryModule">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.QuotationEvaluation.MemberInitializationHelperType">
+<summary>
+ This type should not be called directly. 
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QuotationEvaluation.MemberInitializationHelper``1(Microsoft.FSharp.Linq.QuotationEvaluation.MemberInitializationHelperType)">
+<summary>
+ This function should not be called directly. 
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.QuotationEvaluation.LinqExpressionHelper``1(``0)">
+<summary>
+ This function should not be called directly. 
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.QuotationEvaluation.HelperTypes">
+<summary>
+ A set of types used for implementing quotation conversions.
+ These are public only because targets of Linq Lambda expressions require them to be so
+</summary>
+</member>
+<member name="T:Microsoft.FSharp.Linq.QuotationEvaluation">
+<summary>
+ This module provides Compile and Eval extension members
+ for F# quotation values, implemented by translating to LINQ
+ expression trees and using the LINQ dynamic compiler.
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.ComparableType">
+<summary>
+ Wrapper for System.Type that implements the 'comparable'
+ constraint (to make it possible to use types as keys of Map)
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.IQuotationAdapter">
+<summary>
+ Represents a rule that modifies quotations in some way
+ Processing quotations and types recursively can be done using
+ IQuotationTransformation passed as argument
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.IQuotationTransformation">
+<summary>
+ Represents a transformation of quotations that changes both 
+ expressions and types (e.g. to replace 'int' with 'string')
+ (Recursively processes the whole quotation or type)
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.MutableTuple`1">
+<summary>
+ This type shouldn't be used directly from user code.
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.MutableTuple`2">
+<summary>
+ This type shouldn't be used directly from user code.
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.MutableTuple`3">
+<summary>
+ This type shouldn't be used directly from user code.
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.MutableTuple`4">
+<summary>
+ This type shouldn't be used directly from user code.
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.MutableTuple`5">
+<summary>
+ This type shouldn't be used directly from user code.
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.MutableTuple`6">
+<summary>
+ This type shouldn't be used directly from user code.
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.MutableTuple`7">
+<summary>
+ This type shouldn't be used directly from user code.
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.MutableTuple`8">
+<summary>
+ This type shouldn't be used directly from user code.
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="M:Microsoft.FSharp.Linq.Runtime.ParameterizedType.Rebuild(Microsoft.FSharp.Collections.FSharpList{System.Type})">
+<summary>
+ Provide arguments to the parameterized type
+</summary>
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.ParameterizedType">
+<summary>
+ Represents information about System.Type that has one or more
+ type parameters (and can be reconstructed when arguments are 
+ provided). The type can be pointer, byref, generic or array.
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="M:Microsoft.FSharp.Linq.Runtime.Adapters.TupleAdapter.Microsoft-FSharp-Linq-Runtime-IQuotationAdapter-AdaptType(Microsoft.FSharp.Linq.Runtime.IQuotationTransformation,System.Type)">
+<summary>
+ Turns all top-level uses of tuple into mutable tuples
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.Runtime.Adapters.TupleAdapter.Microsoft-FSharp-Linq-Runtime-IQuotationAdapter-AdaptExpr(Microsoft.FSharp.Linq.Runtime.IQuotationTransformation,Microsoft.FSharp.Quotations.FSharpExpr)">
+<summary>
+ Turns all tupl-level uses of 'NewTuple' and 'TupleGet' into
+ corresponding calls (constructor / property get) on mutable tuples
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.Adapters.TupleAdapter">
+<summary>
+ Adapts tuples in quotations.
+ (Replace uses of the tuple type with 'MutableTuple' type which
+ has get/set properties & parameterless constructor and can be used
+ in LINQ to Entities)
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.Runtime.Adapters.RecordAdapter.Microsoft-FSharp-Linq-Runtime-IQuotationAdapter-AdaptType(Microsoft.FSharp.Linq.Runtime.IQuotationTransformation,System.Type)">
+<summary>
+ Turns all top-level uses of records into tuples
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.Runtime.Adapters.RecordAdapter.Microsoft-FSharp-Linq-Runtime-IQuotationAdapter-AdaptExpr(Microsoft.FSharp.Linq.Runtime.IQuotationTransformation,Microsoft.FSharp.Quotations.FSharpExpr)">
+<summary>
+ Turns all tupl-level uses of 'NewTuple' and 'TupleGet' into
+ corresponding calls (constructor / property get) on mutable tuples
+</summary>
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.Adapters.RecordAdapter">
+<summary>
+ Adapts records in quotations (Replaces uses of records with tuples
+ which can be later removed using TupleAdapter)
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.Runtime.Adapters.|Let|``2(``0,``1)">
+<summary>
+ Declare symbol inside pattern. For example:
+  | Let 1 (i, <NestedPattern#1>) 
+  | Let 2 (i, <NestedPattern#2>) ->
+      // i will be either 1 or 2
+</summary>
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.Adapters">
+
+</member>
+<member name="">
+
+</member>
+<member name="">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.Execution">
+
+</member>
+<member name="M:Microsoft.FSharp.Linq.Runtime.Transformations.transformQuotation(Microsoft.FSharp.Linq.Runtime.IQuotationAdapter,Microsoft.FSharp.Collections.FSharpMap{Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpVar},Microsoft.FSharp.Quotations.FSharpExpr)">
+<summary>
+ Transform quotation using the specified quotation transformation.
+ This replaces expressions according to the 'TransformExpr' and 
+ replaces types according to the 'TransformType' method.
+</summary>
+</member>
+<member name="M:Microsoft.FSharp.Linq.Runtime.Transformations.transformType(Microsoft.FSharp.Linq.Runtime.IQuotationAdapter,Microsoft.FSharp.Linq.Runtime.IQuotationTransformation,System.Type)">
+<summary>
+ Transform a specified type using quotation adapter
+ (This recursively processes all type parameters of the type as well.)
+</summary>
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.Transformations">
+
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.TypeExtensions">
+
+</member>
+<member name="M:Microsoft.FSharp.Linq.Runtime.TypePatterns.|Parameterized|Parameter|Primitive|(System.Type)">
+<summary>
+ Decompose type into several options - A type can be
+ primitive type, type parameter or parameterized type
+</summary>
+</member>
+<member name="T:Microsoft.FSharp.Linq.Runtime.TypePatterns">
+
+</member>
+</members>
+</doc>
diff --git a/workyard/linq/FSharp.PowerPack.Linq/FuncConvertExtensions.fs b/workyard/linq/FSharp.PowerPack.Linq/FuncConvertExtensions.fs
new file mode 100644
index 0000000..b8458fd
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/FuncConvertExtensions.fs
@@ -0,0 +1,28 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Core
+    open System
+    open System.Linq
+
+    [<Sealed; AbstractClass>]
+    type FuncConvertExtensions = 
+
+        static member  ToFSharpFunc( f : Action<_,_>) = (fun a1 a2 -> f.Invoke(a1,a2))
+        static member  ToFSharpFunc( f : Func<_>) = (fun () -> f.Invoke())
+        static member  ToFSharpFunc( f : Func<_,_>) = (fun a1 -> f.Invoke(a1))
+        static member  ToFSharpFunc( f : Func<_,_,_>) = (fun a1 a2 -> f.Invoke(a1,a2))
+        static member  ToFSharpFunc( f : Action<_,_,_>) = (fun a1 a2 a3 -> f.Invoke(a1,a2,a3))
+        static member  ToFSharpFunc( f : Func<_,_,_,_>) = (fun a1 a2 a3 -> f.Invoke(a1,a2,a3))
+        static member  ToFSharpFunc( f : Action<_,_,_,_>) = (fun a1 a2 a3 a4 -> f.Invoke(a1,a2,a3,a4))
+        static member  ToFSharpFunc( f : Func<_,_,_,_,_>) = (fun a1 a2 a3 a4 -> f.Invoke(a1,a2,a3,a4))
+        static member  ToTupledFSharpFunc( f : Func<_>) = (fun () -> f.Invoke())
+        static member  ToTupledFSharpFunc( f : Func<_,_>) = (fun a1 -> f.Invoke(a1))
+        static member  ToTupledFSharpFunc( f : Action<_,_>) = (fun (a1,a2) -> f.Invoke(a1,a2))
+        static member  ToTupledFSharpFunc( f : Func<_,_,_>) = (fun (a1,a2) -> f.Invoke(a1,a2))
+        static member  ToTupledFSharpFunc( f : Action<_,_,_>) = (fun (a1,a2,a3) -> f.Invoke(a1,a2,a3))
+        static member  ToTupledFSharpFunc( f : Func<_,_,_,_>) = (fun (a1,a2,a3) -> f.Invoke(a1,a2,a3))
+        static member  ToTupledFSharpFunc( f : Action<_,_,_,_>) = (fun (a1,a2,a3,a4) -> f.Invoke(a1,a2,a3,a4))
+        static member  ToTupledFSharpFunc( f : Func<_,_,_,_,_>) = (fun (a1,a2,a3,a4) -> f.Invoke(a1,a2,a3,a4))
+
+
diff --git a/workyard/linq/FSharp.PowerPack.Linq/FuncConvertExtensions.fsi b/workyard/linq/FSharp.PowerPack.Linq/FuncConvertExtensions.fsi
new file mode 100644
index 0000000..6102c10
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/FuncConvertExtensions.fsi
@@ -0,0 +1,40 @@
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Core
+    open System
+
+    [<Sealed; AbstractClass>]
+    type FuncConvertExtensions =
+
+        static member  ToFSharpFunc       : Func<'U>     -> (unit -> 'U)
+        
+        static member  ToFSharpFunc       : Func<'T1,'U>     -> ('T1 -> 'U)
+        
+        static member  ToFSharpFunc       : Action<'T1,'T2>           -> ('T1 -> 'T2 -> unit)
+        
+        static member  ToFSharpFunc       : Func<'T1,'T2,'U>     -> ('T1 -> 'T2 -> 'U)
+        
+        static member  ToFSharpFunc       : Action<'T1,'T2,'T3>       -> ('T1 -> 'T2 -> 'T3 -> unit)
+        
+        static member  ToFSharpFunc       : Func<'T1,'T2,'T3,'U> -> ('T1 -> 'T2 -> 'T3 -> 'U)
+
+        static member  ToFSharpFunc       : Action<'T1,'T2,'T3,'T4>       -> ('T1 -> 'T2 -> 'T3 -> 'T4 -> unit)
+        
+        static member  ToFSharpFunc       : Func<'T1,'T2,'T3,'T4,'U> -> ('T1 -> 'T2 -> 'T3 -> 'T4 -> 'U)
+
+        static member  ToTupledFSharpFunc : Func<'U>     -> (unit -> 'U)
+        
+        static member  ToTupledFSharpFunc : Func<'T1,'U>     -> ('T1 -> 'U)
+        
+        static member  ToTupledFSharpFunc : Action<'T1,'T2>           -> ('T1 * 'T2 -> unit)
+        
+        static member  ToTupledFSharpFunc : Func<'T1,'T2,'U>     -> ('T1 * 'T2 -> 'U)
+        
+        static member  ToTupledFSharpFunc : Action<'T1,'T2,'T3>       -> ('T1 * 'T2 * 'T3 -> unit)
+        
+        static member  ToTupledFSharpFunc : Func<'T1,'T2,'T3,'U> -> ('T1 * 'T2 * 'T3 -> 'U)
+
+        static member  ToTupledFSharpFunc : Action<'T1,'T2,'T3,'T4>       -> ('T1 * 'T2 * 'T3 * 'T4 -> unit)
+        
+        static member  ToTupledFSharpFunc : Func<'T1,'T2,'T3,'T4,'U> -> ('T1 * 'T2 * 'T3 * 'T4 -> 'U)
+
diff --git a/workyard/linq/FSharp.PowerPack.Linq/Linq.fs b/workyard/linq/FSharp.PowerPack.Linq/Linq.fs
new file mode 100644
index 0000000..8e2252b
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/Linq.fs
@@ -0,0 +1,936 @@
+// Copyright (c) Microsoft Corporation 2005-2008.
+// This sample code is provided "as is" without warranty of any kind. 
+// We disclaim all warranties, either express or implied, including the 
+// warranties of merchantability and fitness for a particular purpose. 
+//
+
+
+namespace Microsoft.FSharp.Linq
+
+open System
+open System.Linq
+open System.Collections.Generic
+open System.Linq.Expressions
+open System.Reflection
+open System.Reflection.Emit
+open Microsoft.FSharp
+open Microsoft.FSharp.Reflection
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Quotations.Patterns
+open Microsoft.FSharp.Quotations.DerivedPatterns
+
+module ExtraHashCompare =
+    let GenericNotEqualIntrinsic<'T> (x:'T) (y:'T) : bool = not (Microsoft.FSharp.Core.LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<'T> x y)
+
+
+module QuotationEvaluation = 
+    
+    type This = 
+        static member Assembly = typeof<This>.Assembly
+
+    let hashCompareType = typeof<list<_>>.Assembly.GetType("Microsoft.FSharp.Core.LanguagePrimitives+HashCompare")
+    let extraHashCompareType = This.Assembly.GetType("Microsoft.FSharp.Linq.ExtraHashCompare")
+    let genericEqualityIntrinsic = "GenericEqualityIntrinsic" |> hashCompareType.GetMethod
+    let genericNotEqualIntrinsic = "GenericNotEqualIntrinsic" |> extraHashCompareType.GetMethod
+    let genericLessThanIntrinsic = "GenericLessThanIntrinsic" |> hashCompareType.GetMethod
+    let genericGreaterThanIntrinsic = "GenericGreaterThanIntrinsic" |> hashCompareType.GetMethod
+    let genericGreaterOrEqualIntrinsic = "GenericGreaterOrEqualIntrinsic" |> hashCompareType.GetMethod
+    let genericLessOrEqualIntrinsic = "GenericLessOrEqualIntrinsic" |> hashCompareType.GetMethod
+
+
+    type ConvEnv = 
+        {   eraseEquality : bool;
+            varEnv : Map<Var,Expression>
+        }
+    let asExpr x = (x :> Expression)
+
+    let bindingFlags = BindingFlags.Public ||| BindingFlags.NonPublic
+    let instanceBindingFlags = BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.DeclaredOnly
+    let isNamedType(typ:Type) = not (typ.IsArray || typ.IsByRef || typ.IsPointer)
+    let equivHeadTypes (ty1:Type) (ty2:Type) = 
+        isNamedType(ty1) &&
+        if ty1.IsGenericType then 
+          ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition())
+        else 
+          ty1.Equals(ty2)
+
+    let isFunctionType typ = equivHeadTypes typ (typeof<(int -> int)>)
+    let getFunctionType typ = 
+        if not (isFunctionType typ) then invalidArg "typ" "cannot convert recursion except for function types"
+        let tyargs = typ.GetGenericArguments()
+        tyargs.[0], tyargs.[1]
+    
+    let WhileHelper gd b : 'T = 
+        let rec loop () = if gd() then (b(); loop())
+        loop();
+        unbox (box ())
+
+    let ArrayAssignHelper (arr : 'T[]) (idx:int) (elem:'T) : 'unt = 
+        arr.[idx] <- elem;
+        unbox (box ())
+
+
+    let TryFinallyHelper e h = 
+        try e() 
+        finally h()
+
+    let TryWithHelper e filter handler = 
+        try e() 
+        with e when (filter e <> 0) -> handler e
+
+    let WhileMethod = match <@@ WhileHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+    let ArrayAssignMethod = match <@@ ArrayAssignHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+    let TryFinallyMethod = match <@@ TryFinallyHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+    let TryWithMethod = match <@@ TryWithHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+    let StringConcat = match <@@ String.Concat : obj * obj -> string @@> with Lambdas(_, Call(_, minfo, _)) -> minfo | _ -> failwith "couldn't find minfo"
+ 
+    module HelperTypes = 
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 -> unit
+        type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 * 'T20 -> unit
+
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> 'T6
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> 'T7 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> 'T8 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> 'T9 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> 'T10 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> 'T11 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> 'T12 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> 'T13 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> 'T14 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> 'T15 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> 'T16 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> 'T17 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 -> 'T18 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 -> 'T19 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 -> 'T20 
+        type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20, 'T21> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 * 'T20 -> 'T21 
+
+    open HelperTypes
+    
+    let GetActionType (args:Type[])  = 
+        if args.Length <= 4 then 
+            Expression.GetActionType args
+        else
+            match args.Length with 
+            | 5 -> typedefof<ActionHelper<_,_,_,_,_>>.MakeGenericType args
+            | 6 -> typedefof<ActionHelper<_,_,_,_,_,_>>.MakeGenericType args
+            | 7 -> typedefof<ActionHelper<_,_,_,_,_,_,_>>.MakeGenericType args
+            | 8 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 9 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 10 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 11 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 12 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 13 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 14 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 15 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 16 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 17 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 18 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 19 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 20 -> typedefof<ActionHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | _ -> raise <| new NotSupportedException("Quotation expressions with statements or closures containing more then 20 free variables may not be translated in this release of the F# PowerPack. This is due to limitations in the variable binding expression forms available in LINQ expression trees")
+
+    let GetFuncType (args:Type[])  = 
+        if args.Length <= 5 then 
+            Expression.GetFuncType args
+        else
+            match args.Length with 
+            | 6 -> typedefof<FuncHelper<_,_,_,_,_,_>>.MakeGenericType args
+            | 7 -> typedefof<FuncHelper<_,_,_,_,_,_,_>>.MakeGenericType args
+            | 8 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 9 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 10 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 11 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 12 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 13 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 14 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 15 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 16 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 17 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 18 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 19 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 20 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | 21 -> typedefof<FuncHelper<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType args
+            | _ -> raise <| new NotSupportedException("Quotation expressions with statements or closures containing more then 20 free variables may not be translated in this release of the F# PowerPack. This is due to limitations in the variable binding expression forms available in LINQ expression trees")
+            
+
+    let LetRec1Helper (F1:System.Func<_,_,_>) (B:System.Func<_,_>) = 
+        let fhole = ref (Unchecked.defaultof<_>)
+        let f = new System.Func<_,_>(fun x -> F1.Invoke(fhole.Value,x))
+        fhole := f
+        B.Invoke f
+
+    let LetRec2Helper (F1:System.Func<_,_,_,_>) (F2:System.Func<_,_,_,_>) (B:System.Func<_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        B.Invoke(f1,f2)
+
+    let LetRec3Helper (F1:System.Func<_,_,_,_,_>) (F2:System.Func<_,_,_,_,_>) (F3:System.Func<_,_,_,_,_>) (B:System.Func<_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        B.Invoke(f1,f2,f3)
+
+    let LetRec4Helper 
+           (F1:FuncHelper<_,_,_,_,_,_>) 
+           (F2:FuncHelper<_,_,_,_,_,_>) 
+           (F3:FuncHelper<_,_,_,_,_,_>) 
+           (F4:FuncHelper<_,_,_,_,_,_>) 
+           (B:System.Func<_,_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f4hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,x))
+        let f4 = new System.Func<_,_>(fun x -> F4.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        f4hole := f4
+        B.Invoke(f1,f2,f3,f4)
+
+
+    let LetRec5Helper 
+           (F1:FuncHelper<_,_,_,_,_,_,_>) 
+           (F2:FuncHelper<_,_,_,_,_,_,_>) 
+           (F3:FuncHelper<_,_,_,_,_,_,_>) 
+           (F4:FuncHelper<_,_,_,_,_,_,_>) 
+           (F5:FuncHelper<_,_,_,_,_,_,_>) 
+           (B:FuncHelper<_,_,_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f4hole = ref (Unchecked.defaultof<_>)
+        let f5hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,x))
+        let f4 = new System.Func<_,_>(fun x -> F4.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,x))
+        let f5 = new System.Func<_,_>(fun x -> F5.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        f4hole := f4
+        f5hole := f5
+        B.Invoke(f1,f2,f3,f4,f5)
+
+    let LetRec6Helper 
+           (F1:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (F2:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (F3:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (F4:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (F5:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (F6:FuncHelper<_,_,_,_,_,_,_,_>) 
+           (B:FuncHelper<_,_,_,_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f4hole = ref (Unchecked.defaultof<_>)
+        let f5hole = ref (Unchecked.defaultof<_>)
+        let f6hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        let f4 = new System.Func<_,_>(fun x -> F4.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        let f5 = new System.Func<_,_>(fun x -> F5.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        let f6 = new System.Func<_,_>(fun x -> F6.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        f4hole := f4
+        f5hole := f5
+        f6hole := f6
+        B.Invoke(f1,f2,f3,f4,f5,f6)
+
+
+    let LetRec7Helper 
+           (F1:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F2:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F3:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F4:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F5:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F6:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (F7:FuncHelper<_,_,_,_,_,_,_,_,_>) 
+           (B:FuncHelper<_,_,_,_,_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f4hole = ref (Unchecked.defaultof<_>)
+        let f5hole = ref (Unchecked.defaultof<_>)
+        let f6hole = ref (Unchecked.defaultof<_>)
+        let f7hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f4 = new System.Func<_,_>(fun x -> F4.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f5 = new System.Func<_,_>(fun x -> F5.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f6 = new System.Func<_,_>(fun x -> F6.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        let f7 = new System.Func<_,_>(fun x -> F7.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        f4hole := f4
+        f5hole := f5
+        f6hole := f6
+        f7hole := f7
+        B.Invoke(f1,f2,f3,f4,f5,f6,f7)
+
+
+    let LetRec8Helper 
+           (F1:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F2:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F3:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F4:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F5:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F6:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F7:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (F8:FuncHelper<_,_,_,_,_,_,_,_,_,_>) 
+           (B:FuncHelper<_,_,_,_,_,_,_,_,_>) = 
+        let f1hole = ref (Unchecked.defaultof<_>)
+        let f2hole = ref (Unchecked.defaultof<_>)
+        let f3hole = ref (Unchecked.defaultof<_>)
+        let f4hole = ref (Unchecked.defaultof<_>)
+        let f5hole = ref (Unchecked.defaultof<_>)
+        let f6hole = ref (Unchecked.defaultof<_>)
+        let f7hole = ref (Unchecked.defaultof<_>)
+        let f8hole = ref (Unchecked.defaultof<_>)
+        let f1 = new System.Func<_,_>(fun x -> F1.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f2 = new System.Func<_,_>(fun x -> F2.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f3 = new System.Func<_,_>(fun x -> F3.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f4 = new System.Func<_,_>(fun x -> F4.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f5 = new System.Func<_,_>(fun x -> F5.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f6 = new System.Func<_,_>(fun x -> F6.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f7 = new System.Func<_,_>(fun x -> F7.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        let f8 = new System.Func<_,_>(fun x -> F8.Invoke(f1hole.Value,f2hole.Value,f3hole.Value,f4hole.Value,f5hole.Value,f6hole.Value,f7hole.Value,f8hole.Value,x))
+        f1hole := f1
+        f2hole := f2
+        f3hole := f3
+        f4hole := f4
+        f5hole := f5
+        f6hole := f6
+        f7hole := f7
+        f8hole := f8
+        B.Invoke(f1,f2,f3,f4,f5,f6,f7,f8)
+
+
+    let IsVoidType (ty:System.Type)  = (ty = typeof<System.Void>)
+
+    // The following two are used to store recognized 'member intialization pattern' in the quotation 
+    // (it is recognized in LinqQueries and then translated to 'Expression.MemberInit' in Linq)     
+    type internal MemberInitializationHelperType =
+      | MemberInitialization of Expr * Expr list
+
+    let internal MemberInitializationHelper (a:MemberInitializationHelperType) : 'R = 
+      failwith "This function should not be called directly. "
+
+
+    let SequentialHelper (x:'T) (y:'U) = y
+ 
+    let LinqExpressionHelper (x:'T) : Expression<'T> = failwith ""
+    
+    let MakeFakeExpression (x:Expr) = 
+        let minfo = match <@@ LinqExpressionHelper @@> with Lambda(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find method info"
+        Expr.Call(minfo.GetGenericMethodDefinition().MakeGenericMethod [| x.Type |], [ x ])
+
+    let showAll = BindingFlags.Public ||| BindingFlags.NonPublic 
+
+    let WrapVoid b objOpt args (env: ConvEnv) (e:Expression) = 
+        if b then 
+            let frees (e:Expr) = e.GetFreeVars()
+            let addFrees e acc = List.foldBack Set.add (frees e |> Seq.toList) acc
+            let fvs = Option.foldBack addFrees objOpt (List.foldBack addFrees args Set.empty) |> Set.toArray
+            let fvsP = fvs |> Array.map (fun v -> (Map.find v env.varEnv :?> ParameterExpression))
+            let fvtys = fvs |> Array.map (fun v -> v.Type) 
+
+            let dty = GetActionType fvtys 
+            let e = Expression.Lambda(dty,e,fvsP)
+            let d = e.Compile()
+
+            let argtys = Array.append fvtys [| dty |]
+            let delP = Expression.Parameter(dty, "del")
+
+            let m = new System.Reflection.Emit.DynamicMethod("wrapper",typeof<unit>,argtys)
+            let ilg = m.GetILGenerator()
+            
+            ilg.Emit(OpCodes.Ldarg ,fvs.Length)
+            fvs |> Array.iteri (fun i _ -> ilg.Emit(OpCodes.Ldarg ,int16 i))
+            ilg.EmitCall(OpCodes.Callvirt,dty.GetMethod("Invoke",instanceBindingFlags),null)
+            ilg.Emit(OpCodes.Ldnull)
+            ilg.Emit(OpCodes.Ret)
+            let args = Array.append (fvsP |> Array.map asExpr) [| (Expression.Constant(d) |> asExpr) |]
+            Expression.Call((null:Expression),(m:>MethodInfo),args) |> asExpr
+        else
+            e
+
+    let (|GenericEqualityQ|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.GenericEquality @>
+    let (|EqualsQ|_|)    = (|SpecificCall|_|) <@ ( = ) @>
+    let (|GreaterQ|_|)   = (|SpecificCall|_|) <@ ( > ) @>
+    let (|GreaterEqQ|_|) = (|SpecificCall|_|) <@ ( >=) @>
+    let (|LessQ|_|)      = (|SpecificCall|_|) <@ ( <)  @>
+    let (|LessEqQ|_|) = (|SpecificCall|_|) <@ ( <=) @>
+    let (|NotEqQ|_|) = (|SpecificCall|_|) <@ ( <>) @>
+    let (|NotQ|_|) =  (|SpecificCall|_|) <@ not   @>
+    let (|NegQ|_|) = (|SpecificCall|_|) <@ ( ~-) : int -> int @>
+    let (|PlusQ|_|)      = (|SpecificCall|_|) <@ ( + ) @>
+    let (|DivideQ|_|) = (|SpecificCall|_|) <@ ( / ) @> 
+    let (|MinusQ|_|) = (|SpecificCall|_|) <@ ( - ) @>
+    let (|MultiplyQ|_|) = (|SpecificCall|_|) <@ ( * ) @>
+    let (|ModuloQ|_|) = (|SpecificCall|_|) <@ ( % ) @>
+    let (|ShiftLeftQ|_|) = (|SpecificCall|_|) <@ ( <<< ) @>
+    let (|ShiftRightQ|_|) = (|SpecificCall|_|) <@ ( >>> ) @>
+    let (|BitwiseAndQ|_|) = (|SpecificCall|_|) <@ ( &&& ) @>
+    let (|BitwiseOrQ|_|) = (|SpecificCall|_|) <@ ( ||| ) @>
+    let (|BitwiseXorQ|_|) = (|SpecificCall|_|) <@ ( ^^^ ) @>
+    let (|BitwiseNotQ|_|) = (|SpecificCall|_|) <@ ( ~~~ ) @>
+    let (|CheckedNeg|_|) = (|SpecificCall|_|) <@ Checked.( ~-) : int -> int @>
+    let (|CheckedPlusQ|_|)      = (|SpecificCall|_|) <@ Checked.( + ) @>
+    let (|CheckedMinusQ|_|) = (|SpecificCall|_|) <@ Checked.( - ) @>
+    let (|CheckedMultiplyQ|_|) = (|SpecificCall|_|) <@ Checked.( * ) @>
+    let (|ConvCharQ|_|) = (|SpecificCall|_|) <@ char @>
+    let (|ConvDecimalQ|_|) = (|SpecificCall|_|) <@ decimal @>
+    let (|ConvFloatQ|_|) = (|SpecificCall|_|) <@ float @>
+    let (|ConvFloat32Q|_|) = (|SpecificCall|_|) <@ float32 @>
+    let (|ConvSByteQ|_|) = (|SpecificCall|_|) <@ sbyte @>
+    let (|ConvInt16Q|_|) = (|SpecificCall|_|) <@ int16 @>
+    let (|ConvInt32Q|_|) = (|SpecificCall|_|) <@ int32 @>
+    let (|ConvIntQ|_|) = (|SpecificCall|_|) <@ int @>
+    let (|ConvInt64Q|_|) = (|SpecificCall|_|) <@ int64 @>
+    let (|ConvByteQ|_|) = (|SpecificCall|_|) <@ byte @>
+    let (|ConvUInt16Q|_|) = (|SpecificCall|_|) <@ uint16 @>
+    let (|ConvUInt32Q|_|) = (|SpecificCall|_|) <@ uint32 @>
+    let (|ConvUInt64Q|_|) = (|SpecificCall|_|) <@ uint64 @>
+
+    let (|CheckedConvCharQ|_|) = (|SpecificCall|_|) <@ Checked.char @>
+    let (|CheckedConvSByteQ|_|) = (|SpecificCall|_|) <@ Checked.sbyte @>
+    let (|CheckedConvInt16Q|_|) = (|SpecificCall|_|) <@ Checked.int16 @>
+    let (|CheckedConvInt32Q|_|) = (|SpecificCall|_|) <@ Checked.int32 @>
+    let (|CheckedConvInt64Q|_|) = (|SpecificCall|_|) <@ Checked.int64 @>
+    let (|CheckedConvByteQ|_|) = (|SpecificCall|_|) <@ Checked.byte @>
+    let (|CheckedConvUInt16Q|_|) = (|SpecificCall|_|) <@ Checked.uint16 @>
+    let (|CheckedConvUInt32Q|_|) = (|SpecificCall|_|) <@ Checked.uint32 @>
+    let (|CheckedConvUInt64Q|_|) = (|SpecificCall|_|) <@ Checked.uint64 @>
+    let (|LinqExpressionHelperQ|_|) = (|SpecificCall|_|) <@ LinqExpressionHelper @>
+    let (|ArrayLookupQ|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.GetArray : int[] -> int -> int @>
+    let (|ArrayAssignQ|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.SetArray : int[] -> int -> int -> unit @>
+    let (|ArrayTypeQ|_|) (ty:System.Type) = if ty.IsArray && ty.GetArrayRank() = 1 then Some(ty.GetElementType()) else None
+
+    /// Extract member initialization expression stored in 'MemberInitializationHelper' (by LinqQueries.fs)
+    let (|MemberInitializationQ|_|) = function
+      | SpecificCall <@ MemberInitializationHelper @> (None, _, [ Patterns.Value(:? MemberInitializationHelperType as mt, _) ]) -> 
+          let (MemberInitialization(init, props)) = mt
+          Some(init, props)
+      | _ -> None
+    
+    /// Convert F# quotations to LINQ expression trees.
+    /// A more polished LINQ-Quotation translator will be published
+    /// concert with later versions of LINQ.
+    let rec ConvExpr (env:ConvEnv) (inp:Expr) = 
+        //printf "ConvExpr : %A\n" inp
+        match inp with 
+
+        // Generic cases 
+        | Patterns.Var(v) -> 
+                try
+                    Map.find v env.varEnv
+                with
+                |   :? KeyNotFoundException when v.Name = "this" ->
+                        let message = 
+                            "Encountered unxpected variable named 'this'. This might happen because " +
+                            "quotations used in queries can’t contain references to let-bound values in classes unless the quotation literal occurs in an instance member. " +
+                            "If this is the case, workaround by replacing references to implicit fields with references to " +
+                            "local variables, e.g. rewrite\r\n" +
+                            "   type Foo() =\r\n" +
+                            "       let x = 1\r\n" +
+                            "       let bar() = <@ x @>\r\n" +
+                            "as: \r\n" +
+                            "   type Foo() =\r\n" +
+                            "       let x = 1\r\n" +
+                            "       let bar() = let x = x in <@ x @>\r\n";
+
+                        NotSupportedException(message) |> raise    
+        | DerivedPatterns.AndAlso(x1,x2)             -> Expression.AndAlso(ConvExpr env x1, ConvExpr env x2) |> asExpr
+        | DerivedPatterns.OrElse(x1,x2)              -> Expression.OrElse(ConvExpr env x1, ConvExpr env x2)  |> asExpr
+        | Patterns.Value(x,ty)                -> Expression.Constant(x,ty)              |> asExpr
+
+        // REVIEW: exact F# semantics for TypeAs and TypeIs
+        | Patterns.Coerce(x,toTy) -> 
+            let converted = ConvExpr env x 
+            
+            // Linq to Entities doesn't like 'TypeAs' expressions (coercion from
+            // IQueryable<T> to IEnumerable<T>) that are generated e.g. in:
+            //
+            //     <@ seq { for p in dx.Products do
+            //                for c in dx.Categories do yield p } @>
+            //
+            // However, the expression tree has 'C# semantics' so we don't need 
+            // explicit TypeAs if the coercion is statically type-safe. The rules are subtle,
+            // so we don't generate TypeAs (at least) in a simple case when both are 
+            // reference types and the assignment is statically safe.
+            // (see also ``Join using nested 'for' with 'String.Concat' call`` test in v40 build)
+
+            if not toTy.IsValueType && not x.Type.IsValueType && toTy.IsAssignableFrom(x.Type) then converted
+            else Expression.TypeAs(ConvExpr env x,toTy) |> asExpr
+
+        | Patterns.TypeTest(x,toTy) -> 
+            Expression.TypeIs(ConvExpr env x,toTy) |> asExpr
+        
+        // Expr.*Get
+        | Patterns.FieldGet(objOpt,fieldInfo) -> 
+            Expression.Field(ConvObjArg env objOpt None, fieldInfo) |> asExpr
+
+        | Patterns.TupleGet(arg,n) -> 
+             let argP = ConvExpr env arg 
+             let rec build ty argP n = 
+                 match Reflection.FSharpValue.PreComputeTuplePropertyInfo(ty,n) with 
+                 | propInfo,None -> 
+                     Expression.Property(argP, propInfo)  |> asExpr
+                 | propInfo,Some(nestedTy,n2) -> 
+                     build nestedTy (Expression.Property(argP,propInfo) |> asExpr) n2
+             build arg.Type argP n
+              
+        | Patterns.PropertyGet(objOpt,propInfo,args) -> 
+            let coerceTo = 
+                if objOpt.IsSome && FSharpType.IsUnion propInfo.DeclaringType && FSharpType.IsUnion propInfo.DeclaringType.BaseType  then  
+                    Some propInfo.DeclaringType
+                else 
+                    None
+            match args with 
+            | [] -> 
+                Expression.Property(ConvObjArg env objOpt coerceTo, propInfo) |> asExpr
+            | _ -> 
+                let argsP = ConvExprs env args
+                Expression.Call(ConvObjArg env objOpt coerceTo, propInfo.GetGetMethod(true),argsP) |> asExpr
+
+        // Expr.*Set
+        | Patterns.PropertySet(objOpt,propInfo,args,v) -> 
+            let args = (args @ [v])
+            let argsP = ConvExprs env args 
+            let minfo = propInfo.GetSetMethod(true)
+            Expression.Call(ConvObjArg env objOpt None, minfo,argsP) |> asExpr |> WrapVoid (IsVoidType minfo.ReturnType) objOpt args env 
+
+        // Object initialization generated by LinqQueries
+        | MemberInitializationQ(ctor, propInfos) ->
+            let bindings =
+              [| for p in propInfos ->
+                  match p with 
+                  | Patterns.PropertySet(_, pinfo, args, assign) ->
+                      if args <> [] then raise (NotSupportedException "Parameterized properties not supported in member initialization.")
+                      Expression.Bind(pinfo, ConvExpr env assign) :> MemberBinding
+                  | _ -> failwith "Expected PropertySet in member initialization." |]
+            match ConvExpr env ctor with
+            | :? NewExpression as converted ->
+                Expression.MemberInit(converted, bindings) |> asExpr
+            | _ -> failwith "Expected Constructor call in member initialization." 
+    
+        // Expr.(Call,Application)
+        | Patterns.Call(objOpt,minfo,args) -> 
+            let transComparison x1 x2 exprConstructor exprErasedConstructor (intrinsic : MethodInfo) =
+                let e1 = ConvExpr env x1
+                let e2 = ConvExpr env x2
+
+                if env.eraseEquality then
+                    exprErasedConstructor(e1,e2) |> asExpr
+                else 
+                    exprConstructor(e1, e2, false, intrinsic.MakeGenericMethod([|x1.Type|])) |> asExpr
+
+            match inp with 
+            // Special cases for this translation
+            
+            // Do the same thing as C# compiler (It would be nicer to use 'String.Concat(string[])'
+            // but that's not supported in Linq to Entities. See also the test
+            // ``Join using nested 'for' with string concatenation``
+
+            |  PlusQ (_, [ty1;ty2;ty3],[x1;x2]) when (ty1 = typeof<string>) && (ty2 = typeof<string>) ->
+                 Expression.Add(ConvExpr env x1, ConvExpr env x2, StringConcat) |> asExpr
+
+
+            //| SpecificCall <@ LanguagePrimitives.GenericEquality @>([ty1],[x1;x2]) 
+            //| SpecificCall <@ ( = ) @>([ty1],[x1;x2]) when (ty1 = typeof<string>) ->
+            //     ConvExpr env (<@@  System.String.op_Equality(%%x1,%%x2) @@>)
+
+            | GenericEqualityQ (_, _,[x1;x2]) 
+            | EqualsQ (_, _,[x1;x2]) ->     transComparison x1 x2 Expression.Equal Expression.Equal genericEqualityIntrinsic
+
+            | GreaterQ (_, _,[x1;x2]) ->    transComparison x1 x2 Expression.GreaterThan Expression.GreaterThan genericGreaterThanIntrinsic
+
+            | GreaterEqQ (_, _,[x1;x2]) ->  transComparison x1 x2 Expression.GreaterThanOrEqual Expression.GreaterThanOrEqual genericGreaterOrEqualIntrinsic
+
+            | LessQ (_, _,[x1;x2]) ->       transComparison x1 x2 Expression.LessThan Expression.LessThan genericLessThanIntrinsic
+
+            | LessEqQ (_, _,[x1;x2]) ->     transComparison x1 x2 Expression.LessThanOrEqual Expression.LessThanOrEqual genericLessOrEqualIntrinsic
+
+            | NotEqQ (_, _,[x1;x2]) ->      transComparison x1 x2 Expression.NotEqual Expression.NotEqual genericNotEqualIntrinsic
+
+            | NotQ (_, _,[x1])    -> Expression.Not(ConvExpr env x1)                                   |> asExpr
+
+
+            | NegQ (_, _,[x1])    -> Expression.Negate(ConvExpr env x1)                                |> asExpr
+            | PlusQ (_, _,[x1;x2]) -> Expression.Add(ConvExpr env x1, ConvExpr env x2)      |> asExpr
+            | DivideQ (_, _,[x1;x2]) -> Expression.Divide (ConvExpr env x1, ConvExpr env x2)  |> asExpr
+            | MinusQ (_, _,[x1;x2]) -> Expression.Subtract(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | MultiplyQ (_, _,[x1;x2]) -> Expression.Multiply(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | ModuloQ (_, _,[x1;x2]) -> Expression.Modulo (ConvExpr env x1, ConvExpr env x2) |> asExpr
+                 /// REVIEW: basic arithmetic with method witnesses
+                 /// REVIEW: negate,add, divide, multiply, subtract with method witness
+
+            | ShiftLeftQ (_, _,[x1;x2]) -> Expression.LeftShift(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | ShiftRightQ (_, _,[x1;x2]) -> Expression.RightShift(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | BitwiseAndQ (_, _,[x1;x2]) -> Expression.And(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | BitwiseOrQ (_, _,[x1;x2]) -> Expression.Or(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | BitwiseXorQ (_, _,[x1;x2]) -> Expression.ExclusiveOr(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | BitwiseNotQ (_, _,[x1]) -> Expression.Not(ConvExpr env x1) |> asExpr
+                 /// REVIEW: bitwise operations with method witnesses
+
+            | CheckedNeg (_, _,[x1]) -> Expression.NegateChecked(ConvExpr env x1)                                |> asExpr
+            | CheckedPlusQ (_, _,[x1;x2]) -> Expression.AddChecked(ConvExpr env x1, ConvExpr env x2)      |> asExpr
+            | CheckedMinusQ (_, _,[x1;x2]) -> Expression.SubtractChecked(ConvExpr env x1, ConvExpr env x2) |> asExpr
+            | CheckedMultiplyQ (_, _,[x1;x2]) -> Expression.MultiplyChecked(ConvExpr env x1, ConvExpr env x2) |> asExpr
+
+            | ConvCharQ (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<char>) |> asExpr
+            | ConvDecimalQ (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<decimal>) |> asExpr
+            | ConvFloatQ (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<float>) |> asExpr
+            | ConvFloat32Q (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<float32>) |> asExpr
+            | ConvSByteQ (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<sbyte>) |> asExpr
+            | ConvInt16Q (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<int16>) |> asExpr
+            | ConvInt32Q (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<int32>) |> asExpr
+            | ConvIntQ (_, [ty],[x1])    -> Expression.Convert(ConvExpr env x1, typeof<int32>) |> asExpr
+            | ConvInt64Q (_, [ty],[x1])  -> Expression.Convert(ConvExpr env x1, typeof<int64>) |> asExpr
+            | ConvByteQ (_, [ty],[x1])   -> Expression.Convert(ConvExpr env x1, typeof<byte>) |> asExpr
+            | ConvUInt16Q (_, [ty],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<uint16>) |> asExpr
+            | ConvUInt32Q (_, [ty],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<uint32>) |> asExpr
+            | ConvUInt64Q (_, [ty],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<uint64>) |> asExpr
+             /// REVIEW: convert with method witness
+
+            | CheckedConvCharQ (_, [ty],[x1])  -> Expression.ConvertChecked(ConvExpr env x1, typeof<char>) |> asExpr
+            | CheckedConvSByteQ (_, [ty],[x1])  -> Expression.ConvertChecked(ConvExpr env x1, typeof<sbyte>) |> asExpr
+            | CheckedConvInt16Q (_, [ty],[x1])  -> Expression.ConvertChecked(ConvExpr env x1, typeof<int16>) |> asExpr
+            | CheckedConvInt32Q (_, [ty],[x1])  -> Expression.ConvertChecked(ConvExpr env x1, typeof<int32>) |> asExpr
+            | CheckedConvInt64Q (_, [ty],[x1])  -> Expression.ConvertChecked(ConvExpr env x1, typeof<int64>) |> asExpr
+            | CheckedConvByteQ (_, [ty],[x1])   -> Expression.ConvertChecked(ConvExpr env x1, typeof<byte>) |> asExpr
+            | CheckedConvUInt16Q (_, [ty],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<uint16>) |> asExpr
+            | CheckedConvUInt32Q (_, [ty],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<uint32>) |> asExpr
+            | CheckedConvUInt64Q (_, [ty],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<uint64>) |> asExpr
+            | ArrayLookupQ (_, [ArrayTypeQ(elemTy);_;_],[x1;x2]) -> 
+                Expression.ArrayIndex(ConvExpr env x1, ConvExpr env x2) |> asExpr
+
+            | ArrayAssignQ (_, [ArrayTypeQ(elemTy);_;_],[arr;idx;elem]) -> 
+                let minfo = ArrayAssignMethod.GetGenericMethodDefinition().MakeGenericMethod [| elemTy;typeof<unit> |]
+                Expression.Call(minfo,[| ConvExpr env arr; ConvExpr env idx; ConvExpr env elem |]) |> asExpr
+            
+            // Throw away markers inserted to satisfy C#'s design where they pass an argument
+            // or type T to an argument expecting Expr<T>.
+            | LinqExpressionHelperQ (_, [_],[x1]) -> ConvExpr env x1
+             
+              /// ArrayLength
+              /// ListBind
+              /// ListInit
+              /// ElementInit
+            | _ -> 
+                let argsP = ConvExprs env args 
+                Expression.Call(ConvObjArg env objOpt None, minfo, argsP) |> asExpr |> WrapVoid (IsVoidType minfo.ReturnType) objOpt args env 
+
+        // f x1 x2 x3 x4 --> InvokeFast4
+        | Patterns.Application(Patterns.Application(Patterns.Application(Patterns.Application(f,arg1),arg2),arg3),arg4) -> 
+            let domainTy1, rangeTy = getFunctionType f.Type
+            let domainTy2, rangeTy = getFunctionType rangeTy
+            let domainTy3, rangeTy = getFunctionType rangeTy
+            let domainTy4, rangeTy = getFunctionType rangeTy
+            let (-->) ty1 ty2 = Reflection.FSharpType.MakeFunctionType(ty1,ty2)
+            let ty = domainTy1 --> domainTy2 
+            let meth = (ty.GetMethods() |> Array.find (fun minfo -> minfo.Name = "InvokeFast" && minfo.GetParameters().Length = 5)).MakeGenericMethod [| domainTy3; domainTy4; rangeTy |]
+            let argsP = ConvExprs env [f; arg1;arg2;arg3; arg4]
+            Expression.Call((null:Expression), meth, argsP) |> asExpr
+
+        // f x1 x2 x3 --> InvokeFast3
+        | Patterns.Application(Patterns.Application(Patterns.Application(f,arg1),arg2),arg3) -> 
+            let domainTy1, rangeTy = getFunctionType f.Type
+            let domainTy2, rangeTy = getFunctionType rangeTy
+            let domainTy3, rangeTy = getFunctionType rangeTy
+            let (-->) ty1 ty2 = Reflection.FSharpType.MakeFunctionType(ty1,ty2)
+            let ty = domainTy1 --> domainTy2 
+            let meth = (ty.GetMethods() |> Array.find (fun minfo -> minfo.Name = "InvokeFast" && minfo.GetParameters().Length = 4)).MakeGenericMethod [| domainTy3; rangeTy |]
+            let argsP = ConvExprs env [f; arg1;arg2;arg3]
+            Expression.Call((null:Expression), meth, argsP) |> asExpr
+
+        // f x1 x2 --> InvokeFast2
+        | Patterns.Application(Patterns.Application(f,arg1),arg2) -> 
+            let domainTy1, rangeTy = getFunctionType f.Type
+            let domainTy2, rangeTy = getFunctionType rangeTy
+            let (-->) ty1 ty2 = Reflection.FSharpType.MakeFunctionType(ty1,ty2)
+            let ty = domainTy1 --> domainTy2 
+            let meth = (ty.GetMethods() |> Array.find (fun minfo -> minfo.Name = "InvokeFast" && minfo.GetParameters().Length = 3)).MakeGenericMethod [| rangeTy |]
+            let argsP = ConvExprs env [f; arg1;arg2]
+            Expression.Call((null:Expression), meth, argsP) |> asExpr
+
+        // f x1 --> Invoke
+        | Patterns.Application(f,arg) -> 
+            let fP = ConvExpr env f
+            let argP = ConvExpr env arg
+            let meth = f.Type.GetMethod("Invoke")
+            Expression.Call(fP, meth, [| argP |]) |> asExpr
+
+        // Expr.New*
+        | Patterns.NewRecord(recdTy,args) -> 
+            let ctorInfo = Reflection.FSharpValue.PreComputeRecordConstructorInfo(recdTy,showAll) 
+            Expression.New(ctorInfo,ConvExprs env args) |> asExpr
+
+        | Patterns.NewArray(ty,args) -> 
+            Expression.NewArrayInit(ty,ConvExprs env args) |> asExpr
+
+        | Patterns.DefaultValue(ty) -> 
+            Expression.New(ty) |> asExpr
+
+        | Patterns.NewUnionCase(unionCaseInfo,args) -> 
+            let methInfo = Reflection.FSharpValue.PreComputeUnionConstructorInfo(unionCaseInfo,showAll)
+            let argsR = ConvExprs env args 
+            Expression.Call((null:Expression),methInfo,argsR) |> asExpr
+
+        | Patterns.UnionCaseTest(e,unionCaseInfo) -> 
+            let methInfo = Reflection.FSharpValue.PreComputeUnionTagMemberInfo(unionCaseInfo.DeclaringType,showAll)
+            let obj = ConvExpr env e 
+            let tagE = 
+                match methInfo with 
+                | :? PropertyInfo as p -> 
+                    Expression.Property(obj,p) |> asExpr
+                | :? MethodInfo as m -> 
+                    Expression.Call((null:Expression),m,[| obj |]) |> asExpr
+                | _ -> failwith "unreachable case"
+            Expression.Equal(tagE, Expression.Constant(unionCaseInfo.Tag)) |> asExpr
+
+        | Patterns.NewObject(ctorInfo,args) -> 
+            Expression.New(ctorInfo,ConvExprs env args) |> asExpr
+
+        | Patterns.NewDelegate(dty,vs,b) -> 
+            let vsP = List.map ConvVar vs 
+            let env = {env with varEnv = List.foldBack2 (fun (v:Var) vP -> Map.add v (vP |> asExpr)) vs vsP env.varEnv }
+            let bodyP = ConvExpr env b 
+            Expression.Lambda(dty, bodyP, vsP) |> asExpr 
+
+        | Patterns.NewTuple(args) -> 
+             let tupTy = args |> List.map (fun arg -> arg.Type) |> Array.ofList |> Reflection.FSharpType.MakeTupleType
+             let argsP = ConvExprs env args 
+             let rec build ty (argsP: Expression[]) = 
+                 match Reflection.FSharpValue.PreComputeTupleConstructorInfo(ty) with 
+                 | ctorInfo,None -> Expression.New(ctorInfo,argsP) |> asExpr 
+                 | ctorInfo,Some(nestedTy) -> 
+                     let n = ctorInfo.GetParameters().Length - 1
+                     Expression.New(ctorInfo, Array.append argsP.[0..n-1] [| build nestedTy argsP.[n..] |]) |> asExpr
+             build tupTy argsP
+
+        | Patterns.IfThenElse(g,t,e) -> 
+            Expression.Condition(ConvExpr env g, ConvExpr env t,ConvExpr env e) |> asExpr
+
+        | Patterns.Sequential (e1,e2) -> 
+            let e1P = ConvExpr env e1
+            let e2P = ConvExpr env e2
+            let minfo = match <@@ SequentialHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+            let minfo = minfo.GetGenericMethodDefinition().MakeGenericMethod [| e1.Type; e2.Type |]
+            Expression.Call(minfo,[| e1P; e2P |]) |> asExpr
+
+        | Patterns.Let (v,e,b) -> 
+            let vP = ConvVar v
+            let envinner = { env with varEnv = Map.add v (vP |> asExpr) env.varEnv } 
+            let bodyP = ConvExpr envinner b 
+            let eP = ConvExpr env e
+            let ty = GetFuncType [| v.Type; b.Type |] 
+            let lam = Expression.Lambda(ty,bodyP,[| vP |]) |> asExpr
+            Expression.Call(lam,ty.GetMethod("Invoke",instanceBindingFlags),[| eP |]) |> asExpr
+
+        | Patterns.Lambda(v,body) -> 
+            let vP = ConvVar v
+            let env = { env with varEnv = Map.add v (vP |> asExpr) env.varEnv }
+            let tyargs = [| v.Type; body.Type |]
+            let bodyP = ConvExpr env body
+            let convType = typedefof<System.Converter<obj,obj>>.MakeGenericType tyargs
+            let convDelegate = Expression.Lambda(convType, bodyP, [| vP |]) |> asExpr
+            Expression.Call(typeof<FuncConvert>,"ToFSharpFunc",tyargs,[| convDelegate |]) |> asExpr
+    
+        | Patterns.WhileLoop(gd,b) -> 
+            let gdP = ConvExpr env <@@ (fun () -> (%%gd:bool)) @@>
+            let bP = ConvExpr env <@@ (fun () -> (%%b:unit)) @@>
+            let minfo = WhileMethod.GetGenericMethodDefinition().MakeGenericMethod [| typeof<unit> |]
+            Expression.Call(minfo,[| gdP; bP |]) |> asExpr
+        
+        | Patterns.TryFinally(e,h) -> 
+            let eP = ConvExpr env (Expr.Lambda(new Var("unitVar",typeof<unit>), e))
+            let hP = ConvExpr env <@@ (fun () -> (%%h:unit)) @@>
+            let minfo = TryFinallyMethod.GetGenericMethodDefinition().MakeGenericMethod [| e.Type |]
+            Expression.Call(minfo,[| eP; hP |]) |> asExpr
+        
+        | Patterns.TryWith(e,vf,filter,vh,handler) -> 
+            let eP = ConvExpr env (Expr.Lambda(new Var("unitVar",typeof<unit>), e))
+            let filterP = ConvExpr env (Expr.Lambda(vf,filter))
+            let handlerP = ConvExpr env (Expr.Lambda(vh,handler))
+            let minfo = TryWithMethod.GetGenericMethodDefinition().MakeGenericMethod [| e.Type |]
+            Expression.Call(minfo,[| eP; filterP; handlerP |]) |> asExpr
+
+        | Patterns.LetRecursive(binds,body) -> 
+
+            let vfs = List.map fst binds
+            
+            let pass1 = 
+                binds |> List.map (fun (vf,expr) -> 
+                    match expr with 
+                    | Lambda(vx,expr) -> 
+                        let domainTy,rangeTy = getFunctionType vf.Type
+                        let vfdTy = GetFuncType [| domainTy; rangeTy |]
+                        let vfd = new Var("d",vfdTy)
+                        (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd)
+                    | _ -> failwith "cannot convert recursive bindings that do not define functions")
+
+            let trans = pass1 |> List.map (fun (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd) -> (vf,vfd)) |> Map.ofList
+
+            // Rewrite uses of the recursively defined functions to be invocations of the delegates
+            // We do this because the delegate are allocated "once" and we can normally just invoke them efficiently
+            let rec rw t = 
+                match t with 
+                | Application(Var(vf),t) when trans.ContainsKey(vf) -> 
+                     let vfd = trans.[vf]
+                     Expr.Call(Expr.Var(vfd),vfd.Type.GetMethod("Invoke",instanceBindingFlags),[t])
+                | ExprShape.ShapeVar(vf) when trans.ContainsKey(vf)-> 
+                     let vfd = trans.[vf]
+                     let nv = new Var("nv",fst(getFunctionType vf.Type)) 
+                     Expr.Lambda(nv,Expr.Call(Expr.Var(vfd),vfd.Type.GetMethod("Invoke",instanceBindingFlags),[Expr.Var(nv)]))
+                | ExprShape.ShapeVar(_) -> t
+                | ExprShape.ShapeCombination(obj,args) -> ExprShape.RebuildShapeCombination(obj,List.map rw args)
+                | ExprShape.ShapeLambda(v,arg) -> Expr.Lambda(v,rw arg)
+
+            let vfdTys    = pass1 |> List.map (fun (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd) -> vfdTy) |> Array.ofList
+            let vfds      = pass1 |> List.map (fun (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd) -> vfd)
+
+            let FPs = 
+                [| for (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd) in pass1 do
+                      let expr = rw expr
+                      let tyF = GetFuncType (Array.append vfdTys [| vx.Type; expr.Type |])
+                      let F = Expr.NewDelegate(tyF,vfds@[vx],expr)
+                      let FP = ConvExpr env F
+                      yield FP |]
+
+            let body = rw body
+
+            let methTys   = 
+                [| for (vf,vx,expr,domainTy,rangeTy,vfdTy,vfd) in pass1 do
+                      yield domainTy
+                      yield rangeTy
+                   yield body.Type |]
+
+            let B = Expr.NewDelegate(GetFuncType (Array.append vfdTys [| body.Type |]),vfds,body)
+            let BP = ConvExpr env B
+
+            let minfo = 
+                let q = 
+                    match vfds.Length with 
+                    | 1 -> <@@ LetRec1Helper @@>
+                    | 2 -> <@@ LetRec2Helper @@>
+                    | 3 -> <@@ LetRec3Helper @@>
+                    | 4 -> <@@ LetRec4Helper @@>
+                    | 5 -> <@@ LetRec5Helper @@>
+                    | 6 -> <@@ LetRec6Helper @@>
+                    | 7 -> <@@ LetRec7Helper @@>
+                    | 8 -> <@@ LetRec8Helper @@>
+                    | _ -> raise <| new NotSupportedException("In this release of the F# Power Pack, mutually recursive function groups involving 9 or more functions may not be converted to LINQ expressions")
+                match q with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+
+            let minfo = minfo.GetGenericMethodDefinition().MakeGenericMethod methTys
+            Expression.Call(minfo,Array.append FPs [| BP |]) |> asExpr
+
+        | Patterns.AddressOf _ -> raise <| new NotSupportedException("Address-of expressions may not be converted to LINQ expressions")
+        | Patterns.AddressSet _ -> raise <| new NotSupportedException("Address-set expressions may not be converted to LINQ expressions")
+        | Patterns.FieldSet _ -> raise <| new NotSupportedException("Field-set expressions may not be converted to LINQ expressions")
+
+        | _ -> 
+            raise <| new NotSupportedException(sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)
+
+    and ConvObjArg env objOpt coerceTo : Expression = 
+        match objOpt with
+        | Some(obj) -> 
+            let expr = ConvExpr env obj
+            match coerceTo with 
+            | None -> expr
+            | Some ty -> Expression.TypeAs(expr, ty) :> Expression
+        | None -> 
+            null
+
+    and ConvExprs env es : Expression[] = 
+        es |> List.map (ConvExpr env) |> Array.ofList 
+
+    and ConvVar (v: Var) = 
+        //printf "** Expression .Parameter(%a, %a)\n" output_any ty output_any nm;
+        Expression.Parameter(v.Type, v.Name)
+
+    let Conv (e: #Expr,eraseEquality) = ConvExpr { eraseEquality = eraseEquality; varEnv = Map.empty } (e :> Expr)
+
+    let CompileImpl (e: #Expr, eraseEquality) = 
+       let ty = e.Type
+       let e = Expr.NewDelegate(GetFuncType([|typeof<unit>; ty |]), [new Var("unit",typeof<unit>)],e)
+       let linqExpr = Conv (e,eraseEquality)
+       let linqExpr = (linqExpr :?> LambdaExpression)
+       let d = linqExpr.Compile()
+       (fun () -> 
+           try 
+             d.DynamicInvoke [| box () |]
+           with :? System.Reflection.TargetInvocationException as exn -> 
+               raise exn.InnerException)
+
+    let Compile (e: #Expr) = CompileImpl(e,false)
+
+    let Eval e = Compile e ()
+
+
+    type Microsoft.FSharp.Quotations.Expr with 
+        member x.ToLinqExpression() = Conv(x, false)
+        member x.CompileUntyped() = Compile(x)
+        member x.EvalUntyped() = Eval(x)
+
+    type Microsoft.FSharp.Quotations.Expr<'T> with 
+        member x.Compile() = 
+            let f = Compile(x)  
+            (fun () -> (f()) :?> 'T)
+        member x.Eval() = (Eval(x) :?> 'T)
+
+  
+open QuotationEvaluation
+  
+[<Sealed>]
+type QuotationEvaluator() = 
+
+    static member ToLinqExpression (e: Microsoft.FSharp.Quotations.Expr) = e.ToLinqExpression()
+
+   
+    static member CompileUntyped (e : Microsoft.FSharp.Quotations.Expr) = e.CompileUntyped()
+
+    static member EvaluateUntyped (e : Microsoft.FSharp.Quotations.Expr) = e.EvalUntyped()
+
+    static member internal EvaluateUntypedUsingQueryApproximations (e: Microsoft.FSharp.Quotations.Expr) = CompileImpl(e, true) ()
+
+    static member Compile (e : Microsoft.FSharp.Quotations.Expr<'T>) = e.Compile()
+
+    static member Evaluate (e : Microsoft.FSharp.Quotations.Expr<'T>) = e.Eval()
+
+    
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Linq/Linq.fsi b/workyard/linq/FSharp.PowerPack.Linq/Linq.fsi
new file mode 100644
index 0000000..4526966
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/Linq.fsi
@@ -0,0 +1,171 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Linq
+
+    open System
+    open System.Linq.Expressions
+
+    module ExtraHashCompare =
+        /// An intrinsic for compiling <c><@ x <> y @></c> to expression trees
+        val GenericNotEqualIntrinsic : 'T -> 'T -> bool
+
+    [<Sealed>]
+    type QuotationEvaluator = 
+
+        /// Convert the quotation expression to LINQ expression trees
+        ///
+        /// This operation will only succeed for a subset of quotation expressions.
+        ///
+        /// Exceptions: InvalidArgumentException will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        static member ToLinqExpression : Microsoft.FSharp.Quotations.Expr -> System.Linq.Expressions.Expression
+
+        /// Compile the quotation expression by first converting to LINQ expression trees
+        ///
+        /// Exceptions: InvalidArgumentException will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        static member CompileUntyped : Microsoft.FSharp.Quotations.Expr -> (unit -> obj)
+
+        /// Compile the quotation expression by first converting to LINQ expression trees
+        ///
+        /// Exceptions: InvalidArgumentException will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        static member EvaluateUntyped : Microsoft.FSharp.Quotations.Expr -> obj
+
+        static member internal EvaluateUntypedUsingQueryApproximations : Microsoft.FSharp.Quotations.Expr -> obj
+    
+        /// Compile the quotation expression by first converting to LINQ expression trees
+        ///
+        /// Exceptions: InvalidArgumentException will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        static member Compile : Microsoft.FSharp.Quotations.Expr<'T> -> (unit -> 'T)
+
+        /// Evaluate the quotation expression by first converting to LINQ expression trees
+        ///
+        /// Exceptions: InvalidArgumentException will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        static member Evaluate : Microsoft.FSharp.Quotations.Expr<'T> -> 'T
+        
+    /// This module provides Compile and Eval extension members
+    /// for F# quotation values, implemented by translating to LINQ
+    /// expression trees and using the LINQ dynamic compiler.
+    module QuotationEvaluation =
+
+        type Microsoft.FSharp.Quotations.Expr with 
+              /// Convert the quotation expression to LINQ expression trees
+              ///
+              /// This operation will only succeed for a subset of quotation expressions.
+              ///
+              /// Exceptions: InvalidArgumentException will be raised if the input expression is
+              /// not in the subset that can be converted to a LINQ expression tree
+              member ToLinqExpression : unit -> System.Linq.Expressions.Expression
+
+              /// Compile the quotation expression by first converting to LINQ expression trees
+              ///
+              /// Exceptions: InvalidArgumentException will be raised if the input expression is
+              /// not in the subset that can be converted to a LINQ expression tree
+              member CompileUntyped : unit -> (unit -> obj)
+
+              /// Compile the quotation expression by first converting to LINQ expression trees
+              ///
+              /// Exceptions: InvalidArgumentException will be raised if the input expression is
+              /// not in the subset that can be converted to a LINQ expression tree
+              member EvalUntyped : unit -> obj
+
+        type Microsoft.FSharp.Quotations.Expr<'T> with 
+              /// Compile the quotation expression by first converting to LINQ expression trees
+              ///
+              /// Exceptions: InvalidArgumentException will be raised if the input expression is
+              /// not in the subset that can be converted to a LINQ expression tree
+              member Compile : unit -> (unit -> 'T)
+
+              /// Evaluate the quotation expression by first converting to LINQ expression trees
+              ///
+              /// Exceptions: InvalidArgumentException will be raised if the input expression is
+              /// not in the subset that can be converted to a LINQ expression tree
+              member Eval : unit -> 'T
+
+        /// This function should not be called directly. 
+        //
+        // NOTE: when an F# expression tree is converted to a Linq expression tree using ToLinqExpression 
+        // the transformation of <c>LinqExpressionHelper(e)</c> is simple the same as the transformation of
+        // 'e'. This allows LinqExpressionHelper to be used as a marker to satisfy the C# design where 
+        // certain expression trees are constructed using methods with a signature that expects an
+        // expression tree of type <c>Expression<T></c> but are passed an expression tree of type T.
+        val LinqExpressionHelper : 'T -> Expression<'T>
+
+        /// This type should not be called directly. 
+        type internal MemberInitializationHelperType =
+            | MemberInitialization of Quotations.Expr * Quotations.Expr list
+
+        /// This function should not be called directly. 
+        val internal MemberInitializationHelper : MemberInitializationHelperType ->  'R
+
+        /// A set of types used for implementing quotation conversions.
+        /// These are public only because targets of Linq Lambda expressions require them to be so
+        module HelperTypes = 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 -> unit
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type ActionHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 * 'T20 -> unit
+
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> 'T6
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> 'T7 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> 'T8 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> 'T9 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> 'T10 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> 'T11 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> 'T12 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> 'T13 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> 'T14 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> 'T15 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> 'T16 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> 'T17 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 -> 'T18 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 -> 'T19 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 -> 'T20 
+            [<System.Obsolete("This type is for use by the quotation to LINQ expression tree converter and is not for direct use from user code")>]
+            type FuncHelper<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10, 'T11, 'T12, 'T13, 'T14, 'T15, 'T16, 'T17, 'T18, 'T19, 'T20, 'T21> = delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 * 'T17 * 'T18 * 'T19 * 'T20 -> 'T21 
diff --git a/workyard/linq/FSharp.PowerPack.Linq/LinqQueries.fs b/workyard/linq/FSharp.PowerPack.Linq/LinqQueries.fs
new file mode 100644
index 0000000..310879d
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/LinqQueries.fs
@@ -0,0 +1,831 @@
+// Copyright (c) Microsoft Corporation 2005-2008.
+// This sample code is provided "as is" without warranty of any kind. 
+// We disclaim all warranties, either express or implied, including the 
+// warranties of merchantability and fitness for a particular purpose. 
+//
+
+namespace Microsoft.FSharp.Linq
+
+open System
+open System.Linq
+open System.Collections.Generic
+open System.Linq.Expressions
+open System.Reflection
+open System.Reflection.Emit
+open Microsoft.FSharp
+open Microsoft.FSharp.Linq.QuotationEvaluation
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Quotations.Patterns
+open Microsoft.FSharp.Quotations.DerivedPatterns
+
+#nowarn "57"
+#nowarn "44" //deprecation 
+      
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Query =
+
+    let debug = false
+        
+    let contains key source = 
+        System.Linq.Enumerable.Contains(source,key)
+
+    let minBy<'T1,'T2> keySelector source = 
+        System.Linq.Enumerable.Min(source,Func<'T1,'T2>(keySelector))
+
+    let maxBy<'T1,'T2> keySelector source = 
+        System.Linq.Enumerable.Max(source,Func<'T1,'T2>(keySelector))
+
+    let groupBy keySelector source = 
+        System.Linq.Enumerable.GroupBy(source,Func<_,_>(keySelector))
+
+    let join  outerSource innerSource outerKeySelector innerKeySelector resultSelector = 
+        System.Linq.Enumerable.Join(outerSource,innerSource,Func<_,_>(outerKeySelector),Func<_,_>(innerKeySelector),Func<_,_,_>(resultSelector))
+
+    let groupJoin  outerSource innerSource outerKeySelector innerKeySelector resultSelector = 
+        System.Linq.Enumerable.GroupJoin(outerSource,innerSource,Func<_,_>(outerKeySelector),Func<_,_>(innerKeySelector),Func<_,_,_>(resultSelector))
+
+    let ConvVar (v: Var) = 
+        Expression.Parameter(v.Type, v.Name)
+
+    let asExpr x = (x :> Expression)
+            
+    let (|Getter|_|) (prop: #PropertyInfo) =
+        match prop.GetGetMethod(true) with 
+        | null -> None
+        | v -> Some v
+
+    let (|CallPipe|_|) = (|SpecificCall|_|) <@ (|>) @>
+    // Match 'f x' or 'x |> f' or 'x |> (fun x -> f (x :> ty))'
+    let (|SpecificPipedCall0|_|) q = 
+       let (|CallQ|_|) = (|SpecificCall|_|) q
+       function
+       | CallPipe (None, [_;_],[arg1;Lambda(arg1v,CallQ (None, tyargs,[arg1E])) ]) -> 
+           let arg1 = arg1E.Substitute (Map.ofSeq [ (arg1v,arg1) ]).TryFind 
+           Some(tyargs,arg1)
+
+       | CallQ (None, tyargs,[arg1]) -> 
+           Some(tyargs,arg1)
+
+       | _ -> None           
+
+    // Match 
+    //     'f x y' or 
+    //     'y |> f x' or
+    //     'y |> (fun y -> f (x :> ty) (y :> ty))'
+    //     'y |> let x = e in (fun y -> f (x :> ty) (y :> ty))'
+    let (|SpecificPipedCall1|_|) q = 
+       let (|CallQ|_|) = (|SpecificCall|_|) q
+       function
+       // Encoded form of some uses of 'T1rg2 |> f arg1'
+       | CallPipe (None, [_;_],[arg2;Let(arg1v,arg1,Lambda(arg2v,CallQ (None, tyargs,[arg1E;arg2E]))) ]) -> 
+              let arg1 = arg1E.Substitute (Map.ofSeq [ (arg1v,arg1) ]).TryFind 
+              let arg2 = arg2E.Substitute (Map.ofSeq [ (arg2v,arg2) ]).TryFind 
+              Some(tyargs,arg1,arg2)
+
+       | CallPipe (None, [_;_],[arg2;Lambda(arg2v,CallQ (None, tyargs,[arg1;arg2E])) ]) -> 
+              let arg2 = arg2E.Substitute (Map.ofSeq [ (arg2v,arg2) ]).TryFind 
+              Some(tyargs,arg1,arg2)
+
+       | CallQ (None, tyargs,[arg1;arg2]) -> 
+              Some(tyargs,arg1,arg2)
+       | _ -> None           
+
+        
+    let GetGenericMethodDefinition (m:MethodInfo) = 
+        if m.IsGenericMethod then m.GetGenericMethodDefinition() else m
+
+    let FindGenericStaticMethodInfo mexpr =
+        match mexpr with 
+        | Lambdas(_,Call(None,methInfo,_)) -> GetGenericMethodDefinition methInfo
+        | _ -> failwithf "FindGenericStaticMethodInfo: %A is not a static method call lambda" mexpr
+
+    let CallGenericStaticMethod mexpr  =
+        let m = FindGenericStaticMethodInfo mexpr in
+        //printf "m = %A\n" m;
+        fun (tyargs,args) -> 
+            //printf "invoking %A\n" m;
+            
+            let m = 
+                if m.IsGenericMethod then 
+                    m.MakeGenericMethod(Array.ofList tyargs) 
+                else
+                    m
+            m.Invoke(null,Array.ofList args)
+
+    let FT1 = typedefof<System.Func<_,_>>
+    let FT2 = typedefof<System.Func<_,_,_>>
+    let boolTy = typeof<bool>
+    let MakeQueryFuncTy (dty,rty) = FT1.MakeGenericType([| dty; rty |])
+    let MakeQueryFunc2Ty (dty1,dty2,rty) = FT2.MakeGenericType([| dty1; dty2; rty |])
+
+    let IEnumerableTypeDef = typedefof<IEnumerable<_>>
+    let IQueryableTypeDef = typedefof<IQueryable<_>>
+    let MakeIEnumerableTy dty= IEnumerableTypeDef.MakeGenericType([| dty|])
+    let MakeIQueryableTy dty= IQueryableTypeDef.MakeGenericType([| dty|])
+
+    let isNamedType(typ:Type) = not (typ.IsArray || typ.IsByRef || typ.IsPointer)
+    let equivHeadTypes (ty1:Type) (ty2:Type) = 
+        isNamedType(ty1) &&
+        if ty1.IsGenericType then 
+          ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition())
+        else 
+          ty1.Equals(ty2)
+
+    let IsIQueryableTy ty = equivHeadTypes IQueryableTypeDef ty
+   
+
+    let CallSeqToList = 
+        let F = CallGenericStaticMethod <@ Seq.toList @> 
+        fun (srcTy,src) -> 
+            F ([srcTy],[src])
+
+    let CallSeqToArray = 
+        let F = CallGenericStaticMethod <@ Seq.toArray @> 
+        fun (srcTy,src) -> 
+            F ([srcTy],[src])
+
+    let CallQueryableContains = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Contains : _ * _ -> _ @> 
+        fun (srcTy,src,key:Expression) -> 
+            F ([srcTy],[src;box key])
+
+    let CallQueryableMinBy = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Min : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,destTy,src,predicate:Expression) -> 
+            F ([srcTy;destTy],[src;box predicate])
+
+    let CallQueryableMin = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Min : _ -> _ @> 
+        fun (srcTy,src) -> 
+            F ([srcTy],[src])
+
+    let CallQueryableMaxBy = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Max : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,destTy,src,predicate:Expression) -> 
+            F ([srcTy;destTy],[src;box predicate])
+
+    let CallQueryableMax = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Max : _ -> _ @> 
+        fun (srcTy,src) -> 
+            F ([srcTy],[src])
+
+    let CallQueryableAverageBy = 
+        let F_float = CallGenericStaticMethod <@ System.Linq.Queryable.Average : _ * Expression<Func<_,float>> -> _ @> 
+        let F_float32 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : _ * Expression<Func<_,float32>> -> _ @> 
+        let F_decimal = CallGenericStaticMethod <@ System.Linq.Queryable.Average : _ * Expression<Func<_,decimal>> -> _ @> 
+        // Note these don't satisfy the F# constraints anyway
+        let F_int32 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : _ * Expression<Func<_,int32>> -> _ @> 
+        let F_int64 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : _ * Expression<Func<_,int64>> -> _ @> 
+        fun (srcTy,destTy,src,predicate:Expression) -> 
+            match srcTy with 
+            | ty when ty = typeof<float> -> F_float ([destTy],[src;box predicate])
+            | ty when ty = typeof<float32> -> F_float32 ([destTy],[src;box predicate])
+            | ty when ty = typeof<decimal> -> F_decimal ([destTy],[src;box predicate])
+            | ty when ty = typeof<int32> -> F_int32 ([destTy],[src;box predicate])
+            | ty when ty = typeof<int64> -> F_int64 ([destTy],[src;box predicate])
+            | _ -> failwith "unrecognized use of 'Seq.averageBy'"
+
+
+    let CallQueryableAverage = 
+        let F_float = CallGenericStaticMethod <@ System.Linq.Queryable.Average : IQueryable<float> -> _ @> 
+        let F_float32 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : IQueryable<float32>  -> _ @> 
+        let F_decimal = CallGenericStaticMethod <@ System.Linq.Queryable.Average : IQueryable<decimal>  -> _ @> 
+        // Note these don't satisfy the F# constraints anyway
+        let F_int32 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : IQueryable<int32>  -> _ @> 
+        let F_int64 = CallGenericStaticMethod <@ System.Linq.Queryable.Average : IQueryable<int64>  -> _ @> 
+        fun (srcTy,src) -> 
+            match srcTy with 
+            | ty when ty = typeof<float> -> F_float ([],[src])
+            | ty when ty = typeof<float32> -> F_float32 ([],[src])
+            | ty when ty = typeof<decimal> -> F_decimal ([],[src])
+            | ty when ty = typeof<int32> -> F_int32 ([],[src])
+            | ty when ty = typeof<int64> -> F_int64 ([],[src])
+            | _ -> failwith "unrecognized use of 'Seq.average'"
+
+    let CallQueryableSumBy = 
+        let F_float = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : _ * Expression<Func<_,float>> -> _ @> 
+        let F_float32 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : _ * Expression<Func<_,float32>> -> _ @> 
+        let F_decimal = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : _ * Expression<Func<_,decimal>> -> _ @> 
+        let F_int32 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : _ * Expression<Func<_,int32>> -> _ @> 
+        let F_int64 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : _ * Expression<Func<_,int64>> -> _ @> 
+        fun (srcTy,destTy,src,predicate:Expression) -> 
+            match srcTy with 
+            | ty when ty = typeof<float> -> F_float ([destTy],[src;box predicate])
+            | ty when ty = typeof<float32> -> F_float32 ([destTy],[src;box predicate])
+            | ty when ty = typeof<decimal> -> F_decimal ([destTy],[src;box predicate])
+            | ty when ty = typeof<int32> -> F_int32 ([destTy],[src;box predicate])
+            | ty when ty = typeof<int64> -> F_int64 ([destTy],[src;box predicate])
+            | _ -> failwith "unrecognized use of 'Seq.sumBy'"
+
+    let CallQueryableSum = 
+        let F_float = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : IQueryable<float> -> _ @> 
+        let F_float32 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : IQueryable<float32>  -> _ @> 
+        let F_decimal = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : IQueryable<decimal>  -> _ @> 
+        // Note these don't satisfy the F# constraints anyway
+        let F_int32 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : IQueryable<int32>  -> _ @> 
+        let F_int64 = CallGenericStaticMethod <@ System.Linq.Queryable.Sum : IQueryable<int64>  -> _ @> 
+        fun (srcTy,src) -> 
+            match srcTy with 
+            | ty when ty = typeof<float> -> F_float ([],[src])
+            | ty when ty = typeof<float32> -> F_float32 ([],[src])
+            | ty when ty = typeof<decimal> -> F_decimal ([],[src])
+            | ty when ty = typeof<int32> -> F_int32 ([],[src])
+            | ty when ty = typeof<int64> -> F_int64 ([],[src])
+            | _ -> failwith "unrecognized use of 'Seq.sum"
+
+    let CallQueryableFirst = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.First : _ -> _ @> 
+        fun (srcTy,src) -> 
+            F ([srcTy],[src])
+
+    let CallQueryableFirstFind = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.First : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,src,predicate:Expression) -> 
+            F ([srcTy],[src;box predicate])
+
+    let CallQueryableCount = 
+        let F = CallGenericStaticMethod <@ System.Linq.Queryable.Count : _ -> _ @> 
+        fun (srcTy:Type,src:obj) -> 
+            F ([srcTy],[src])
+
+    let BindGenericMethod (methInfo:MethodInfo) tyargs = 
+        if methInfo.IsGenericMethod then 
+            methInfo.GetGenericMethodDefinition().MakeGenericMethod(Array.ofList tyargs)
+        else
+            methInfo
+
+    let minfo = match <@@ LinqExpressionHelper @@> with Lambda(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find method info"
+    let MakeFakeExpression (x:Expr) = 
+        Expr.Call(minfo.GetGenericMethodDefinition().MakeGenericMethod [| x.Type |], [ x ])
+
+            
+    let MakeGenericStaticMethod lam  =
+        // Nb. the SelectMany/Where/Select methods theoretically expects an expression, but the
+        // LINQ team decided to only pass it a delegate construction. The coercion from
+        // the delegate construction to the expression is effectively implicit in LINQ, but
+        // not in F# quotations, so we have to use 'Unchecked' version (see also FSBUGS #970)
+        let methInfo = FindGenericStaticMethodInfo lam 
+        (fun (tyargs,args) -> Expr.Call(BindGenericMethod methInfo tyargs,args))
+           
+
+    let MakeQueryableSelect = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.Select : _ * Expression<Func<_,_>> -> _) @>
+        fun (srcTy,targetTy,src,v,f)  -> 
+            
+            let selector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,targetTy), v,f)
+
+            let selector = MakeFakeExpression selector
+            F ([srcTy;targetTy],[src;selector])
+
+    let MakeQueryableAppend = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.Concat ) @>
+        fun (srcTy,src1,src2)  -> 
+            F ([srcTy],[src1;src2])
+
+    let MakeQueryableContains = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.Contains : _ * _ -> _ ) @>
+        fun (srcTy,src1,src2)  -> 
+            F ([srcTy],[src1;src2])
+
+    let MakeQueryableAsQueryable = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.AsQueryable : seq<_>  -> IQueryable<_>) @>
+        fun (ty,src)  -> 
+            F ([ty],[src])
+
+    let MakeEnumerableEmpty = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Enumerable.Empty : unit -> seq<_>) @>
+        fun (ty)  -> 
+            F ([ty],[])
+
+    let MakeQueryableEmpty = 
+        fun (ty)  -> 
+            MakeQueryableAsQueryable (ty,MakeEnumerableEmpty ty)
+
+    let MakeQueryableSelectMany = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.SelectMany : IQueryable<_> * Expression<Func<_,_>> -> IQueryable<_>) @>
+        fun (srcTy,targetTy,src,v,f)  -> 
+            let selector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,MakeIEnumerableTy targetTy), [v],f)
+
+            let selector = MakeFakeExpression selector
+            F ([srcTy;targetTy],[src;selector])
+
+    let MakeQueryableWhere = 
+        let F = MakeGenericStaticMethod <@ (System.Linq.Queryable.Where : _ * Expression<Func<_,_>> -> _) @>
+        fun (srcTy,src,v,f)  -> 
+            let selector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,typeof<bool>), [v],f)
+
+            let selector = MakeFakeExpression selector
+            F ([srcTy],[src;selector])
+
+
+
+    let MakeQueryableOrderBy = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.OrderBy : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,keyTy,src,v,keySelector)  -> 
+            
+            let selector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,keyTy), [v],keySelector)
+
+            let selector = MakeFakeExpression selector
+            F ([srcTy;keyTy],[src;selector])
+
+    let MakeQueryableDistinct = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Distinct : _ -> _ @> 
+        fun (srcTy,src)  -> 
+            let src = Expr.Coerce(src,MakeIQueryableTy srcTy)
+            F ([srcTy],[src])
+
+    let MakeQueryableTake = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Take @> 
+        fun (srcTy,src,count)  -> 
+            let src = Expr.Coerce(src,MakeIQueryableTy srcTy)
+            F ([srcTy],[src;count])
+
+    let MakeQueryableGroupBy = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.GroupBy : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,keyTy,src,v,keySelector)  -> 
+            let keySelector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,keyTy), [v],keySelector) 
+
+            let keySelector = MakeFakeExpression keySelector
+            F ([srcTy;keyTy],[src;keySelector])
+
+    let MakeQueryableMinBy = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Min : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,keyTy,src,v,keySelector)  -> 
+            let keySelector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,keyTy), [v],keySelector) 
+
+            let keySelector = MakeFakeExpression keySelector
+            F ([srcTy;keyTy],[src;keySelector])
+
+    let MakeQueryableMaxBy = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Max : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,keyTy,src,v,keySelector)  -> 
+            let keySelector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,keyTy), [v],keySelector) 
+
+            let keySelector = MakeFakeExpression keySelector
+            F ([srcTy;keyTy],[src;keySelector])
+
+    let MakeQueryableAny = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Any : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,src,v,keySelector)  -> 
+            let keySelector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,boolTy), [v],keySelector) 
+
+            let keySelector = MakeFakeExpression keySelector
+            F ([srcTy],[src;keySelector])
+
+    let MakeQueryableAll = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.All : _ * Expression<Func<_,_>> -> _ @> 
+        fun (srcTy,src,v,keySelector)  -> 
+            let keySelector = Expr.NewDelegate(MakeQueryFuncTy(srcTy,boolTy), [v],keySelector) 
+
+            let keySelector = MakeFakeExpression keySelector
+            F ([srcTy],[src;keySelector])
+
+    let MakeQueryableJoin = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Join : _ * _ * Expression<Func<_,_>> * Expression<Func<_,_>> * Expression<Func<_,_,_>> -> _ @> 
+        fun (outerSourceTy,innerSourceTy,keyTy,resultTy,outerSource,innerSource,outerKeyVar,outerKeySelector,innerKeyVar,innerKeySelector,outerResultKeyVar,innerResultKeyVar,resultSelector)  -> 
+            let outerKeySelector = Expr.NewDelegate(MakeQueryFuncTy(outerSourceTy,keyTy), [outerKeyVar],outerKeySelector) |> MakeFakeExpression 
+            let innerKeySelector = Expr.NewDelegate(MakeQueryFuncTy(innerSourceTy,keyTy), [innerKeyVar],innerKeySelector) |> MakeFakeExpression 
+            let resultSelector = Expr.NewDelegate(MakeQueryFunc2Ty(outerSourceTy,innerSourceTy,resultTy), [outerResultKeyVar;innerResultKeyVar],resultSelector) |> MakeFakeExpression 
+            F ([outerSourceTy;innerSourceTy;keyTy;resultTy],[outerSource;innerSource;outerKeySelector;innerKeySelector;resultSelector])
+
+
+    let MakeQueryableGroupJoin = 
+        let F = MakeGenericStaticMethod <@ System.Linq.Queryable.GroupJoin : _ * _ * Expression<Func<_,_>> * Expression<Func<_,_>> * Expression<Func<_,_,_>> -> _ @> 
+        fun (outerSourceTy,innerSourceTy,keyTy,resultTy,outerSource,innerSource,outerKeyVar,outerKeySelector,innerKeyVar,innerKeySelector,outerResultKeyVar,innerResultKeyVar,resultSelector)  -> 
+            let outerKeySelector = Expr.NewDelegate(MakeQueryFuncTy(outerSourceTy,keyTy), [outerKeyVar],outerKeySelector) |> MakeFakeExpression 
+            let innerKeySelector = Expr.NewDelegate(MakeQueryFuncTy(innerSourceTy,keyTy), [innerKeyVar],innerKeySelector) |> MakeFakeExpression 
+            let resultSelector = Expr.NewDelegate(MakeQueryFunc2Ty(outerSourceTy,MakeIEnumerableTy(innerSourceTy),resultTy), [outerResultKeyVar;innerResultKeyVar],resultSelector) |> MakeFakeExpression 
+            F ([outerSourceTy;innerSourceTy;keyTy;resultTy],[outerSource;innerSource;outerKeySelector;innerKeySelector;resultSelector])
+
+
+
+    let MakeLambda = 
+        let F = CallGenericStaticMethod <@ (fun (a:Expression,b:ParameterExpression[]) -> System.Linq.Expressions.Expression.Lambda<_>(a,b)) @> 
+        fun (srcTy,targetTy,arg:Expression,p:ParameterExpression) -> 
+            (F ([MakeQueryFuncTy(srcTy,targetTy)],[box arg;box [| p |] ]) :?> Expression)
+
+    /// Project F# function expressions to Linq LambdaExpression nodes
+    let FuncExprToLinqFunc2Expression (srcTy,targetTy,v,body) = 
+        Expr.NewDelegate(Linq.Expressions.Expression.GetFuncType [| srcTy; targetTy |], [v],body).ToLinqExpression()
+
+
+    let MakeMapConcat = 
+        let F = MakeGenericStaticMethod <@ Seq.collect @>
+        fun (srcTy,targetTy,f,src)  -> 
+            F ([srcTy;MakeIEnumerableTy targetTy;targetTy],[f;src])
+
+    let MakeFilter = 
+        let F = MakeGenericStaticMethod <@ Seq.filter @>
+        fun (srcTy,f,src)  -> 
+            F ([srcTy],[f;src])
+
+    
+    // The following patterns are used to recognize object construction 
+    // using the 'new O(Prop1 = <e>, Prop2 = <e>)' syntax
+
+    /// Recognize sequential series written as (... ((<e>; <e>); <e>); ...)
+    let (|LeftSequentialSeries|) e =
+      let rec leftSequentialSeries acc e =
+        match e with 
+        | Patterns.Sequential(e1, e2) -> leftSequentialSeries (e2::acc) e1
+        | _ -> e::acc
+      leftSequentialSeries [] e
+
+    /// Tests whether a list consists only of assignments of properties of the 
+    /// given variable, null values (ignored) and ends by returning the given variable
+    /// (pattern returns only property assignments)
+    let (|PropSetList|_|) varArg (list:Expr list) =
+      let rec propSetList acc x = 
+        match x with 
+        | ((Patterns.PropertySet(Some(Patterns.Var(var)), _, _, _)) as p) :: xs when var = varArg ->
+            propSetList (p::acc) xs
+        | (Patterns.Value (v, _))::xs when v = null ->
+            propSetList acc xs
+        | [Patterns.Var(var)] when var = varArg -> Some acc
+        | _ -> None
+      propSetList [] list
+
+    /// Recognize object construction written using 'new O(Prop1 = <e>, Prop2 = <e>, ...)'
+    let (|ObjectConstruction|_|) e = 
+      match e with
+      | Patterns.Let
+          ( var, (Patterns.NewObject(_, []) as init), 
+            LeftSequentialSeries propSets ) ->
+          match propSets with 
+          | PropSetList var propSets -> Some(var, init, propSets)
+          | _ -> None
+      | _ -> None
+
+
+    let (|MacroReduction|_|) (p : Expr) = 
+        match p with 
+        | Applications(Lambdas(vs,body),args) when vs.Length = args.Length && List.forall2 (fun vs arg -> List.length vs = List.length args) vs args -> 
+            let tab = Map.ofSeq (List.concat (List.map2 List.zip vs args))
+            let body = body.Substitute tab.TryFind 
+            Some body
+
+        // Macro
+        | PropertyGet(None,Getter(MethodWithReflectedDefinition(body)),[]) -> 
+            Some body
+
+        // Macro
+        | Call(None,MethodWithReflectedDefinition(Lambdas(vs,body)),args) -> 
+            let tab = Map.ofSeq (List.concat (List.map2 (fun (vs:Var list) arg -> match vs,arg with [v],arg -> [(v,arg)] | vs,NewTuple(args) -> List.zip vs args | _ -> List.zip vs [arg]) vs args))
+            let body = body.Substitute tab.TryFind 
+            Some body
+
+        // Macro
+        | Let(v,e,body) ->
+            let tab = Map.ofSeq [ (v,e) ]
+            let body = body.Substitute tab.TryFind 
+            Some body
+        | _ -> None
+
+    let rec MacroExpand (p : Expr) = 
+        match p with 
+        // Do not reduce object construction expression - wrap it into 'MemberInitializationHelper'
+        // so that it can be translated to Expression.MemberInit (which is understood by LINQ to SQL/Entities)
+        | ObjectConstruction(var, init, propSets) ->
+            let v1 = MacroExpand init
+            let v2 = List.map MacroExpand propSets
+            // Wrap object initialization into a value (which is 
+            let minfo = match <@@ MemberInitializationHelper @@> with Lambdas(_,Call(_,minfo,_)) -> minfo | _ -> failwith "couldn't find minfo"
+            let minfo = minfo.GetGenericMethodDefinition().MakeGenericMethod [| var.Type |]
+            Expr.Call(minfo, [ Expr.Value(MemberInitialization(v1, v2)) ])
+
+        // Macro reduction
+        | MacroReduction(reduced) -> 
+            MacroExpand reduced
+        | ExprShape.ShapeCombination(comb,args) ->
+            ExprShape.RebuildShapeCombination(comb, List.map MacroExpand args)
+        | ExprShape.ShapeLambda(v,body) ->
+            Expr.Lambda(v, MacroExpand body)
+        | ExprShape.ShapeVar _ -> p
+
+    let (|PipedCallMapConcat|_|) = (|SpecificPipedCall1|_|) <@ Seq.collect @>
+    let (|CallSingleton|_|) = (|SpecificCall|_|) <@ Seq.singleton @>
+    let (|CallEmpty|_|) = (|SpecificCall|_|) <@ Seq.empty @>
+    let (|PipedCallSort|_|) = (|SpecificPipedCall0|_|) <@ Seq.sort @>
+    let (|PipedCallSortBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.sortBy @>
+    let (|PipedCallSeqGroupBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.groupBy @>
+    let (|PipedCallSeqMinBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.minBy @>
+    let (|PipedCallSeqMaxBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.maxBy @>
+    let (|PipedCallQueryGroupBy|_|) = (|SpecificPipedCall1|_|) <@ groupBy @>
+    let (|PipedCallQueryMinBy|_|) = (|SpecificPipedCall1|_|) <@ minBy @>
+    let (|PipedCallQueryMaxBy|_|) = (|SpecificPipedCall1|_|) <@ maxBy @>
+    let (|PipedCallSeqMap|_|) = (|SpecificPipedCall1|_|) <@ Seq.map @>
+    let (|PipedCallSeqAppend|_|) = (|SpecificPipedCall1|_|) <@ Seq.append @>
+    let (|PipedCallSeqFilter|_|) = (|SpecificPipedCall1|_|) <@ Seq.filter @>
+    let (|PipedCallSeqExists|_|) = (|SpecificPipedCall1|_|) <@ Seq.exists @>
+    let (|PipedCallSeqForAll|_|) = (|SpecificPipedCall1|_|) <@ Seq.forall @>
+    let (|PipedCallSeqDelay|_|) = (|SpecificPipedCall0|_|) <@ Seq.delay @>
+    let (|PipedCallSeqDistinct|_|) = (|SpecificPipedCall0|_|) <@ Seq.distinct @>
+    let (|PipedCallSeqToList|_|) = (|SpecificPipedCall0|_|) <@ Seq.toList @>
+    let (|PipedCallSeqTake|_|) = (|SpecificPipedCall1|_|) <@ Seq.take @>
+    let (|PipedCallSeqTruncate|_|) = (|SpecificPipedCall1|_|) <@ Seq.truncate @>
+    let (|PipedCallSeqToArray|_|) = (|SpecificPipedCall0|_|) <@ Seq.toArray @>
+    let (|PipedCallSeqMin|_|) = (|SpecificPipedCall0|_|) <@ Seq.min @>
+    let (|PipedCallSeqMax|_|) = (|SpecificPipedCall0|_|) <@ Seq.max @>
+    let (|PipedCallQueryContains|_|) = (|SpecificPipedCall1|_|) <@ contains @>
+    let (|CallSeq|_|) = (|SpecificCall|_|) <@ seq @>
+    let (|CallQueryJoin|_|) = (|SpecificCall|_|) <@ join @>
+    let (|CallQueryGroupJoin|_|) = (|SpecificCall|_|) <@ groupJoin @>
+    let (|PipedCallAverageBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.averageBy : (float -> float) -> seq<float> -> float @> 
+    let (|PipedCallAverage|_|) = (|SpecificPipedCall0|_|) <@ Seq.average: seq<float> -> float @>
+    let (|PipedCallSumBy|_|) = (|SpecificPipedCall1|_|) <@ Seq.sumBy : (float -> float) -> seq<float> -> float @>
+    let (|PipedCallSum|_|) = (|SpecificPipedCall0|_|) <@ Seq.sum: seq<float> -> float @>
+    let (|PipedCallSeqLength|_|) = (|SpecificPipedCall0|_|) <@ Seq.length @>
+    let (|PipedCallSeqHead|_|) = (|SpecificPipedCall0|_|) <@ Seq.head @>
+    let (|PipedCallSeqFind|_|) = (|SpecificPipedCall1|_|) <@ Seq.find @>
+
+
+    let queryUntyped body : obj = 
+        let rec TransInner (tm:Expr) = 
+            // printfn "TransInner: %A" tm
+            match tm with 
+
+            // Look through coercions, e.g. to IEnumerable 
+            | Coerce (expr,ty) -> 
+                TransInner expr
+
+            // Seq.collect (fun x -> if P x then tgt else Seq.empty)  sq @> 
+            //    ~~> TRANS(Seq.collect (x -> tgt) (sq.Where(x -> P x))
+            | PipedCallMapConcat ([srcTy;_;targetTy],Lambda(selectorVar, selector),sq) ->
+                let rec TransMapConcatSelector t = 
+                    match t with 
+                    | CallSingleton(None, _,[res]) -> 
+
+                        MakeQueryableSelect(srcTy,targetTy, TransInner sq, [selectorVar],MacroExpand res)
+
+
+                    | IfThenElse(g,tgt,CallEmpty (None, [_],[])) ->
+
+                        let sq = MakeFilter(srcTy,Expr.Lambda(selectorVar,g),sq)
+                        let sq = TransInner (MakeMapConcat(srcTy,targetTy,Expr.Lambda(selectorVar,tgt),sq))
+                        sq
+
+                    | MacroReduction(reduced) -> 
+                        TransMapConcatSelector reduced
+
+                    | selectorBody ->
+                        let selectorBody = TransInner selectorBody
+                        // For some reason IQueryable.SelectMany expects an IEnumerable return
+                        let selectorBody = Expr.Coerce(TransInner selectorBody,MakeIEnumerableTy targetTy)
+                        MakeQueryableSelectMany(srcTy,targetTy, TransInner sq, selectorVar,selectorBody)
+
+                TransMapConcatSelector selector
+            
+            | PipedCallSeqMap ([srcTy;targetTy],Lambda(v,res),sq) ->
+        
+                MakeQueryableSelect(srcTy,targetTy, TransInner sq, [v],MacroExpand res)
+
+            | PipedCallSeqAppend ([srcTy],sq1,sq2) ->
+        
+                MakeQueryableAppend(srcTy, TransInner sq1, TransInner sq2)
+
+            // These occur in the F# quotation form of F# sequence expressions            
+            | PipedCallSeqFilter ([srcTy],Lambda(v,res),sq) ->
+
+                MakeQueryableWhere(srcTy, TransInner sq, v,MacroExpand res)
+
+            // These occur in the F# quotation form of F# sequence expressions            
+            | PipedCallSeqDelay (_,Lambda(_,body)) ->
+        
+                TransInner body
+            
+            // These occur in the F# quotation form of F# sequence expressions            
+            | CallSeq (None, _,[body]) ->
+        
+                TransInner body
+
+                
+            | IfThenElse(g,t,e) ->
+
+                Expr.IfThenElse(g,TransInner t, TransInner e)
+
+
+            // These occur in the F# quotation form of F# sequence expressions            
+            | CallEmpty (None, [ty],[]) ->
+        
+                MakeQueryableEmpty ty
+
+
+            | PipedCallSortBy([ srcTy; keyTy ],Lambda(v,keySelector),source) ->
+
+                MakeQueryableOrderBy(srcTy,keyTy, TransInner source, v,MacroExpand keySelector)
+
+            | PipedCallSort([ srcTy ],source) ->
+
+                let v = new Var("x",srcTy)
+                MakeQueryableOrderBy(srcTy,srcTy, TransInner source, v,Expr.Var v)
+
+            | PipedCallSeqGroupBy _ ->
+
+                failwithf "The operator Seq.groupBy may not be used in queries. Use Microsoft.FSharp.Linq.Query.groupNy instead, which has a different return type to the standard F# operator" tm 
+
+            | PipedCallQueryGroupBy([ srcTy; keyTy ],Lambda(v,keySelector),source) ->
+
+                MakeQueryableGroupBy(srcTy,keyTy, TransInner source, v,MacroExpand keySelector)
+
+            | PipedCallSeqMinBy _ ->
+
+                failwithf "The operator Seq.minBy may not be used in queries. Use Microsoft.FSharp.Linq.Query.minBy instead, which has a different return type to the standard F# operator" tm 
+
+            | PipedCallQueryMinBy([ srcTy; keyTy ],Lambda(v,keySelector),source) ->
+
+                MakeQueryableMinBy(srcTy,keyTy, TransInner source, v,MacroExpand keySelector)
+
+            | PipedCallSeqMaxBy _ ->
+
+                failwithf "The operator Seq.maxBy may not be used in queries. Use Microsoft.FSharp.Linq.Query.maxBy instead, which has a different return type to the standard F# operator" tm 
+
+            | PipedCallQueryMaxBy([ srcTy; keyTy ],Lambda(v,keySelector),source) ->
+
+                MakeQueryableMaxBy(srcTy,keyTy, TransInner source, v,MacroExpand keySelector)
+
+            | PipedCallSeqExists([ srcTy],Lambda(v,keySelector),source) ->
+
+                MakeQueryableAny(srcTy,TransInner source, v,MacroExpand keySelector)
+
+            | PipedCallSeqForAll([ srcTy],Lambda(v,keySelector),source) ->
+
+                MakeQueryableAll(srcTy,TransInner source, v,MacroExpand keySelector)
+
+            | CallQueryJoin(None, [ outerSourceTy;innerSourceTy;keyTy;resultTy ],[outerSource;innerSource;Lambda(outerKeyVar,outerKeySelector);Lambda(innerKeyVar,innerKeySelector);Lambdas([[outerResultKeyVar];[innerResultKeyVar]],resultSelector)])->
+
+                MakeQueryableJoin(outerSourceTy,innerSourceTy,keyTy,resultTy,TransInner outerSource,TransInner innerSource,outerKeyVar,MacroExpand outerKeySelector,innerKeyVar,MacroExpand innerKeySelector,outerResultKeyVar,innerResultKeyVar,MacroExpand resultSelector)  
+
+            | CallQueryGroupJoin(None, [ outerSourceTy;innerSourceTy;keyTy;resultTy ],[outerSource;innerSource;Lambda(outerKeyVar,outerKeySelector);Lambda(innerKeyVar,innerKeySelector);Lambdas([[outerResultKeyVar];[innerResultKeyVar]],resultSelector)])->
+
+                MakeQueryableGroupJoin(outerSourceTy,innerSourceTy,keyTy,resultTy,TransInner outerSource,TransInner innerSource,outerKeyVar,MacroExpand outerKeySelector,innerKeyVar,MacroExpand innerKeySelector,outerResultKeyVar,innerResultKeyVar,MacroExpand resultSelector)  
+
+            | PipedCallSeqDistinct([ srcTy ],source) ->
+                MakeQueryableDistinct(srcTy, TransInner source)
+
+
+            | PipedCallSeqTake([ srcTy ],count,sq) 
+            | PipedCallSeqTruncate([ srcTy ],count,sq) ->
+                MakeQueryableTake(srcTy, TransInner sq, MacroExpand count)
+
+            | MacroReduction(reduced) -> 
+                TransInner reduced
+
+            // These occur in the F# quotation form of F# sequence expressions            
+            //
+            //       match i.Data with 
+            //       | 8 -> ...
+            //       | _ -> ()
+            | Sequential(Value( _, unitType), sq) when unitType  = typeof<unit> -> 
+        
+                TransInner sq
+
+            | expr when typeof<IQueryable>.IsAssignableFrom(expr.Type) ->
+                expr
+
+
+            // Error cases
+            | _  -> 
+                failwithf "The following construct was used in query but is not recognised by the F#-to-LINQ query translator:\n%A\nThis is not a valid query expression. Check the specification of permitted queries and consider moving some of the query out of the quotation" tm 
+
+        let EvalInner (tm:Expr) = TransInner tm |> QuotationEvaluator.EvaluateUntypedUsingQueryApproximations
+
+        let rec EvalOuterWithPostProcess (tm:Expr) = 
+            match tm with
+            
+            // Allow SQL <@ [ for x in ... ] @>
+            | PipedCallSeqToList ([srcTy],sq) ->
+        
+                CallSeqToList (srcTy,EvalInner sq)
+
+            | PipedCallSeqToArray ([srcTy],sq) ->
+        
+                CallSeqToArray (srcTy,EvalInner sq)
+
+
+            | PipedCallSeqMin ([srcTy],sq) ->
+
+                CallQueryableMin(srcTy,EvalInner sq)
+
+            | PipedCallSeqMax ([srcTy],sq) ->
+
+                CallQueryableMax(srcTy,EvalInner sq)
+
+            | PipedCallQueryContains ([srcTy],v,sq) ->
+
+                CallQueryableContains(srcTy,EvalInner sq,(MacroExpand v).ToLinqExpression())
+
+            | PipedCallAverageBy([srcTy;destTy],Lambda(v,res),sq) ->
+
+                CallQueryableAverageBy(srcTy, destTy, EvalInner sq, FuncExprToLinqFunc2Expression (srcTy,destTy,v,MacroExpand  res))
+
+            | PipedCallAverage ([srcTy],sq) ->
+
+                CallQueryableAverage(srcTy, EvalInner sq)
+
+            | PipedCallSumBy ([srcTy;destTy],Lambda(v,res),sq) ->
+
+                CallQueryableSumBy(srcTy, destTy, EvalInner sq, FuncExprToLinqFunc2Expression (srcTy,destTy,v,MacroExpand  res))
+
+            | PipedCallSum ([srcTy],sq) ->
+
+                CallQueryableSum(srcTy, EvalInner sq)
+
+            | PipedCallSeqLength ([ srcTy ],sq) ->
+                CallQueryableCount(srcTy, EvalInner sq)
+
+            | PipedCallSeqHead ([ srcTy ],sq) ->
+                CallQueryableFirst(srcTy, EvalInner sq)
+
+            | PipedCallSeqFind([ srcTy ],sq, NewDelegate(_,[v],f)) ->
+                CallQueryableFirstFind(srcTy, EvalInner sq, FuncExprToLinqFunc2Expression (srcTy,boolTy,v,MacroExpand f))
+
+            | MacroReduction(reduced) -> 
+                EvalOuterWithPostProcess reduced
+
+            | _  -> 
+                EvalInner tm
+        
+        EvalOuterWithPostProcess body 
+ 
+    let query (p : Expr<'T1>) : 'T1 = 
+      Runtime.Execution.wrapQuery queryUntyped p
+
+    let SQL x = query x
+
+
+    
+    
+
+    //-------------------------------------------------------------------------
+    // Nullable utilities for F#
+
+(*
+
+    /// This operator compares Nullable values with non-Nullable values using
+    /// structural comparison
+    [<ReflectedDefinition>]
+    let (>=?!) (x : Nullable<'T1>) (y: 'T1) = 
+        x.HasValue && x.Value >= y
+
+    [<ReflectedDefinition>]
+    let (>?!) (x : Nullable<'T1>) (y: 'T1) = 
+        x.HasValue && x.Value > y
+
+    [<ReflectedDefinition>]
+    let (<=?!) (x : Nullable<'T1>) (y: 'T1) = 
+        not x.HasValue || x.Value <= y
+
+    [<ReflectedDefinition>]
+    let (<?!) (x : Nullable<'T1>) (y: 'T1) = 
+        not x.HasValue || x.Value < y
+
+    [<ReflectedDefinition>]
+    let (=?!) (x : Nullable<'T1>) (y: 'T1) = 
+        x.HasValue && x.Value = y
+
+    [<ReflectedDefinition>]
+    let (<>?!) (x : Nullable<'T1>) (y: 'T1) = 
+        not x.HasValue or x.Value <> y
+
+    /// This overloaded operator divides Nullable values by non-Nullable values
+    /// using the overloaded operator "/".  Inlined to allow use over any type,
+    /// as this resolves the overloading on "/".
+    [<ReflectedDefinition>]
+    let inline (/?!) (x : Nullable<'T1>) (y: 'T1) = 
+        if x.HasValue then new Nullable<'T1>(x.Value / y)
+        else x
+
+    /// This overloaded operator adds Nullable values by non-Nullable values
+    /// using the overloaded operator "+".  Inlined to allow use over any type,
+    /// as this resolves the overloading on "+".
+    [<ReflectedDefinition>]
+    let inline (+?!) (x : Nullable<'T1>) (y: 'T1) = 
+        if x.HasValue then new Nullable<'T1>(x.Value + y)
+        else x
+
+    /// This overloaded operator adds Nullable values by non-Nullable values
+    /// using the overloaded operator "-".  Inlined to allow use over any type,
+    /// as this resolves the overloading on "-".
+    [<ReflectedDefinition>]
+    let inline (-?!) (x : Nullable<'T1>) (y: 'T1) = 
+        if x.HasValue then new Nullable<'T1>(x.Value - y)
+        else x
+
+    /// This overloaded operator adds Nullable values by non-Nullable values
+    /// using the overloaded operator "*".  Inlined to allow use over any type,
+    /// as this resolves the overloading on "*".
+    [<ReflectedDefinition>]
+    let inline ( *?!) (x : Nullable<'T1>) (y: 'T1) = 
+        if x.HasValue then new Nullable<'T1>(x.Value * y)
+        else x
+
+    /// This overloaded operator adds Nullable values by non-Nullable values
+    /// using the overloaded operator "%".  Inlined to allow use over any type,
+    /// as this resolves the overloading on "%".
+    [<ReflectedDefinition>]
+    let inline ( %?!) (x : Nullable<'T1>) (y: 'T1) = 
+        if x.HasValue then new Nullable<'T1>(x.Value % y)
+        else x
+
+*)
+    
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Linq/LinqQueries.fsi b/workyard/linq/FSharp.PowerPack.Linq/LinqQueries.fsi
new file mode 100644
index 0000000..e95e8d0
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/LinqQueries.fsi
@@ -0,0 +1,61 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Linq
+
+    open System
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Query =
+
+        /// Evaluate the quotation expression by first converting to a LINQ expression tree
+        /// making use of IQueryable operators and then executing expression tree
+        ///
+        /// Exceptions: <c>InvalidArgumentException</c> will be raised if the input expression is
+        /// not in the subset that can be converted to a LINQ expression tree
+        val query : Quotations.Expr<'T> -> 'T
+
+        /// When used in queries, this operator corresponds to the LINQ Contains operator and the <c>query</c> convertor recognises it as such
+        val contains : 
+            key:'T -> 
+            source:seq<'T> -> 
+               bool
+
+        /// When used in queries, this operator corresponds to the LINQ Min operator and the <c>query</c> convertor recognises it as such
+        /// It differs in return type from <c>Seq.minBy</c>
+        val minBy : 
+            keySelector:('T -> 'Key) -> 
+            source:seq<'T> -> 
+               'Key
+
+        /// When used in queries, this operator corresponds to the LINQ Max operator and the <c>query</c> convertor recognises it as such
+        /// It differs in return type from <c>Seq.maxBy</c>
+        val maxBy : 
+            keySelector:('T -> 'Key) -> 
+            source:seq<'T> -> 
+               'Key
+
+        /// When used in queries, this operator corresponds to the LINQ Join operator and the <c>query</c> convertor recognises it as such
+        val groupBy : 
+            keySelector:('T -> 'Key) -> 
+            source:seq<'T> -> 
+               seq<System.Linq.IGrouping<'Key,'T>>
+
+        /// This join operator corresponds to the LINQ Join operator and the <c>query</c> convertor recognises it as such
+        val join : 
+            outerSource:seq<'Outer> -> 
+            innerSource:seq<'Inner> -> 
+            outerKeySelector:('Outer -> 'Key) -> 
+            innerKeySelector:('Inner -> 'Key) -> 
+            resultSelector:('Outer -> 'Inner -> 'Result) ->
+               seq<'Result>
+
+
+        /// This join operator implements the LINQ GroupJoin operator and the <c>query</c> convertor recognises it as such
+        val groupJoin : 
+            outerSource:seq<'Outer> -> 
+            innerSource:seq<'Inner> -> 
+            outerKeySelector:('Outer -> 'Key) -> 
+            innerKeySelector:('Inner -> 'Key) -> 
+            resultSelector:('Outer -> seq<'Inner> -> 'Result) ->
+               seq<'Result>
+
diff --git a/workyard/linq/FSharp.PowerPack.Linq/MutableTuple.fs b/workyard/linq/FSharp.PowerPack.Linq/MutableTuple.fs
new file mode 100644
index 0000000..e1d7e47
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/MutableTuple.fs
@@ -0,0 +1,181 @@
+// ----------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation 2005-2011.
+// This sample code is provided "as is" without warranty of any kind. 
+// We disclaim all warranties, either express or implied, including the 
+// warranties of merchantability and fitness for a particular purpose. 
+// ----------------------------------------------------------------------------
+
+namespace Microsoft.FSharp.Linq.Runtime
+
+// ----------------------------------------------------------------------------
+// Mutable Tuples - used when translating queries that use F# tuples
+// and records. We replace tuples/records with mutable tubples which 
+// are handled correctly by LINQ to SQL/Entities
+// ----------------------------------------------------------------------------
+
+/// This type shouldn't be used directly from user code.
+type MutableTuple<'T1>() =
+  [<DefaultValue>]
+  val mutable private item1 : 'T1
+  member x.Item1 with get() = x.item1 and set(v) = x.item1 <- v
+
+
+/// This type shouldn't be used directly from user code.
+type MutableTuple<'T1, 'T2>() =
+  [<DefaultValue>]
+  val mutable private item1 : 'T1
+  member x.Item1 with get() = x.item1 and set(v) = x.item1 <- v
+
+  [<DefaultValue>]
+  val mutable private item2 : 'T2
+  member x.Item2 with get() = x.item2 and set(v) = x.item2 <- v
+
+
+/// This type shouldn't be used directly from user code.
+type MutableTuple<'T1, 'T2, 'T3>() =
+  [<DefaultValue>]
+  val mutable private item1 : 'T1
+  member x.Item1 with get() = x.item1 and set(v) = x.item1 <- v
+
+  [<DefaultValue>]
+  val mutable private item2 : 'T2
+  member x.Item2 with get() = x.item2 and set(v) = x.item2 <- v
+
+  [<DefaultValue>]
+  val mutable private item3 : 'T3
+  member x.Item3 with get() = x.item3 and set(v) = x.item3 <- v
+
+
+/// This type shouldn't be used directly from user code.
+type MutableTuple<'T1, 'T2, 'T3, 'T4>() =
+  [<DefaultValue>]
+  val mutable private item1 : 'T1
+  member x.Item1 with get() = x.item1 and set(v) = x.item1 <- v
+
+  [<DefaultValue>]
+  val mutable private item2 : 'T2
+  member x.Item2 with get() = x.item2 and set(v) = x.item2 <- v
+
+  [<DefaultValue>]
+  val mutable private item3 : 'T3
+  member x.Item3 with get() = x.item3 and set(v) = x.item3 <- v
+
+  [<DefaultValue>]
+  val mutable private item4 : 'T4
+  member x.Item4 with get() = x.item4 and set(v) = x.item4 <- v
+
+
+/// This type shouldn't be used directly from user code.
+type MutableTuple<'T1, 'T2, 'T3, 'T4, 'T5>() =
+  [<DefaultValue>]
+  val mutable private item1 : 'T1
+  member x.Item1 with get() = x.item1 and set(v) = x.item1 <- v
+
+  [<DefaultValue>]
+  val mutable private item2 : 'T2
+  member x.Item2 with get() = x.item2 and set(v) = x.item2 <- v
+
+  [<DefaultValue>]
+  val mutable private item3 : 'T3
+  member x.Item3 with get() = x.item3 and set(v) = x.item3 <- v
+
+  [<DefaultValue>]
+  val mutable private item4 : 'T4
+  member x.Item4 with get() = x.item4 and set(v) = x.item4 <- v
+
+  [<DefaultValue>]
+  val mutable private item5 : 'T5
+  member x.Item5 with get() = x.item5 and set(v) = x.item5 <- v
+
+
+/// This type shouldn't be used directly from user code.
+type MutableTuple<'T1, 'T2, 'T3, 'T4, 'T5, 'T6>() =
+  [<DefaultValue>]
+  val mutable private item1 : 'T1
+  member x.Item1 with get() = x.item1 and set(v) = x.item1 <- v
+
+  [<DefaultValue>]
+  val mutable private item2 : 'T2
+  member x.Item2 with get() = x.item2 and set(v) = x.item2 <- v
+
+  [<DefaultValue>]
+  val mutable private item3 : 'T3
+  member x.Item3 with get() = x.item3 and set(v) = x.item3 <- v
+
+  [<DefaultValue>]
+  val mutable private item4 : 'T4
+  member x.Item4 with get() = x.item4 and set(v) = x.item4 <- v
+
+  [<DefaultValue>]
+  val mutable private item5 : 'T5
+  member x.Item5 with get() = x.item5 and set(v) = x.item5 <- v
+
+  [<DefaultValue>]
+  val mutable private item6 : 'T6
+  member x.Item6 with get() = x.item6 and set(v) = x.item6 <- v
+
+
+/// This type shouldn't be used directly from user code.
+type MutableTuple<'T1, 'T2, 'T3, 'T4, 'T5, 'T6, 'T7>() =
+  [<DefaultValue>]
+  val mutable private item1 : 'T1
+  member x.Item1 with get() = x.item1 and set(v) = x.item1 <- v
+
+  [<DefaultValue>]
+  val mutable private item2 : 'T2
+  member x.Item2 with get() = x.item2 and set(v) = x.item2 <- v
+
+  [<DefaultValue>]
+  val mutable private item3 : 'T3
+  member x.Item3 with get() = x.item3 and set(v) = x.item3 <- v
+
+  [<DefaultValue>]
+  val mutable private item4 : 'T4
+  member x.Item4 with get() = x.item4 and set(v) = x.item4 <- v
+
+  [<DefaultValue>]
+  val mutable private item5 : 'T5
+  member x.Item5 with get() = x.item5 and set(v) = x.item5 <- v
+
+  [<DefaultValue>]
+  val mutable private item6 : 'T6
+  member x.Item6 with get() = x.item6 and set(v) = x.item6 <- v
+
+  [<DefaultValue>]
+  val mutable private item7 : 'T7
+  member x.Item7 with get() = x.item7 and set(v) = x.item7 <- v
+
+
+/// This type shouldn't be used directly from user code.
+type MutableTuple<'T1, 'T2, 'T3, 'T4, 'T5, 'T6, 'T7, 'T8>() =
+  [<DefaultValue>]
+  val mutable private item1 : 'T1
+  member x.Item1 with get() = x.item1 and set(v) = x.item1 <- v
+
+  [<DefaultValue>]
+  val mutable private item2 : 'T2
+  member x.Item2 with get() = x.item2 and set(v) = x.item2 <- v
+
+  [<DefaultValue>]
+  val mutable private item3 : 'T3
+  member x.Item3 with get() = x.item3 and set(v) = x.item3 <- v
+
+  [<DefaultValue>]
+  val mutable private item4 : 'T4
+  member x.Item4 with get() = x.item4 and set(v) = x.item4 <- v
+
+  [<DefaultValue>]
+  val mutable private item5 : 'T5
+  member x.Item5 with get() = x.item5 and set(v) = x.item5 <- v
+
+  [<DefaultValue>]
+  val mutable private item6 : 'T6
+  member x.Item6 with get() = x.item6 and set(v) = x.item6 <- v
+
+  [<DefaultValue>]
+  val mutable private item7 : 'T7
+  member x.Item7 with get() = x.item7 and set(v) = x.item7 <- v
+
+  [<DefaultValue>]
+  val mutable private item8 : 'T8
+  member x.Item8 with get() = x.item8 and set(v) = x.item8 <- v
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Linq/QueryExtensions.fs b/workyard/linq/FSharp.PowerPack.Linq/QueryExtensions.fs
new file mode 100644
index 0000000..1ee1bc8
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/QueryExtensions.fs
@@ -0,0 +1,434 @@
+// ----------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation 2005-2011.
+// This sample code is provided "as is" without warranty of any kind. 
+// We disclaim all warranties, either express or implied, including the 
+// warranties of merchantability and fitness for a particular purpose. 
+// ----------------------------------------------------------------------------
+
+namespace Microsoft.FSharp.Linq.Runtime
+
+open System
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Quotations.DerivedPatterns
+open Microsoft.FSharp.Reflection
+open Microsoft.FSharp.Linq.Runtime
+
+[<AutoOpen>]
+module TypeExtensions = 
+  type System.Type with 
+    /// Returns nicely formatted name of the type
+    member t.NiceName =
+      let sb = new System.Text.StringBuilder()
+      let rec build (t:System.Type) =
+        if t.IsGenericType then 
+          // Remove the `1 part from generic names
+          let tick = t.Name.IndexOf('`')
+          let name = t.Name.Substring(0, tick) 
+          Printf.bprintf sb "%s" t.Name
+          Printf.bprintf sb "<"
+          // Print generic type arguments recursively
+          let args = t.GetGenericArguments()
+          for i in 0 .. args.Length - 1 do 
+            if i <> 0 then Printf.bprintf sb ", "
+            build args.[i]
+          Printf.bprintf sb ">"
+        else
+          // Print ordiary type name
+          Printf.bprintf sb "%s" t.Name
+      build t
+      sb.ToString()
+
+// ----------------------------------------------------------------------------
+
+open TypeExtensions
+
+/// Represents information about System.Type that has one or more
+/// type parameters (and can be reconstructed when arguments are 
+/// provided). The type can be pointer, byref, generic or array.
+type ParameterizedType = 
+  | Pointer
+  | ByRef
+  | Generic of System.Type
+  | Array of int
+  /// Provide arguments to the parameterized type
+  member x.Rebuild(args:System.Type list) =
+    match x, args with 
+    | Pointer, [t] -> t.MakePointerType()
+    | ByRef, [t] -> t.MakeByRefType()
+    | Array n, [t] -> t.MakeArrayType(n)
+    | Generic t, args -> t.MakeGenericType(args |> Array.ofSeq)
+    | _ -> failwith "Cannot rebuild pointer, byref or array type using multiple type parameters!"
+
+/// Wrapper for System.Type that implements the 'comparable'
+/// constraint (to make it possible to use types as keys of Map)
+type ComparableType(t:System.Type) = 
+  member x.Type = t
+  override x.Equals(y) = 
+    x.Type.Equals((y :?> ComparableType).Type)
+  override x.GetHashCode() = 
+    x.Type.GetHashCode()
+  interface System.IComparable with
+    member x.CompareTo(o) =
+      let y = (o :?> ComparableType)
+      compare x.Type.AssemblyQualifiedName y.Type.AssemblyQualifiedName
+
+[<AutoOpen>]
+module TypePatterns =
+  /// Decompose type into several options - A type can be
+  /// primitive type, type parameter or parameterized type
+  let (|Parameterized|Parameter|Primitive|) (typ : System.Type) =
+    if typ.IsGenericType then 
+      let generic = typ.GetGenericTypeDefinition()
+      Parameterized(Generic(generic), typ.GetGenericArguments() |> List.ofSeq)
+    elif typ.IsGenericParameter then Parameter(typ.GenericParameterPosition)
+    elif not typ.HasElementType then Primitive(typ)
+    elif typ.IsArray then Parameterized(Array(typ.GetArrayRank()), [typ.GetElementType()])
+    elif typ.IsByRef then Parameterized(ByRef, [typ.GetElementType()])
+    elif typ.IsPointer then Parameterized(Pointer, [typ.GetElementType()])
+    else failwith "Cannot happen"
+
+// ----------------------------------------------------------------------------
+
+/// Represents a transformation of quotations that changes both 
+/// expressions and types (e.g. to replace 'int' with 'string')
+/// (Recursively processes the whole quotation or type)
+type IQuotationTransformation =
+  abstract TransformExpr : Expr -> Expr 
+  abstract TransformType : Type -> Type
+
+/// Represents a rule that modifies quotations in some way
+/// Processing quotations and types recursively can be done using
+/// IQuotationTransformation passed as argument
+type IQuotationAdapter =
+  abstract AdaptExpr : IQuotationTransformation * Expr -> Expr option
+  abstract AdaptType : IQuotationTransformation * Type -> Type option
+
+module Transformations = 
+
+  /// Transform a specified type using quotation adapter
+  /// (This recursively processes all type parameters of the type as well.)
+  let rec transformType (adapt:IQuotationAdapter) trans typ = 
+    match adapt.AdaptType(trans, typ) with 
+    | Some replacement -> replacement
+    | None ->
+    match typ with
+    | Parameter _ -> failwith "Parameter not expected in applyTypeTransformation"
+    | Primitive _ -> typ
+    | Parameterized(shape, args) ->
+        let args' = args |> List.map (transformType adapt trans)
+        if Seq.forall2 (=) args args' then typ
+        else shape.Rebuild(args')
+
+  /// Transform quotation using the specified quotation transformation.
+  /// This replaces expressions according to the 'TransformExpr' and 
+  /// replaces types according to the 'TransformType' method.
+  let rec transformQuotation (adapt:IQuotationAdapter) ctx (quot:Expr) = 
+    // Create transformation to be used for processing of nested 
+    // quotations (if needed by 'AdaptExpr') using current context
+    let rec trans = 
+      { new IQuotationTransformation with
+          member x.TransformExpr e = transformQuotation adapt ctx e
+          member x.TransformType t = transformType adapt trans t }
+
+    // Run the adapter to see if it changes the expression
+    match adapt.AdaptExpr(trans, quot) with
+    | Some(nquot:Expr) -> nquot
+    | _ ->
+
+    // Decompose quotation and recursively process sub-parts
+    match quot with 
+    | Patterns.Let(v, init, body) ->
+        // We may need to change type of the variable if transformed
+        // initialization expression has different type
+        let init' = transformQuotation adapt ctx init
+        let v', ctx =
+          // We could transform type using 'transformType', but we don't
+          // need to because quotation has type already 
+          if init'.Type <> init.Type then
+            let v' = new Var(v.Name, init'.Type, v.IsMutable)
+            v', Map.add v v' ctx
+          else v, ctx
+        // Transform the body
+        let body' = transformQuotation adapt ctx body
+        Expr.Let(v', init', body')
+
+    | Patterns.NewTuple(elems) ->
+        // Recreate tuple - this infers new type of tuple
+        Expr.NewTuple (elems |> List.map (transformQuotation adapt ctx))
+
+    | Patterns.NewUnionCase(ucase, args) ->
+        // Recreate union case constructor
+        // (We may need to change the type of the union type)
+        let args' = args |> List.map (transformQuotation adapt ctx)
+        let nty = transformType adapt trans ucase.DeclaringType
+        let ucase' = FSharpType.GetUnionCases(nty) |> Seq.find (fun c -> c.Tag = ucase.Tag)
+        Expr.NewUnionCase(ucase', args')
+
+    | Patterns.Call(inst, mi, args) ->
+        // Recreate invocation
+        // (We may need to change type arguments of generic method call)
+        let args' = args |> List.map (transformQuotation adapt ctx)
+        let inst' = inst |> Option.map (transformQuotation adapt ctx)
+        let mi' = 
+          if mi.IsGenericMethod then
+            // Replace type arguments of generic method
+            let gmi = mi.GetGenericMethodDefinition()
+            let types = mi.GetGenericArguments()
+                        |> Array.map (transformType adapt trans)
+            gmi.MakeGenericMethod(types)
+          else mi
+        match inst' with
+        | None -> Expr.Call(mi', args')
+        | Some(inst') -> Expr.Call(inst', mi', args')
+
+    | ExprShape.ShapeLambda(v, body) -> 
+        // Recreate lambda 
+        // (Use type transformation to calculate new type of variable)
+        match transformType adapt trans v.Type with 
+        | nty when nty = v.Type -> Expr.Lambda(v, transformQuotation adapt ctx body)
+        | nty ->
+            // If the type is different, create new variable
+            let v' = new Var(v.Name, nty, v.IsMutable)
+            Expr.Lambda(v', transformQuotation adapt (Map.add v v' ctx) body)
+
+    | Patterns.Coerce(expr, targetType) ->
+        // Recreate coercion - transform the target type
+        let targetType' = transformType adapt trans targetType 
+        Expr.Coerce(transformQuotation adapt ctx expr, targetType')        
+          
+    | ExprShape.ShapeCombination(shape, args) -> 
+        // Recursively process all arguments & recreate
+        let args = args |> List.map (transformQuotation adapt ctx)
+        ExprShape.RebuildShapeCombination(shape, args)
+
+    | ExprShape.ShapeVar(v) -> 
+        match Map.tryFind v ctx with
+        | Some(v) -> Expr.Var(v)
+        | _ -> quot
+
+// ----------------------------------------------------------------------------
+
+module Adapters = 
+
+  /// Declare symbol inside pattern. For example:
+  ///  | Let 1 (i, <NestedPattern#1>) 
+  ///  | Let 2 (i, <NestedPattern#2>) ->
+  ///      // i will be either 1 or 2
+  let (|Let|) v e = (v, e)
+
+
+  /// Adapts records in quotations (Replaces uses of records with tuples
+  /// which can be later removed using TupleAdapter)
+  type RecordAdapter() =
+    interface IQuotationAdapter with
+
+      /// Turns all top-level uses of records into tuples
+      member x.AdaptType(trans, t) =
+        if FSharpType.IsRecord(t) then
+          let types = [| for f in FSharpType.GetRecordFields(t) -> f.PropertyType |]
+          Some(FSharpType.MakeTupleType(types))
+        else None
+
+      /// Turns all tupl-level uses of 'NewTuple' and 'TupleGet' into
+      /// corresponding calls (constructor / property get) on mutable tuples
+      member x.AdaptExpr(trans, q) = 
+        match q with
+        | Patterns.PropertyGet(Some(inst), pi, args) when FSharpType.IsRecord(pi.DeclaringType) ->
+            let idx = FSharpType.GetRecordFields(pi.DeclaringType) |> Seq.findIndex ((=) pi)
+            Some(Expr.TupleGet(trans.TransformExpr(inst), idx))
+        | Patterns.NewRecord(typ, args) ->
+            Some(Expr.NewTuple(args))
+        | _ -> None
+
+
+  /// Adapts tuples in quotations.
+  /// (Replace uses of the tuple type with 'MutableTuple' type which
+  /// has get/set properties & parameterless constructor and can be used
+  /// in LINQ to Entities)
+  type TupleAdapter() =
+
+    // Get arrays of types & map of transformations
+    let tupleTypes = 
+      [| yield typedefof<System.Tuple<_>>, typedefof<MutableTuple<_>>
+         yield typedefof<_ * _>, typedefof<MutableTuple<_, _>>
+         yield typedefof<_ * _ * _>, typedefof<MutableTuple<_, _, _>>
+         yield typedefof<_ * _ * _ * _>, typedefof<MutableTuple<_, _, _, _>>
+         yield typedefof<_ * _ * _ * _ * _>, typedefof<MutableTuple<_, _, _, _, _>>
+         yield typedefof<_ * _ * _ * _ * _ * _>, typedefof<MutableTuple<_, _, _, _, _, _>>
+         yield typedefof<_ * _ * _ * _ * _ * _ * _>, typedefof<MutableTuple<_, _, _, _, _, _, _>>
+         yield typedefof<_ * _ * _ * _ * _ * _ * _ * _>, typedefof<MutableTuple<_, _, _, _, _, _, _, _>> |]
+    let mutableTuples = tupleTypes |> Array.map snd
+    let map = tupleTypes |> dict
+
+    interface IQuotationAdapter with
+
+      /// Turns all top-level uses of tuple into mutable tuples
+      member x.AdaptType(trans, t) =
+        // Tuples are generic, so lookup only for generic types 
+        if t.IsGenericType then
+          let generic = t.GetGenericTypeDefinition()
+          match map.TryGetValue(generic) with
+          | true, tupleType ->
+              // Recursively transform type arguments
+              let args = t.GetGenericArguments() |> Array.map trans.TransformType
+              Some(tupleType.MakeGenericType(args))
+          | _ -> None
+        else None
+
+      /// Turns all tupl-level uses of 'NewTuple' and 'TupleGet' into
+      /// corresponding calls (constructor / property get) on mutable tuples
+      member x.AdaptExpr(trans, q) = 
+        match q with
+        | Patterns.NewTuple(args) ->
+            let createTuple (args:Expr list) =
+              // Will fit into a single tuple type
+              let typ = mutableTuples.[args.Length - 1]
+              let typ = typ.MakeGenericType [| for a in args -> a.Type |]
+              let ctor = typ.GetConstructor [| |]
+              let var = Var.Global("newTuple", typ)
+
+              // Create quotation for 'new MutableTuple(Item1=<e1>, ...)`
+              let assignments = 
+                args |> List.mapi (fun i arg ->
+                  Expr.PropertySet(Expr.Var(var), typ.GetProperty(sprintf "Item%d" (i+1)), arg) )
+              let body = 
+                assignments |> List.rev
+                |> List.fold (fun st v -> Expr.Sequential(st, v)) (Expr.Value(()))
+              let body = Expr.Sequential(body, Expr.Var(var))
+              Expr.Let(var, Expr.NewObject(ctor, []), body)
+
+            let rec create (args:Expr list) = 
+              match args with 
+              | x1::x2::x3::x4::x5::x6::x7::x8::[] ->
+                  createTuple [ x1; x2; x3; x4; x5; x6; x7; createTuple [x8] ]
+              | x1::x2::x3::x4::x5::x6::x7::x8::tail ->
+                  // Too long to fit single tuple - nested tuple after first 7
+                  createTuple [ x1; x2; x3; x4; x5; x6; x7; create (x8::tail) ]
+              | args -> createTuple args
+
+            // Recursively transform arguments & create mutable tuple
+            Some(args |> List.map trans.TransformExpr |> create)
+
+        | Patterns.TupleGet(e, i) ->
+            // Recursively generate tuple get 
+            // (may be nested e.g. TupleGet(<e>, 9) ~> <e>.Item8.Item3)
+            let rec walk i (inst:Expr) (t:Type) = 
+              // Transform type of the tuple we're accessing
+              let newType = map.[t.GetGenericTypeDefinition()]
+              let args = t.GetGenericArguments() |> Array.map trans.TransformType
+              let newType = newType.MakeGenericType(args)
+
+              // Get property (at most the last one)
+              let prop = sprintf "Item%d" (1 + (min i 7))
+              let propInfo = newType.GetProperty(prop)
+              let res = Expr.PropertyGet(inst, propInfo)
+              // Do we need to add another property get for the last property?
+              if i < 7 then res 
+              else walk (i - 7) res (t.GetGenericArguments().[7]) 
+            
+            Some(walk i (trans.TransformExpr e) e.Type)
+
+        | Let 0 (i, DerivedPatterns.SpecificCall <@ fst @> (None, tys, [tuple])) 
+        | Let 1 (i, DerivedPatterns.SpecificCall <@ snd @> (None, tys, [tuple])) ->
+            // Transform calls to 'snd' and 'fst' functions 
+            // (Just create 'TupleGet' quotation and transform it)
+            let expr = Expr.TupleGet(tuple, i)
+            (x :> IQuotationAdapter).AdaptExpr(trans, expr)
+
+        | _ -> None
+
+// ----------------------------------------------------------------------------
+
+type Grouping<'K, 'T>(key:'K, values:seq<'T>) =
+  interface System.Linq.IGrouping<'K, 'T> with
+    member x.Key = key
+  interface System.Collections.IEnumerable with
+    member x.GetEnumerator() = values.GetEnumerator() :> System.Collections.IEnumerator
+  interface System.Collections.Generic.IEnumerable<'T> with
+    member x.GetEnumerator() = values.GetEnumerator()
+
+module Execution =
+  open Microsoft.FSharp.Linq.QuotationEvaluation
+
+  let SeqMap = 
+    match <@ Seq.map : (int -> int) -> int seq -> int seq @> with
+    DerivedPatterns.Lambdas(_, Patterns.Call(_, mi, _)) -> mi.GetGenericMethodDefinition()
+    | _ -> failwith "Cannot extract info for 'Seq.map'"
+
+  let wrapQuery queryUntyped (q:Expr<'T>) : 'T = 
+    let qorig = q :> Expr
+    let qtrans = 
+      qorig
+        |> Transformations.transformQuotation (Adapters.RecordAdapter()) Map.empty
+        |> Transformations.transformQuotation (Adapters.TupleAdapter()) Map.empty
+
+    let rec generateTupleAccess (sourceType:System.Type) (expr:Expr) i =
+      let prop = sourceType.GetProperty(sprintf "Item%d" (min i 8))
+      let expr = Expr.PropertyGet(expr, prop)
+      if i > 7 then 
+        let sourceType = sourceType.GetGenericArguments().[7]
+        generateTupleAccess sourceType expr (i - 7)
+        else expr
+
+    let rec createConversion (sourceType:System.Type) (targetType:System.Type) expr = 
+      printfn " from '%s'\n to '%s'\n\n" sourceType.NiceName targetType.NiceName
+      match sourceType, targetType with
+      | Parameterized(Generic t1, [tyarg1]), Parameterized(Generic t2, [tyarg2]) 
+            when t1 = typedefof<seq<_>> && t2 = typedefof<seq<_>> && tyarg1 <> tyarg2 ->
+          // 
+          let var = new Var("v", tyarg1)
+          let convExpr : Expr = createConversion tyarg1 tyarg2 (Expr.Var(var))
+          let meth = SeqMap.MakeGenericMethod [| tyarg1; tyarg2 |]
+          Expr.Call(meth, [ Expr.Lambda(var, convExpr); expr ])
+
+      | Parameterized(Generic t1, args1), Parameterized(Generic t2, args2) 
+          when FSharpType.IsTuple(targetType) ->
+
+          let var = new Var("t", sourceType)
+          let args = 
+            FSharpType.GetTupleElements(targetType) |> Seq.mapi (fun i targetT ->
+                let acc = generateTupleAccess sourceType (Expr.Var(var)) (i + 1)
+                createConversion acc.Type targetT acc)
+          let body = Expr.NewTuple(List.ofSeq args)
+          Expr.Let(var, expr, body)
+
+      | Parameterized(Generic t1, [keyt1; valt1]), Parameterized(Generic t2, [keyt2; valt2])
+          when t1 = typedefof<System.Linq.IGrouping<_, _>> && t2 = t1 ->
+          if keyt1 <> keyt2 then failwith "Tuples or records are not supported as grouping keys!"
+        
+          let targetGrouping = typedefof<Grouping<_, _>>.MakeGenericType [| keyt2; valt2 |]
+          let targetIGrouping = typedefof<System.Linq.IGrouping<_, _>>.MakeGenericType [| keyt2; valt2 |]
+
+          let prop = sourceType.GetProperty("Key")
+          let var = new Var("v", valt1)
+          let convExpr : Expr = createConversion valt1 valt2 (Expr.Var(var))
+          let meth = SeqMap.MakeGenericMethod [| valt1; valt2 |]
+            
+          let args = 
+            [ Expr.PropertyGet(expr, prop)
+              Expr.Call(meth, [ Expr.Lambda(var, convExpr); expr ]) ]
+
+          Expr.Coerce(Expr.NewObject(targetGrouping.GetConstructors() |> Seq.head, args), targetIGrouping)
+      
+      | Parameterized(Generic t1, args1), Primitive t2 
+          when FSharpType.IsRecord(targetType) ->
+
+          let var = new Var("r", sourceType)
+          let args = 
+            FSharpType.GetRecordFields(targetType) |> Seq.mapi (fun i prop ->
+                let acc = generateTupleAccess sourceType (Expr.Var(var)) (i + 1)
+                createConversion acc.Type prop.PropertyType acc)
+          let body = Expr.NewRecord(targetType, List.ofSeq args)
+          Expr.Let(var, expr, body)
+
+      | _ -> 
+          expr
+
+    let result : obj = queryUntyped qtrans
+    if qtrans.Type <> qorig.Type then
+      let arg = Expr.Value(result, qtrans.Type)
+      let converted = createConversion qtrans.Type qorig.Type arg
+      unbox (converted.EvalUntyped())
+    else
+      printfn "ok"
+      unbox result
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Linq/assemblyinfo.FSharp.PowerPack.Linq.dll.fs b/workyard/linq/FSharp.PowerPack.Linq/assemblyinfo.FSharp.PowerPack.Linq.dll.fs
new file mode 100644
index 0000000..f37c797
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Linq/assemblyinfo.FSharp.PowerPack.Linq.dll.fs
@@ -0,0 +1,7 @@
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("FSharp.PowerPack.Linq.dll")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("FSharp.PowerPack.Linq.dll")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
diff --git a/workyard/linq/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj b/workyard/linq/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj
new file mode 100644
index 0000000..4ec97dc
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <TOOLS Condition=" '$(TOOLS)' == '' ">..\..\tools</TOOLS>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{1B749E89-2B1A-4443-A522-EEB348E01555}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>FSharp.PowerPack.Unittests.v40</RootNamespace>
+    <AssemblyName>FSharp.PowerPack.Unittests.v40</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <StrongName>false</StrongName>
+    <!--->ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB}</ProjectTypeGuids-->
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;ENTITIES</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>62</NoWarn>
+    <OtherFlags>--mlcompatibility</OtherFlags>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>62</NoWarn>
+    <OtherFlags>--mlcompatibility</OtherFlags>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="LibraryTestFx.fs" />
+    <Compile Include="Utilities.fs" />
+    <Compile Include="SeqModule.fs" />
+    <Compile Include="SeqModule2.fs" />
+    <Compile Include="..\FSharp.PowerPack.Unittests\QueryTests.fs">
+      <Link>QueryTests.fs</Link>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="Entities.Northwind">
+      <HintPath>..\FSharp.PowerPack.Unittests\Linq\Entities.Northwind\bin\Debug\Entities.Northwind.dll</HintPath>
+    </Reference>
+    <Reference Include="FSharp.PowerPack.Parallel.Seq">
+      <HintPath>..\..\..\Debug\bin\FSharp.PowerPack.Parallel.Seq.dll</HintPath>
+    </Reference>
+    <Reference Include="mscorlib" />
+    <Reference Include="FSharp.Core" />
+    <Reference Include="nunit.framework">
+      <HintPath>$(TOOLS)\NUnit\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Data.Entity" />
+    <Reference Include="System.Data.Linq" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\FSharp.PowerPack.Linq\FSharp.PowerPack.Linq.fsproj">
+      <Name>FSharp.PowerPack.Linq</Name>
+      <Project>{4c2ed03b-5ace-427b-8285-ad333e60f35e}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+</Project>
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj.vspscc b/workyard/linq/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj.vspscc
new file mode 100644
index 0000000..b6d3289
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests.v40/FSharp.PowerPack.Unittests.v40.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/workyard/linq/FSharp.PowerPack.Unittests.v40/LibraryTestFx.fs b/workyard/linq/FSharp.PowerPack.Unittests.v40/LibraryTestFx.fs
new file mode 100644
index 0000000..5e723b5
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests.v40/LibraryTestFx.fs
@@ -0,0 +1,67 @@
+
+module FSharp.Core.Unittests.LibraryTestFx
+
+open System
+open System.Collections.Generic
+open Microsoft.FSharp.Collections
+open System.Linq
+
+open NUnit.Framework
+
+// Workaround for bug 3601, we are issuing an unnecessary warning
+#nowarn "0004"
+
+/// Check that the lamda throws an exception of the given type. Otherwise
+/// calls Assert.Fail()
+let private CheckThrowsExn<'a when 'a :> exn> (f : unit -> unit) =
+    let funcThrowsAsExpected =
+        try
+            let _ = f ()
+            Some "no exception" // Did not throw!
+        with
+        | :? 'a
+            -> None // Thew null ref, OK
+        | exn -> Some  (exn.ToString()) // Did now throw a null ref exception!
+    match funcThrowsAsExpected with
+    | None -> ()
+    | Some s -> Assert.Fail(s)
+
+let private CheckThrowsExn2<'a when 'a :> exn> s (f : unit -> unit) =
+    let funcThrowsAsExpected =
+        try
+            let _ = f ()
+            false // Did not throw!
+        with
+        | :? 'a
+            -> true   // Thew null ref, OK
+        | _ -> false  // Did now throw a null ref exception!
+    if funcThrowsAsExpected
+    then ()
+    else Assert.Fail(s)
+
+// Illegitimate exceptions. Once we've scrubbed the library, we should add an
+// attribute to flag these exception's usage as a bug.
+let CheckThrowsNullRefException      f = CheckThrowsExn<NullReferenceException>   f
+let CheckThrowsIndexOutRangException f = CheckThrowsExn<IndexOutOfRangeException> f
+
+// Legit exceptions
+let CheckThrowsNotSupportedException f = CheckThrowsExn<NotSupportedException>    f
+let CheckThrowsArgumentException     f = CheckThrowsExn<ArgumentException>        f
+let CheckThrowsArgumentNullException f = CheckThrowsExn<ArgumentNullException>    f
+let CheckThrowsArgumentNullException2 s f  = CheckThrowsExn2<ArgumentNullException>  s  f
+let CheckThrowsKeyNotFoundException  f = CheckThrowsExn<KeyNotFoundException>     f
+let CheckThrowsDivideByZeroException f = CheckThrowsExn<DivideByZeroException>    f
+let CheckThrowsInvalidOperationExn   f = CheckThrowsExn<InvalidOperationException> f
+let CheckThrowsFormatException       f = CheckThrowsExn<FormatException>           f
+let CheckThrowsAggregateException    f = CheckThrowsExn<AggregateException>           f
+
+// Verifies two sequences are equal (same length, equiv elements)
+let VerifyPSeqsEqual seq1 seq2 =
+    let len1 = PSeq.length seq1
+    let len2 = PSeq.length seq2
+    if len1 <> len2 then Assert.Fail(sprintf "seqs not equal length: %d and %d" len1 len2)
+    let set1 = set seq1
+    let set2 = set seq2
+    if set1 = set2
+    then ()
+    else Assert.Fail(sprintf "contents not the same: %A %A" set1 set2)
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests.v40/SeqModule.fs b/workyard/linq/FSharp.PowerPack.Unittests.v40/SeqModule.fs
new file mode 100644
index 0000000..a6c28f4
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests.v40/SeqModule.fs
@@ -0,0 +1,790 @@
+
+namespace FSharp.Core.Unittests.FSharp_Core.Microsoft_FSharp_Collections
+
+open System
+open NUnit.Framework
+open Microsoft.FSharp.Collections
+
+open FSharp.Core.Unittests.LibraryTestFx
+
+// Various tests for the:
+// Microsoft.FSharp.Collections.seq type
+
+(*
+[Test Strategy]
+Make sure each method works on:
+* Integer Seq (value type)
+* String Seq  (reference type)
+* Empty Seq   (0 elements)
+* Null Seq    (null)
+*)
+
+[<TestFixture>]
+type SeqModule() =
+
+//    [<Test>]
+//    member this.CachedSeq_Clear() =
+//     
+//        let evaluatedItems : int list ref = ref []
+//        let cachedSeq = 
+//            PSeq.initInfinite (fun i -> evaluatedItems := i :: !evaluatedItems; i)
+//            |> PSeq.cache
+//        
+//        // Verify no items have been evaluated from the Seq yet
+//        Assert.AreEqual(List.length !evaluatedItems, 0)
+//        
+//        // Force evaluation of 10 elements
+//        PSeq.take 10 cachedSeq
+//        |> PSeq.toList
+//        |> ignore
+//        
+//        // verify ref clear switch length
+//        Assert.AreEqual(List.length !evaluatedItems, 10)
+//
+//        // Force evaluation of 10 elements
+//        PSeq.take 10 cachedSeq
+//        |> PSeq.toList
+//        |> ignore
+//        
+//        // Verify ref clear switch length (should be cached)
+//        Assert.AreEqual(List.length !evaluatedItems, 10)
+//
+//        
+//        // Clear
+//        (box cachedSeq :?> System.IDisposable) .Dispose()
+//        
+//        // Force evaluation of 10 elements
+//        PSeq.take 10 cachedSeq
+//        |> PSeq.toList
+//        |> ignore
+//        
+//        // Verify length of evaluatedItemList is 20
+//        Assert.AreEqual(List.length !evaluatedItems, 20)
+//        ()
+        
+    [<Test>]
+    member this.Append() =
+
+        // empty Seq 
+        let emptySeq1 = PSeq.empty
+        let emptySeq2 = PSeq.empty
+        let appendEmptySeq = PSeq.append emptySeq1 emptySeq2
+        let expectResultEmpty = PSeq.empty
+           
+        VerifyPSeqsEqual expectResultEmpty appendEmptySeq
+          
+        // Integer Seq  
+        let integerSeq1:seq<int> = seq [0..4]
+        let integerSeq2:seq<int> = seq [5..9]
+         
+        let appendIntergerSeq = PSeq.append integerSeq1 integerSeq2
+       
+        let expectResultInteger = seq { for i in 0..9 -> i}
+        
+        VerifyPSeqsEqual expectResultInteger appendIntergerSeq
+        
+        
+        // String Seq
+        let stringSeq1:seq<string> = seq ["1";"2"]
+        let stringSeq2:seq<string> = seq ["3";"4"]
+        
+        let appendStringSeq = PSeq.append stringSeq1 stringSeq2
+        
+        let expectedResultString = seq ["1";"2";"3";"4"]
+        
+        VerifyPSeqsEqual expectedResultString appendStringSeq
+        
+        // null Seq
+        let nullSeq1 = seq [null;null]
+
+        let nullSeq2 =seq [null;null]
+
+        let appendNullSeq = PSeq.append nullSeq1 nullSeq2
+        
+        let expectedResultNull = seq [ null;null;null;null]
+        
+        VerifyPSeqsEqual expectedResultNull appendNullSeq
+        ()
+        
+        
+    [<Test>]
+    member this.Average() =
+        // empty Seq 
+        let emptySeq:pseq<double> = PSeq.empty<double>
+        
+        CheckThrowsInvalidOperationExn (fun () ->  PSeq.average emptySeq |> ignore)
+        
+            
+        // double Seq
+        let doubleSeq:seq<double> = seq [1.0;2.2;2.5;4.3]
+        
+        let averageDouble = PSeq.average doubleSeq
+        
+        Assert.IsFalse( averageDouble <> 2.5)
+        
+        // float32 Seq
+        let floatSeq:seq<float32> = seq [ 2.0f;4.4f;5.0f;8.6f]
+        
+        let averageFloat = PSeq.average floatSeq
+        
+        Assert.IsFalse( averageFloat <> 5.0f)
+        
+        // decimal Seq
+        let decimalSeq:seq<decimal> = seq [ 0M;19M;19.03M]
+        
+        let averageDecimal = PSeq.average decimalSeq
+        
+        Assert.IsFalse( averageDecimal <> 12.676666666666666666666666667M )
+        
+        // null Seq
+        let nullSeq:seq<double> = null
+            
+        CheckThrowsArgumentNullException (fun () -> PSeq.average nullSeq |> ignore) 
+        ()
+        
+        
+    [<Test>]
+    member this.AverageBy() =
+        // empty Seq 
+        let emptySeq:pseq<double> = PSeq.empty<double>
+        
+        CheckThrowsInvalidOperationExn (fun () ->  PSeq.averageBy (fun x -> x+1.0) emptySeq |> ignore)
+        
+        // double Seq
+        let doubleSeq:seq<double> = seq [1.0;2.2;2.5;4.3]
+        
+        let averageDouble = PSeq.averageBy (fun x -> x-2.0) doubleSeq
+        
+        Assert.IsFalse( averageDouble <> 0.5 )
+        
+        // float32 Seq
+        let floatSeq:seq<float32> = seq [ 2.0f;4.4f;5.0f;8.6f]
+        
+        let averageFloat = PSeq.averageBy (fun x -> x*3.3f)  floatSeq
+        
+        Assert.IsFalse( averageFloat <> 16.5f )
+        
+        // decimal Seq
+        let decimalSeq:seq<decimal> = seq [ 0M;19M;19.03M]
+        
+        let averageDecimal = PSeq.averageBy (fun x -> x/10.7M) decimalSeq
+        
+        Assert.IsFalse( averageDecimal <> 1.1847352024922118380062305296M )
+        
+        // null Seq
+        let nullSeq:seq<double> = null
+            
+        CheckThrowsArgumentNullException (fun () -> PSeq.averageBy (fun (x:double)->x+4.0) nullSeq |> ignore) 
+        ()
+        
+//    [<Test>]
+//    member this.Cache() =
+//        // empty Seq 
+//        let emptySeq:pseq<double> = PSeq.empty<double>
+//        
+//        let cacheEmpty = PSeq.cache emptySeq
+//        
+//        let expectedResultEmpty = PSeq.empty
+//        
+//        VerifyPSeqsEqual expectedResultEmpty cacheEmpty
+//               
+//        // double Seq
+//        let doubleSeq:seq<double> = seq [1.0;2.2;2.5;4.3]
+//        
+//        let cacheDouble = PSeq.cache doubleSeq
+//        
+//        VerifyPSeqsEqual doubleSeq cacheDouble
+//        
+//            
+//        // float32 Seq
+//        let floatSeq:seq<float32> = seq [ 2.0f;4.4f;5.0f;8.6f]
+//        
+//        let cacheFloat = PSeq.cache floatSeq
+//        
+//        VerifyPSeqsEqual floatSeq cacheFloat
+//        
+//        // decimal Seq
+//        let decimalSeq:seq<decimal> = seq [ 0M; 19M; 19.03M]
+//        
+//        let cacheDecimal = PSeq.cache decimalSeq
+//        
+//        VerifyPSeqsEqual decimalSeq cacheDecimal
+//        
+//        // null Seq
+//        let nullSeq = seq [null]
+//        
+//        let cacheNull = PSeq.cache nullSeq
+//        
+//        VerifyPSeqsEqual nullSeq cacheNull
+//        ()
+
+    [<Test>]
+    member this.Case() =
+
+        // integer Seq
+        let integerArray = [|1;2|]
+        let integerSeq = PSeq.cast integerArray
+        
+        let expectedIntegerSeq = seq [1;2]
+        
+        VerifyPSeqsEqual expectedIntegerSeq integerSeq
+        
+        // string Seq
+        let stringArray = [|"a";"b"|]
+        let stringSeq = PSeq.cast stringArray
+        
+        let expectedStringSeq = seq["a";"b"]
+        
+        VerifyPSeqsEqual expectedStringSeq stringSeq
+        
+        // empty Seq
+        let emptySeq = PSeq.cast PSeq.empty
+        let expectedEmptySeq = PSeq.empty
+        
+        VerifyPSeqsEqual expectedEmptySeq PSeq.empty
+        
+        // null Seq
+        let nullArray = [|null;null|]
+        let NullSeq = PSeq.cast nullArray
+        let expectedNullSeq = seq [null;null]
+        
+        VerifyPSeqsEqual expectedNullSeq NullSeq
+        
+        
+        ()
+        
+    [<Test>]
+    member this.Choose() =
+        
+        // int Seq
+        let intSeq = seq [1..20]    
+        let funcInt x = if (x%5=0) then Some x else None       
+        let intChoosed = PSeq.choose funcInt intSeq
+        let expectedIntChoosed = seq { for i = 1 to 4 do yield i*5}
+        
+        
+       
+        VerifyPSeqsEqual expectedIntChoosed intChoosed
+        
+        // string Seq
+        let stringSrc = seq ["list";"List"]
+        let funcString x = match x with
+                           | "list"-> Some x
+                           | "List" -> Some x
+                           | _ -> None
+        let strChoosed = PSeq.choose funcString stringSrc   
+        let expectedStrChoose = seq ["list";"List"]
+      
+        VerifyPSeqsEqual expectedStrChoose strChoosed
+        
+        // empty Seq
+        let emptySeq = PSeq.empty
+        let emptyChoosed = PSeq.choose funcInt emptySeq
+        
+        let expectedEmptyChoose = PSeq.empty
+        
+        VerifyPSeqsEqual expectedEmptyChoose emptySeq
+        
+
+        // null Seq
+        let nullSeq:seq<'a> = null    
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.choose funcInt nullSeq |> ignore) 
+        ()
+    
+//    [<Test>]
+//    member this.Compare() =
+//    
+//        // int Seq
+//        let intSeq1 = seq [1;3;7;9]    
+//        let intSeq2 = seq [2;4;6;8] 
+//        let funcInt x y = if (x>y) then x else 0
+//        let intcompared = PSeq.compareWith funcInt intSeq1 intSeq2
+//       
+//        Assert.IsFalse( intcompared <> 7 )
+//        
+//        // string Seq
+//        let stringSeq1 = seq ["a"; "b"]
+//        let stringSeq2 = seq ["c"; "d"]
+//        let funcString x y = match (x,y) with
+//                             | "a", "c" -> 0
+//                             | "b", "d" -> 1
+//                             |_         -> -1
+//        let strcompared = PSeq.compareWith funcString stringSeq1 stringSeq2  
+//        Assert.IsFalse( strcompared <> 1 )
+//         
+//        // empty Seq
+//        let emptySeq = PSeq.empty
+//        let emptycompared = PSeq.compareWith funcInt emptySeq emptySeq
+//        
+//        Assert.IsFalse( emptycompared <> 0 )
+//       
+//        // null Seq
+//        let nullSeq:seq<int> = null    
+//         
+//        CheckThrowsArgumentNullException (fun () -> PSeq.compareWith funcInt nullSeq emptySeq |> ignore)  
+//        CheckThrowsArgumentNullException (fun () -> PSeq.compareWith funcInt emptySeq nullSeq |> ignore)  
+//        CheckThrowsArgumentNullException (fun () -> PSeq.compareWith funcInt nullSeq nullSeq |> ignore)  
+//
+//        ()
+        
+    [<Test>]
+    member this.Concat() =
+         // integer Seq
+        let seqInt = 
+            seq { for i in 0..9 do                
+                    yield seq {for j in 0..9 do
+                                yield i*10+j}}
+        let conIntSeq = PSeq.concat seqInt
+        let expectedIntSeq = seq { for i in 0..99 do yield i}
+        
+        VerifyPSeqsEqual expectedIntSeq conIntSeq
+         
+        // string Seq
+        let strSeq = 
+            seq { for a in 'a' .. 'b' do
+                    for b in 'a' .. 'b' do
+                        yield seq [a; b] }
+     
+        let conStrSeq = PSeq.concat strSeq
+        let expectedStrSeq = seq ['a';'a';'a';'b';'b';'a';'b';'b';]
+        VerifyPSeqsEqual expectedStrSeq conStrSeq
+        
+//        // Empty Seq
+//        let emptySeqs = seq [seq[ PSeq.empty;PSeq.empty];seq[ PSeq.empty;PSeq.empty]]
+//        let conEmptySeq = PSeq.concat emptySeqs
+//        let expectedEmptySeq =seq { for i in 1..4 do yield PSeq.empty}
+//        
+//        VerifyPSeqsEqual expectedEmptySeq conEmptySeq   
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.concat nullSeq  |> ignore) 
+ 
+        () 
+        
+    [<Test>]
+    member this.CountBy() =
+        // integer Seq
+        let funcIntCount_by (x:int) = x%3 
+        let seqInt = 
+            seq { for i in 0..9 do                
+                    yield i}
+        let countIntSeq = PSeq.countBy funcIntCount_by seqInt
+         
+        let expectedIntSeq = seq [0,4;1,3;2,3]
+        
+        VerifyPSeqsEqual expectedIntSeq countIntSeq
+         
+        // string Seq
+        let funcStrCount_by (s:string) = s.IndexOf("key")
+        let strSeq = seq [ "key";"blank key";"key";"blank blank key"]
+       
+        let countStrSeq = PSeq.countBy funcStrCount_by strSeq
+        let expectedStrSeq = seq [0,2;6,1;12,1]
+        VerifyPSeqsEqual expectedStrSeq countStrSeq
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let countEmptySeq = PSeq.countBy funcIntCount_by emptySeq
+        let expectedEmptySeq =seq []
+        
+        VerifyPSeqsEqual expectedEmptySeq countEmptySeq  
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+       
+        CheckThrowsArgumentNullException (fun () -> PSeq.countBy funcIntCount_by nullSeq  |> ignore) 
+        () 
+    
+    [<Test>]
+    member this.Distinct() =
+        
+        // integer Seq
+        let IntDistinctSeq =  
+            seq { for i in 0..9 do                
+                    yield i % 3 }
+       
+        let DistinctIntSeq = PSeq.distinct IntDistinctSeq
+       
+        let expectedIntSeq = seq [0;1;2]
+        
+        VerifyPSeqsEqual expectedIntSeq DistinctIntSeq
+     
+        // string Seq
+        let strDistinctSeq = seq ["elementDup"; "ele1"; "ele2"; "elementDup"]
+       
+        let DistnctStrSeq = PSeq.distinct strDistinctSeq
+        let expectedStrSeq = seq ["elementDup"; "ele1"; "ele2"]
+        VerifyPSeqsEqual expectedStrSeq DistnctStrSeq
+
+        // array Seq
+        let arrDistinctSeq = seq [[|1|];[|1;2|]; [|1|];[|3|]]
+       
+        let DistnctArrSeq = PSeq.distinct arrDistinctSeq
+        let expectedArrSeq = seq [[|1|]; [|1; 2|]; [|3|]]
+        VerifyPSeqsEqual expectedArrSeq DistnctArrSeq
+        
+        
+        // Empty Seq
+        let emptySeq : pseq<decimal * unit>         = PSeq.empty
+        let distinctEmptySeq : pseq<decimal * unit> = PSeq.distinct emptySeq
+        let expectedEmptySeq : pseq<decimal * unit> = PSeq.ofList []
+       
+        VerifyPSeqsEqual expectedEmptySeq distinctEmptySeq
+
+        // null Seq
+        let nullSeq:seq<unit> = null
+       
+        CheckThrowsArgumentNullException(fun () -> PSeq.distinct nullSeq  |> ignore) 
+        () 
+    
+    [<Test>]
+    member this.DistinctBy () =
+        // integer Seq
+        let funcInt x = x % 3 
+        let IntDistinct_bySeq =  
+            seq { for i in 0..9 do                
+                    yield i }
+       
+        let distinct_byIntSeq = PSeq.distinctBy funcInt IntDistinct_bySeq
+        
+        Assert.AreEqual(3, PSeq.length distinct_byIntSeq )
+        
+        let mappedBack = distinct_byIntSeq |> PSeq.map funcInt
+
+        let expectedIntSeq = seq [0;1;2]
+        
+        VerifyPSeqsEqual expectedIntSeq mappedBack 
+             
+        // string Seq
+        let funcStrDistinct (s:string) = s.IndexOf("key")
+        let strSeq = seq [ "key"; "blank key"; "key dup"; "blank key dup"]
+       
+        let DistnctStrSeq = PSeq.distinctBy funcStrDistinct strSeq
+        let expectedStrSeq = seq ["key"; "blank key"]
+        VerifyPSeqsEqual expectedStrSeq DistnctStrSeq
+        
+        // Empty Seq
+        let emptySeq            : pseq<int> = PSeq.empty
+        let distinct_byEmptySeq : pseq<int> = PSeq.distinctBy funcInt emptySeq
+        let expectedEmptySeq    : pseq<int> = PSeq.ofList []
+       
+        VerifyPSeqsEqual expectedEmptySeq distinct_byEmptySeq
+
+        // null Seq
+        let nullSeq : seq<'a> = null
+       
+        CheckThrowsArgumentNullException(fun () -> PSeq.distinctBy funcInt nullSeq  |> ignore) 
+        () 
+    
+    [<Test>]
+    member this.Exists() =
+
+        // Integer Seq
+        let funcInt x = (x % 2 = 0) 
+        let IntexistsSeq =  
+            seq { for i in 0..9 do                
+                    yield i}
+       
+        let ifExistInt = PSeq.exists funcInt IntexistsSeq
+        
+        Assert.IsTrue( ifExistInt) 
+            
+        // String Seq
+        let funcStr (s:string) = s.Contains("key")
+        let strSeq = seq ["key"; "blank key"]
+       
+        let ifExistStr = PSeq.exists funcStr strSeq
+        
+        Assert.IsTrue( ifExistStr)
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let ifExistsEmpty = PSeq.exists funcInt emptySeq
+        
+        Assert.IsFalse( ifExistsEmpty)
+       
+        
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+           
+        CheckThrowsArgumentNullException (fun () -> PSeq.exists funcInt nullSeq |> ignore) 
+        () 
+    
+    [<Test>]
+    member this.Exists2() =
+        // Integer Seq
+        let funcInt x y = (x+y)%3=0 
+        let Intexists2Seq1 =  seq [1;3;7]
+        let Intexists2Seq2 = seq [1;6;3]
+            
+        let ifExist2Int = PSeq.exists2 funcInt Intexists2Seq1 Intexists2Seq2
+        Assert.IsTrue( ifExist2Int)
+             
+        // String Seq
+        let funcStr s1 s2 = ((s1 + s2) = "CombinedString")
+        let strSeq1 = seq [ "Combined"; "Not Combined"] |> PSeq.ordered
+        let strSeq2 = seq [ "String";   "Other String"] |> PSeq.ordered
+        let ifexists2Str = PSeq.exists2 funcStr strSeq1 strSeq2
+        Assert.IsTrue(ifexists2Str)
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let ifexists2Empty = PSeq.exists2 funcInt emptySeq emptySeq
+        Assert.IsFalse( ifexists2Empty)
+       
+        // null Seq
+        let nullSeq:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.exists2 funcInt nullSeq nullSeq |> ignore) 
+        () 
+    
+    
+    [<Test>]
+    member this.Filter() =
+        // integer Seq
+        let funcInt x = if (x % 5 = 0) then true else false
+        let IntSeq =
+            seq { for i in 1..20 do
+                    yield i }
+                    
+        let filterIntSeq = PSeq.filter funcInt IntSeq
+          
+        let expectedfilterInt = seq [ 5;10;15;20]
+        
+        VerifyPSeqsEqual expectedfilterInt filterIntSeq
+        
+        // string Seq
+        let funcStr (s:string) = s.Contains("Expected Content")
+        let strSeq = seq [ "Expected Content"; "Not Expected"; "Expected Content"; "Not Expected"]
+        
+        let filterStrSeq = PSeq.filter funcStr strSeq
+        
+        let expectedfilterStr = seq ["Expected Content"; "Expected Content"]
+        
+        VerifyPSeqsEqual expectedfilterStr filterStrSeq    
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let filterEmptySeq = PSeq.filter funcInt emptySeq
+        
+        let expectedEmptySeq =seq []
+       
+        VerifyPSeqsEqual expectedEmptySeq filterEmptySeq
+       
+        
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.filter funcInt nullSeq  |> ignore) 
+        () 
+    
+    [<Test>]
+    member this.Find() =
+        
+        // integer Seq
+        let funcInt x = if (x % 5 = 0) then true else false
+        let IntSeq =
+            seq { for i in 1..20 do
+                    yield i }
+                    
+        let findInt = PSeq.find funcInt IntSeq
+        Assert.AreEqual(findInt, 5)  
+             
+        // string Seq
+        let funcStr (s:string) = s.Contains("Expected Content")
+        let strSeq = seq [ "Expected Content";"Not Expected"]
+        
+        let findStr = PSeq.find funcStr strSeq
+        Assert.AreEqual(findStr, "Expected Content")
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.find funcInt emptySeq |> ignore)
+       
+        // null Seq
+        let nullSeq:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.find funcInt nullSeq |> ignore) 
+        ()
+    
+    [<Test>]
+    member this.FindIndex() =
+        
+        // integer Seq
+        let digits = [1 .. 100] |> PSeq.ofList
+        let idx = digits |> PSeq.findIndex (fun i -> i.ToString().Length > 1)
+        Assert.AreEqual(idx, 9)
+
+        // empty Seq 
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.findIndex (fun i -> true) PSeq.empty |> ignore)
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.findIndex (fun i -> true) null |> ignore)
+        ()
+    
+    [<Test>]
+    member this.Pick() =
+    
+        let digits = [| 1 .. 10 |] |> PSeq.ofArray
+        let result = PSeq.pick (fun i -> if i > 5 then Some(i.ToString()) else None) digits
+        Assert.AreEqual(result, "6")
+        
+        // Empty seq (Bugged, 4173)
+        CheckThrowsKeyNotFoundException (fun () -> PSeq.pick (fun i -> Some('a')) ([| |] : int[]) |> ignore)
+
+        // Null
+        CheckThrowsArgumentNullException (fun () -> PSeq.pick (fun i -> Some(i + 0)) null |> ignore)
+        ()
+        
+    [<Test>]
+    member this.Fold() =
+        let funcInt x y = x+y
+             
+        let IntSeq =
+            seq { for i in 1..10 do
+                    yield i}
+                    
+        let foldInt = PSeq.fold funcInt 1 IntSeq
+        if foldInt <> 56 then Assert.Fail()
+        
+        // string Seq
+        let funcStr (x:string) (y:string) = x+y
+        let strSeq = seq ["B"; "C";  "D" ; "E"]
+        let foldStr = PSeq.fold  funcStr "A" strSeq
+      
+        if foldStr <> "ABCDE" then Assert.Fail()
+        
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let foldEmpty = PSeq.fold funcInt 1 emptySeq
+        if foldEmpty <> 1 then Assert.Fail()
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.fold funcInt 1 nullSeq |> ignore) 
+        () 
+        
+    [<Test>]
+    member this.ForAll() =
+
+        let funcInt x  = if x%2 = 0 then true else false
+        let IntSeq =
+            seq { for i in 1..10 do
+                    yield i*2}
+        let for_allInt = PSeq.forall funcInt  IntSeq
+           
+        if for_allInt <> true then Assert.Fail()
+        
+             
+        // string Seq
+        let funcStr (x:string)  = x.Contains("a")
+        let strSeq = seq ["a"; "ab";  "abc" ; "abcd"]
+        let for_allStr = PSeq.forall  funcStr strSeq
+       
+        if for_allStr <> true then Assert.Fail()
+        
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let for_allEmpty = PSeq.forall funcInt emptySeq
+        
+        if for_allEmpty <> true then Assert.Fail()
+        
+        // null Seq
+        let nullSeq:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.forall funcInt  nullSeq |> ignore) 
+        () 
+        
+    [<Test>]
+    member this.ForAll2() =
+
+        let funcInt x y = if (x+y)%2 = 0 then true else false
+        let IntSeq =
+            seq { for i in 1..10 do
+                    yield i}
+            |> PSeq.ordered
+                    
+        let for_all2Int = PSeq.forall2 funcInt  IntSeq IntSeq
+           
+        if for_all2Int <> true then Assert.Fail()
+        
+        // string Seq
+        let funcStr (x:string) (y:string)  = (x+y).Length = 5
+        let strSeq1 = seq ["a"; "ab";  "abc" ; "abcd"] |> PSeq.ordered
+        let strSeq2 = seq ["abcd"; "abc";  "ab" ; "a"] |> PSeq.ordered
+        let for_all2Str = PSeq.forall2  funcStr strSeq1 strSeq2
+       
+        if for_all2Str <> true then Assert.Fail()
+        
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        let for_all2Empty = PSeq.forall2 funcInt emptySeq emptySeq
+        
+        if for_all2Empty <> true then Assert.Fail()
+
+        // null Seq
+        let nullSeq:seq<'a> = null
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.forall2 funcInt  nullSeq nullSeq |> ignore) 
+        
+    [<Test>]
+    member this.GroupBy() =
+        
+        let funcInt x = x%5
+             
+        let IntSeq =
+            seq { for i in 0 .. 9 do
+                    yield i }
+                    
+        let group_byInt = PSeq.groupBy funcInt IntSeq |> PSeq.map (fun (i, v) -> i, PSeq.toList v |> set)
+        
+        let expectedIntSeq = 
+            seq { for i in 0..4 do
+                     yield i, set [i; i+5] }
+                   
+        VerifyPSeqsEqual group_byInt expectedIntSeq
+             
+        // string Seq
+        let funcStr (x:string) = x.Length
+        let strSeq = seq ["length7"; "length 8";  "length7" ; "length  9"]
+        
+        let group_byStr = PSeq.groupBy  funcStr strSeq |> PSeq.map (fun (i, v) -> i, PSeq.toList v |> set)
+        let expectedStrSeq = 
+            seq {
+                yield 7, set ["length7"; "length7"]
+                yield 8, set ["length 8"]
+                yield 9, set ["length  9"] }
+       
+        VerifyPSeqsEqual expectedStrSeq group_byStr
+
+
+        // array keys
+        let funcStr (x:string) = x.ToCharArray() |> Array.filter (fun c -> Char.IsUpper(c))
+        let strSeq = seq ["Hello"; "Goodbye";  "Hello"; "How Are You?"]
+        
+        let group_byStr = PSeq.groupBy funcStr strSeq |> PSeq.map (fun (i, v) -> i, PSeq.toList v|> set)
+        let expectedStrSeq = 
+            seq {
+                yield [|'H'|], set ["Hello"; "Hello"]
+                yield [|'G'|], set ["Goodbye"]
+                yield [|'H';'A';'Y'|], set ["How Are You?"] }
+       
+        VerifyPSeqsEqual expectedStrSeq group_byStr
+
+        
+//        // Empty Seq
+//        let emptySeq = PSeq.empty
+//        let group_byEmpty = PSeq.groupBy funcInt emptySeq
+//        let expectedEmptySeq = seq []
+//
+//        VerifyPSeqsEqual expectedEmptySeq group_byEmpty
+        
+        // null Seq
+        let nullSeq:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.iter (fun _ -> ()) (PSeq.groupBy funcInt nullSeq)) 
+        () 
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests.v40/SeqModule2.fs b/workyard/linq/FSharp.PowerPack.Unittests.v40/SeqModule2.fs
new file mode 100644
index 0000000..6c12920
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests.v40/SeqModule2.fs
@@ -0,0 +1,1210 @@
+
+namespace FSharp.Core.Unittests.FSharp_Core.Microsoft_FSharp_Collections
+
+open System
+open NUnit.Framework
+open Microsoft.FSharp.Collections
+open FSharp.Core.Unittests.LibraryTestFx
+open System.Linq
+
+[<TestFixture>]
+type SeqModule2() =
+
+    [<Test>]
+    member this.Hd() =
+             
+        let IntSeq =
+            seq { for i in 0 .. 9 do
+                    yield i }
+                    
+        if PSeq.head IntSeq <> 0 then Assert.Fail()
+                 
+        // string Seq
+        let strSeq = seq ["first"; "second";  "third"]
+        if PSeq.head strSeq <> "first" then Assert.Fail()
+         
+        // Empty Seq
+        let emptySeq = PSeq.empty
+        CheckThrowsInvalidOperationExn ( fun() -> PSeq.head emptySeq)
+      
+        // null Seq
+        let nullSeq:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () ->PSeq.head nullSeq) 
+        () 
+        
+        
+    [<Test>]
+    member this.Init() =
+
+        let funcInt x = x
+        let init_finiteInt = PSeq.init 9 funcInt
+        let expectedIntSeq = seq [ 0..8]
+      
+        VerifyPSeqsEqual expectedIntSeq  init_finiteInt
+        
+             
+        // string Seq
+        let funcStr x = x.ToString()
+        let init_finiteStr = PSeq.init 5  funcStr
+        let expectedStrSeq = seq ["0";"1";"2";"3";"4"]
+
+        VerifyPSeqsEqual expectedStrSeq init_finiteStr
+        
+        // null Seq
+        let funcNull x = null
+        let init_finiteNull = PSeq.init 3 funcNull
+        let expectedNullSeq = seq [ null;null;null]
+        
+        VerifyPSeqsEqual expectedNullSeq init_finiteNull
+        () 
+        
+//    [<Test>]
+//    member this.InitInfinite() =
+//
+//        let funcInt x = x
+//        let init_infiniteInt = PSeq.initInfinite funcInt
+//        let resultint = PSeq.find (fun x -> x =100) init_infiniteInt
+//        
+//        Assert.AreEqual(100,resultint)
+//        
+//             
+//        // string Seq
+//        let funcStr x = x.ToString()
+//        let init_infiniteStr = PSeq.initInfinite  funcStr
+//        let resultstr = PSeq.find (fun x -> x = "100") init_infiniteStr
+//        
+//        Assert.AreEqual("100",resultstr)
+//       
+       
+    [<Test>]
+    member this.IsEmpty() =
+        
+        //seq int
+        let seqint = seq [1;2;3]
+        let is_emptyInt = PSeq.isEmpty seqint
+        
+        Assert.IsFalse(is_emptyInt)
+              
+        //seq str
+        let seqStr = seq["first";"second"]
+        let is_emptyStr = PSeq.isEmpty  seqStr
+
+        Assert.IsFalse(is_emptyInt)
+        
+        //seq empty
+        let seqEmpty = PSeq.empty
+        let is_emptyEmpty = PSeq.isEmpty  seqEmpty
+        Assert.IsTrue(is_emptyEmpty) 
+        
+        //seq null
+        let seqnull:seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.isEmpty seqnull |> ignore)
+        ()
+        
+    [<Test>]
+    member this.Iter() =
+//        //seq int
+//        let seqint =  seq [ 1..3]
+//        let cacheint = ref 0
+//       
+//        let funcint x = cacheint := !cacheint + x
+//        PSeq.iter funcint seqint
+//        Assert.AreEqual(6,!cacheint)
+//              
+//        //seq str
+//        let seqStr = seq ["first";"second"]
+//        let cachestr =ref ""
+//        let funcstr x = cachestr := !cachestr+x
+//        PSeq.iter funcstr seqStr
+//         
+//        Assert.AreEqual("firstsecond",!cachestr, sprintf "Not equal! firstsecond <> %A" !cachestr)
+        
+         // empty array    
+        let emptyseq = PSeq.empty
+        let resultEpt = ref 0
+        PSeq.iter (fun x -> Assert.Fail()) emptyseq   
+
+        // null seqay
+        let nullseq:seq<'a> =  null
+        
+        CheckThrowsArgumentNullException (fun () -> PSeq.iter (fun x -> ()) nullseq |> ignore)  
+        ()
+        
+    [<Test>]
+    member this.Iter2() =
+    
+//        //seq int
+//        let seqint =  seq [ 1..3]
+//        let cacheint = ref 0
+//       
+//        let funcint x y = cacheint := !cacheint + x+y
+//        PSeq.iter2 funcint seqint seqint
+//        Assert.AreEqual(12,!cacheint)
+//              
+//        //seq str
+//        let seqStr = seq ["first";"second"]
+//        let cachestr =ref ""
+//        let funcstr x y = cachestr := !cachestr+x+y
+//        PSeq.iter2 funcstr seqStr seqStr
+//         
+//        Assert.AreEqual("firstfirstsecondsecond",!cachestr)
+//        
+         // empty array    
+        let emptyseq = PSeq.empty
+        let resultEpt = ref 0
+        PSeq.iter2 (fun x y-> Assert.Fail()) emptyseq  emptyseq 
+
+        // null seqay
+        let nullseq:seq<'a> =  null
+        CheckThrowsArgumentNullException (fun () -> PSeq.iter2 (fun x y -> ()) nullseq nullseq |> ignore)  
+        
+        ()
+        
+    [<Test>]
+    member this.Iteri() =
+    
+//        // seq int
+//        let seqint =  seq [ 1..10]
+//        let cacheint = ref 0
+//       
+//        let funcint x y = cacheint := !cacheint + x+y
+//        PSeq.iteri funcint seqint
+//        Assert.AreEqual(100,!cacheint)
+//              
+//        // seq str
+//        let seqStr = seq ["first";"second"]
+//        let cachestr =ref 0
+//        let funcstr (x:int) (y:string) = cachestr := !cachestr+ x + y.Length
+//        PSeq.iteri funcstr seqStr
+//         
+//        Assert.AreEqual(12,!cachestr)
+//        
+//         // empty array    
+//        let emptyseq = PSeq.empty
+//        let resultEpt = ref 0
+//        PSeq.iteri funcint emptyseq
+//        Assert.AreEqual(0,!resultEpt)
+
+        // null seqay
+        let nullseq:seq<'a> =  null
+        CheckThrowsArgumentNullException (fun () -> PSeq.iteri (fun x i -> ()) nullseq |> ignore)  
+        ()
+        
+    [<Test>]
+    member this.Length() =
+
+         // integer seq  
+        let resultInt = PSeq.length {1..8}
+        if resultInt <> 8 then Assert.Fail()
+        
+        // string Seq    
+        let resultStr = PSeq.length (seq ["Lists"; "are";  "commonly" ; "list" ])
+        if resultStr <> 4 then Assert.Fail()
+        
+        // empty Seq     
+        let resultEpt = PSeq.length PSeq.empty
+        if resultEpt <> 0 then Assert.Fail()
+
+        // null Seq
+        let nullSeq:seq<'a> = null     
+        CheckThrowsArgumentNullException (fun () -> PSeq.length  nullSeq |> ignore)  
+        
+        ()
+        
+    [<Test>]
+    member this.Map() =
+
+         // integer Seq
+        let funcInt x = 
+                match x with
+                | _ when x % 2 = 0 -> 10*x            
+                | _ -> x
+       
+        let resultInt = PSeq.map funcInt { 1..10 }
+        let expectedint = seq [1;20;3;40;5;60;7;80;9;100]
+        
+        VerifyPSeqsEqual expectedint resultInt
+        
+        // string Seq
+        let funcStr (x:string) = x.ToLower()
+        let resultStr = PSeq.map funcStr (seq ["Lists"; "Are";  "Commonly" ; "List" ])
+        let expectedSeq = seq ["lists"; "are";  "commonly" ; "list"]
+        
+        VerifyPSeqsEqual expectedSeq resultStr
+        
+        // empty Seq
+        let resultEpt = PSeq.map funcInt PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+
+        // null Seq
+        let nullSeq:seq<'a> = null 
+        CheckThrowsArgumentNullException (fun () -> PSeq.map funcStr nullSeq |> ignore)
+        
+        ()
+        
+    [<Test>]
+    member this.Map2() =
+         // integer Seq
+        let funcInt x y = x+y
+        let resultInt = PSeq.map2 funcInt { 1..10 } {2..2..20} 
+        let expectedint = seq [3;6;9;12;15;18;21;24;27;30]
+        
+        VerifyPSeqsEqual expectedint resultInt
+        
+        // string Seq
+        let funcStr (x:int) (y:string) = x+y.Length
+        let resultStr = PSeq.map2 funcStr (seq[3;6;9;11]) (seq ["Lists"; "Are";  "Commonly" ; "List" ])
+        let expectedSeq = seq [8;9;17;15]
+        
+        VerifyPSeqsEqual expectedSeq resultStr
+        
+        // empty Seq
+        let resultEpt = PSeq.map2 funcInt PSeq.empty PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+
+        // null Seq
+        let nullSeq:seq<'a> = null 
+        let validSeq = seq [1]
+        CheckThrowsArgumentNullException (fun () -> PSeq.map2 funcInt nullSeq validSeq |> ignore)
+        
+        ()
+        
+        
+    member private this.MapWithSideEffectsTester (map : (int -> int) -> seq<int> -> pseq<int>) expectExceptions =
+        let i = ref 0
+        let f x = i := !i + 1; x*x
+        let e = ([1;2] |> map f).GetEnumerator()
+        
+        if expectExceptions then
+            CheckThrowsInvalidOperationExn  (fun _ -> e.Current|>ignore)
+            Assert.AreEqual(0, !i)
+        if not (e.MoveNext()) then Assert.Fail()
+        Assert.AreEqual(1, !i)
+        let _ = e.Current
+        Assert.AreEqual(1, !i)
+        let _ = e.Current
+        Assert.AreEqual(1, !i)
+        
+        if not (e.MoveNext()) then Assert.Fail()
+        Assert.AreEqual(2, !i)
+        let _ = e.Current
+        Assert.AreEqual(2, !i)
+        let _ = e.Current
+        Assert.AreEqual(2, !i)
+
+        if e.MoveNext() then Assert.Fail()
+        Assert.AreEqual(2, !i)
+        if expectExceptions then
+            CheckThrowsInvalidOperationExn (fun _ -> e.Current |> ignore)
+            Assert.AreEqual(2, !i)
+
+        
+        i := 0
+        let e = ([] |> map f).GetEnumerator()
+        if e.MoveNext() then Assert.Fail()
+        Assert.AreEqual(0,!i)
+        if e.MoveNext() then Assert.Fail()
+        Assert.AreEqual(0,!i)
+        
+        
+    member private this.MapWithExceptionTester (map : (int -> int) -> seq<int> -> pseq<int>) =
+        let raiser x = if x > 0 then raise(NotSupportedException()) else x
+        let raises = (map raiser [0; 1])
+        CheckThrowsAggregateException(fun _ -> PSeq.toArray raises |> ignore)
+       
+
+//    [<Test>]
+//    member this.MapWithSideEffects () =
+//        this.MapWithSideEffectsTester PSeq.map true
+        
+    [<Test>]
+    member this.MapWithException () =
+        this.MapWithExceptionTester PSeq.map
+
+        
+//    [<Test>]
+//    member this.SingletonCollectWithSideEffects () =
+//        this.MapWithSideEffectsTester (fun f-> PSeq.collect (f >> PSeq.singleton)) true
+        
+    [<Test>]
+    member this.SingletonCollectWithException () =
+        this.MapWithExceptionTester (fun f-> PSeq.collect (f >> PSeq.singleton))
+
+     
+//    [<Test>]
+//    member this.SystemLinqSelectWithSideEffects () =
+//        this.MapWithSideEffectsTester (fun f s -> System.Linq.ParallelEnumerable.Select(s.AsParallel(), Func<_,_>(f))) false
+//        
+    [<Test>]
+    member this.SystemLinqSelectWithException () =
+        this.MapWithExceptionTester (fun f s -> System.Linq.ParallelEnumerable.Select(s.AsParallel(), Func<_,_>(f)))
+
+        
+//    [<Test>]
+//    member this.MapiWithSideEffects () =
+//        let i = ref 0
+//        let f _ x = i := !i + 1; x*x
+//        let e = ([1;2] |> PSeq.mapi f).GetEnumerator()
+//        
+//        CheckThrowsInvalidOperationExn  (fun _ -> e.Current|>ignore)
+//        Assert.AreEqual(0, !i)
+//        if not (e.MoveNext()) then Assert.Fail()
+//        Assert.AreEqual(1, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(1, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(1, !i)
+//        
+//        if not (e.MoveNext()) then Assert.Fail()
+//        Assert.AreEqual(2, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(2, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(2, !i)
+//        
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(2, !i)
+//        CheckThrowsInvalidOperationExn  (fun _ -> e.Current|>ignore)
+//        Assert.AreEqual(2, !i)
+//        
+//        i := 0
+//        let e = ([] |> PSeq.mapi f).GetEnumerator()
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(0,!i)
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(0,!i)
+        
+//    [<Test>]
+//    member this.Map2WithSideEffects () =
+//        let i = ref 0
+//        let f x y = i := !i + 1; x*x
+//        let e = (PSeq.map2 f [1;2] [1;2]).GetEnumerator()
+//        
+//        CheckThrowsInvalidOperationExn  (fun _ -> e.Current|>ignore)
+//        Assert.AreEqual(0, !i)
+//        if not (e.MoveNext()) then Assert.Fail()
+//        Assert.AreEqual(1, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(1, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(1, !i)
+//        
+//        if not (e.MoveNext()) then Assert.Fail()
+//        Assert.AreEqual(2, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(2, !i)
+//        let _ = e.Current
+//        Assert.AreEqual(2, !i)
+//
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(2,!i)
+//        CheckThrowsInvalidOperationExn  (fun _ -> e.Current|>ignore)
+//        Assert.AreEqual(2, !i)
+//        
+//        i := 0
+//        let e = (PSeq.map2 f [] []).GetEnumerator()
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(0,!i)
+//        if e.MoveNext() then Assert.Fail()
+//        Assert.AreEqual(0,!i)
+        
+    [<Test>]
+    member this.Collect() =
+         // integer Seq
+        let funcInt x = seq [x+1]
+        let resultInt = PSeq.collect funcInt { 1..10 } 
+       
+        let expectedint = seq {2..11}
+        
+        VerifyPSeqsEqual expectedint resultInt
+        
+        // string Seq
+        let funcStr (y:string) = y+"ist"
+       
+        let resultStr = PSeq.collect funcStr (seq ["L"])
+        
+        
+        let expectedSeq = seq ['L';'i';'s';'t']
+        
+        VerifyPSeqsEqual expectedSeq resultStr
+        
+        // empty Seq
+        let resultEpt = PSeq.collect funcInt PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+
+        // null Seq
+        let nullSeq:seq<'a> = null 
+       
+        CheckThrowsArgumentNullException (fun () -> PSeq.collect funcInt nullSeq |> ignore)
+        
+        ()
+        
+    [<Test>]
+    member this.Mapi() =
+
+         // integer Seq
+        let funcInt x y = x+y
+        let resultInt = PSeq.mapi funcInt { 10..2..20 } 
+        let expectedint = seq [10;13;16;19;22;25]
+        
+        VerifyPSeqsEqual expectedint resultInt
+        
+        // string Seq
+        let funcStr (x:int) (y:string) =x+y.Length
+       
+        let resultStr = PSeq.mapi funcStr (seq ["Lists"; "Are";  "Commonly" ; "List" ])
+        let expectedStr = seq [5;4;10;7]
+         
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // empty Seq
+        let resultEpt = PSeq.mapi funcInt PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+
+        // null Seq
+        let nullSeq:seq<'a> = null 
+       
+        CheckThrowsArgumentNullException (fun () -> PSeq.mapi funcInt nullSeq |> ignore)
+        
+        ()
+        
+    [<Test>]
+    member this.Max() =
+        // integer Seq
+        let resultInt = PSeq.max { 10..20 } 
+        Assert.AreEqual(20,resultInt)
+
+
+        // integer64 Seq
+        let resultInt64 = PSeq.max { 10L..20L } 
+        Assert.AreEqual(20L,resultInt64)
+
+
+        // float Seq
+        let resultFloat = PSeq.max { 10.0..20.0 } 
+        Assert.AreEqual(20.0,resultFloat)
+
+        // float32 Seq
+        let resultFloat32 = PSeq.max { 10.0f..20.0f } 
+        Assert.AreEqual(20.0f,resultFloat32)
+
+        // decimal Seq
+        let resultDecimal = PSeq.max { (decimal 10)..(decimal 20) } 
+        Assert.AreEqual((decimal 20),resultDecimal)
+
+        // string Seq
+       
+        let resultStr = PSeq.max (seq ["Lists"; "Are";  "MaxString" ; "List" ])
+        Assert.AreEqual("MaxString",resultStr)
+          
+        // empty Seq
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.max ( PSeq.empty : pseq<float>) |> ignore)
+        
+        // null Seq
+        let nullSeq:seq<float> = null 
+        CheckThrowsArgumentNullException (fun () -> PSeq.max nullSeq |> ignore)
+        
+        ()
+        
+    [<Test>]
+    member this.MaxBy() =
+    
+        // integer Seq
+        let funcInt x = - (x % 18)
+        let resultInt = PSeq.maxBy funcInt { 2..2..20 } 
+        Assert.AreEqual(18,resultInt)
+        
+        // string Seq
+        let funcStr (x:string)  = x.Length 
+        let resultStr = PSeq.maxBy funcStr (seq ["Lists"; "Are";  "Commonly" ; "List" ])
+        Assert.AreEqual("Commonly",resultStr)
+         
+        // empty Seq
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.maxBy funcInt (PSeq.empty : pseq<int>) |> ignore)
+        
+        // null Seq
+        let nullSeq:seq<int> = null 
+        CheckThrowsArgumentNullException (fun () ->PSeq.maxBy funcInt nullSeq |> ignore)
+        
+
+        ()
+        
+    [<Test>]
+    member this.MinBy() =
+    
+        // integer Seq
+        let funcInt x = decimal(x % 18)
+        let resultInt = PSeq.minBy funcInt { 2..2..20 } 
+        Assert.AreEqual(18,resultInt)
+        
+        // string Seq
+        let funcStr (x:string)  = x.Length 
+        let resultStr = PSeq.minBy funcStr (seq ["Lists"; "Are";  "Commonly" ; "List" ])
+        Assert.AreEqual("Are",resultStr)
+          
+        // empty Seq
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.minBy funcInt (PSeq.empty : pseq<int>) |> ignore) 
+        
+        // null Seq
+        let nullSeq:seq<int> = null 
+        CheckThrowsArgumentNullException (fun () ->PSeq.minBy funcInt nullSeq |> ignore)
+        
+        ()
+        
+          
+    [<Test>]
+    member this.Min() =
+
+        // integer Seq
+        let resultInt = PSeq.min { 10..20 } 
+        Assert.AreEqual(10,resultInt)
+
+
+        // integer64 Seq
+        let resultInt64 = PSeq.min { 10L..20L } 
+        Assert.AreEqual(10L,resultInt64)
+
+
+        // float Seq
+        let resultFloat = PSeq.min { 10.0..20.0 } 
+        Assert.AreEqual(10.0,resultFloat)
+
+        // float32 Seq
+        let resultFloat32 = PSeq.min { 10.0f..20.0f } 
+        Assert.AreEqual(10.0f,resultFloat32)
+
+        // decimal Seq
+        let resultDecimal = PSeq.min { (decimal 10)..(decimal 20) } 
+        Assert.AreEqual((decimal 10),resultDecimal)
+
+        
+//        // string Seq
+//        let resultStr = PSeq.min (seq ["Lists"; "Are";  "minString" ; "List" ])
+//        Assert.AreEqual("Are",resultStr)
+          
+        // empty Seq
+        CheckThrowsInvalidOperationExn (fun () -> PSeq.min (PSeq.empty : pseq<int>) |> ignore) 
+        
+        // null Seq
+        let nullSeq:seq<float> = null 
+        CheckThrowsArgumentNullException (fun () -> PSeq.min nullSeq |> ignore)
+        
+        ()
+        
+    [<Test>]
+    member this.Nth() =
+         
+        // Negative index
+        for i = -1 downto -10 do
+           CheckThrowsArgumentException (fun () -> PSeq.nth i { 10 .. 20 } |> ignore)
+            
+        // Out of range
+        for i = 11 to 20 do
+           CheckThrowsArgumentException (fun () -> PSeq.nth i { 10 .. 20 } |> ignore)
+         
+         // integer Seq
+        let resultInt = PSeq.nth 3 { 10..20 } 
+        Assert.AreEqual(13, resultInt)
+        
+        // string Seq
+        let resultStr = PSeq.nth 3 (seq ["Lists"; "Are";  "nthString" ; "List" ])
+        Assert.AreEqual("List",resultStr)
+          
+        // empty Seq
+        CheckThrowsArgumentException(fun () -> PSeq.nth 0 (PSeq.empty : pseq<decimal>) |> ignore)
+       
+        // null Seq
+        let nullSeq:seq<'a> = null 
+        CheckThrowsArgumentNullException (fun () ->PSeq.nth 3 nullSeq |> ignore)
+        
+        ()
+         
+    [<Test>]
+    member this.Of_Array() =
+         // integer Seq
+        let resultInt = PSeq.ofArray [|1..10|]
+        let expectedInt = {1..10}
+         
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let resultStr = PSeq.ofArray [|"Lists"; "Are";  "ofArrayString" ; "List" |]
+        let expectedStr = seq ["Lists"; "Are";  "ofArrayString" ; "List" ]
+        VerifyPSeqsEqual expectedStr resultStr
+          
+        // empty Seq 
+        let resultEpt = PSeq.ofArray [| |] 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+       
+        ()
+        
+    [<Test>]
+    member this.Of_List() =
+         // integer Seq
+        let resultInt = PSeq.ofList [1..10]
+        let expectedInt = {1..10}
+         
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+       
+        let resultStr =PSeq.ofList ["Lists"; "Are";  "ofListString" ; "List" ]
+        let expectedStr = seq ["Lists"; "Are";  "ofListString" ; "List" ]
+        VerifyPSeqsEqual expectedStr resultStr
+          
+        // empty Seq 
+        let resultEpt = PSeq.ofList [] 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+        ()
+        
+          
+//    [<Test>]
+//    member this.Pairwise() =
+//         // integer Seq
+//        let resultInt = PSeq.pairwise {1..3}
+//       
+//        let expectedInt = seq [1,2;2,3]
+//         
+//        VerifyPSeqsEqual expectedInt resultInt
+//        
+//        // string Seq
+//        let resultStr =PSeq.pairwise ["str1"; "str2";"str3" ]
+//        let expectedStr = seq ["str1","str2";"str2","str3"]
+//        VerifyPSeqsEqual expectedStr resultStr
+//          
+//        // empty Seq 
+//        let resultEpt = PSeq.pairwise [] 
+//        VerifyPSeqsEqual resultEpt PSeq.empty
+//       
+//        ()
+        
+    [<Test>]
+    member this.Reduce() =
+         
+        // integer Seq
+        let resultInt = PSeq.reduce (fun x y -> x + y) (seq [5;4;3;2;1])
+        Assert.AreEqual(15,resultInt)
+        
+//        // string Seq
+//        let resultStr = PSeq.reduce (fun (x:string) (y:string) -> x.Remove(0,y.Length)) (seq ["ABCDE";"A"; "B";  "C" ; "D" ])
+//        Assert.AreEqual("E",resultStr) 
+       
+        // empty Seq 
+        CheckThrowsInvalidOperationExn(fun () -> PSeq.reduce (fun x y -> x/y)  PSeq.empty |> ignore)
+        
+        // null Seq
+        let nullSeq : seq<'a> = null
+        CheckThrowsArgumentNullException (fun () -> PSeq.reduce (fun (x:string) (y:string) -> x.Remove(0,y.Length))  nullSeq  |> ignore)   
+        ()
+
+         
+//    [<Test>]
+//    member this.Scan() =
+//        // integer Seq
+//        let funcInt x y = x+y
+//        let resultInt = PSeq.scan funcInt 9 {1..10}
+//        let expectedInt = seq [9;10;12;15;19;24;30;37;45;54;64]
+//        VerifyPSeqsEqual expectedInt resultInt
+//        
+//        // string Seq
+//        let funcStr x y = x+y
+//        let resultStr =PSeq.scan funcStr "x" ["str1"; "str2";"str3" ]
+//        
+//        let expectedStr = seq ["x";"xstr1"; "xstr1str2";"xstr1str2str3"]
+//        VerifyPSeqsEqual expectedStr resultStr
+//          
+//        // empty Seq 
+//        let resultEpt = PSeq.scan funcInt 5 PSeq.empty 
+//       
+//        VerifyPSeqsEqual resultEpt (seq [ 5])
+//       
+//        // null Seq
+//        let seqNull:seq<'a> = null
+//        CheckThrowsArgumentNullException(fun() -> PSeq.scan funcInt 5 seqNull |> ignore)
+//        ()
+        
+    [<Test>]
+    member this.Singleton() =
+        // integer Seq
+        let resultInt = PSeq.singleton 1
+       
+        let expectedInt = seq [1]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let resultStr =PSeq.singleton "str1"
+        let expectedStr = seq ["str1"]
+        VerifyPSeqsEqual expectedStr resultStr
+         
+        // null Seq
+        let resultNull = PSeq.singleton null
+        let expectedNull = seq [null]
+        VerifyPSeqsEqual expectedNull resultNull
+        ()
+    
+        
+    [<Test>]
+    member this.Skip() =
+    
+        // integer Seq
+        let resultInt = PSeq.skip 2 (seq [1;2;3;4])
+        let expectedInt = seq [3;4]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let resultStr =PSeq.skip 2 (seq ["str1";"str2";"str3";"str4"])
+        let expectedStr = seq ["str3";"str4"]
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // empty Seq 
+        let resultEpt = PSeq.skip 0 PSeq.empty 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+        
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.skip 1 null |> ignore)
+        ()
+       
+    [<Test>]
+    member this.Skip_While() =
+    
+        // integer Seq
+        let funcInt x = (x < 3)
+        let resultInt = PSeq.skipWhile funcInt (seq [1;2;3;4;5;6])
+        let expectedInt = seq [3;4;5;6]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let funcStr (x:string) = x.Contains(".")
+        let resultStr =PSeq.skipWhile funcStr (seq [".";"asdfasdf.asdfasdf";"";"";"";"";"";"";"";"";""])
+        let expectedStr = seq ["";"";"";"";"";"";"";"";""]
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // empty Seq 
+        let resultEpt = PSeq.skipWhile funcInt PSeq.empty 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+        
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.skipWhile funcInt null |> ignore)
+        ()
+       
+    [<Test>]
+    member this.Sort() =
+
+        // integer Seq
+        let resultInt = PSeq.sort (seq [1;3;2;4;6;5;7])
+        let expectedInt = {1..7}
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+       
+        let resultStr =PSeq.sort (seq ["str1";"str3";"str2";"str4"])
+        let expectedStr = seq ["str1";"str2";"str3";"str4"]
+        VerifyPSeqsEqual expectedStr resultStr
+
+        // array Seq
+       
+        let resultArray =PSeq.sort (seq [[|1;2|]; [|5|]; [|3;4|]; [|4|]])
+        let expectedArray = seq [[|4|]; [|5|]; [|1; 2|]; [|3; 4|]]
+        VerifyPSeqsEqual expectedArray resultArray
+        
+        // empty Seq 
+        let resultEpt = PSeq.sort PSeq.empty 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.sort null  |> ignore)
+        ()
+        
+    [<Test>]
+    member this.SortBy() =
+
+        // integer Seq
+        let funcInt x = Math.Abs(x-5)
+        let resultInt = PSeq.sortBy funcInt (seq [1;2;4;5;7])
+        let expectedInt = seq [5;4;7;2;1]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let funcStr (x:string) = x.IndexOf("key")
+        let resultStr =PSeq.sortBy funcStr (seq ["st(key)r";"str(key)";"s(key)tr";"(key)str"])
+        
+        let expectedStr = seq ["(key)str";"s(key)tr";"st(key)r";"str(key)"]
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // array Seq
+        let resultArray =PSeq.sortBy (Array.toList) (seq [[|1;2|]; [|5|]; [|3;4|]; [|4|]])
+        let expectedArray = seq [[|4|]; [|5|]; [|1; 2|]; [|3; 4|]]
+        VerifyPSeqsEqual expectedArray resultArray
+
+        // empty Seq 
+        let resultEpt = PSeq.sortBy funcInt PSeq.empty 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.sortBy funcInt null  |> ignore)
+        ()
+        
+    [<Test>]
+    member this.Sum() =
+    
+        // integer Seq
+        let resultInt = PSeq.sum (seq [1..10])
+        Assert.AreEqual(55,resultInt)
+
+        // int64 Seq
+        let resultInt64 = PSeq.sum (seq [1L..10L])
+        Assert.AreEqual(55L,resultInt64)
+        
+        // float32 Seq
+        let floatSeq = (seq [ 1.2f;3.5f;6.7f ])
+        let resultFloat = PSeq.sum floatSeq
+        if resultFloat <> 11.4f then Assert.Fail()
+        
+        // double Seq
+        let doubleSeq = (seq [ 1.0;8.0 ])
+        let resultDouble = PSeq.sum doubleSeq
+        if resultDouble <> 9.0 then Assert.Fail()
+        
+        // decimal Seq
+        let decimalSeq = (seq [ 0M;19M;19.03M ])
+        let resultDecimal = PSeq.sum decimalSeq
+        if resultDecimal <> 38.03M then Assert.Fail()      
+          
+      
+        // empty float32 Seq
+        let emptyFloatSeq = PSeq.empty<System.Single> 
+        let resultEptFloat = PSeq.sum emptyFloatSeq 
+        if resultEptFloat <> 0.0f then Assert.Fail()
+        
+        // empty double Seq
+        let emptyDoubleSeq = PSeq.empty<System.Double> 
+        let resultDouEmp = PSeq.sum emptyDoubleSeq 
+        if resultDouEmp <> 0.0 then Assert.Fail()
+        
+        // empty decimal Seq
+        let emptyDecimalSeq = PSeq.empty<System.Decimal> 
+        let resultDecEmp = PSeq.sum emptyDecimalSeq 
+        if resultDecEmp <> 0M then Assert.Fail()
+       
+        ()
+        
+    [<Test>]
+    member this.SumBy() =
+
+        // integer Seq
+        let resultInt = PSeq.sumBy (fun x -> x + 1) (seq [1..10])
+        Assert.AreEqual(65,resultInt)
+        
+        // int64 Seq
+        let resultInt64 = PSeq.sumBy int (seq [1L..10L])
+        Assert.AreEqual(55,resultInt64)
+
+        // float32 Seq
+        let floatSeq = (seq [ 1.2f;3.5f;6.7f ])
+        let resultFloat = PSeq.sumBy float32 floatSeq
+        if resultFloat <> 11.4f then Assert.Fail()
+        
+        // double Seq
+        let doubleSeq = (seq [ 1.0;8.0 ])
+        let resultDouble = PSeq.sumBy double doubleSeq
+        if resultDouble <> 9.0 then Assert.Fail()
+        
+        // decimal Seq
+        let decimalSeq = (seq [ 0M;19M;19.03M ])
+        let resultDecimal = PSeq.sumBy decimal decimalSeq
+        if resultDecimal <> 38.03M then Assert.Fail()      
+
+        // empty float32 Seq
+        let emptyFloatSeq = PSeq.empty<System.Single> 
+        let resultEptFloat = PSeq.sumBy float32 emptyFloatSeq 
+        if resultEptFloat <> 0.0f then Assert.Fail()
+        
+        // empty double Seq
+        let emptyDoubleSeq = PSeq.empty<System.Double> 
+        let resultDouEmp = PSeq.sumBy double emptyDoubleSeq 
+        if resultDouEmp <> 0.0 then Assert.Fail()
+        
+        // empty decimal Seq
+        let emptyDecimalSeq = PSeq.empty<System.Decimal> 
+        let resultDecEmp = PSeq.sumBy decimal emptyDecimalSeq 
+        if resultDecEmp <> 0M then Assert.Fail()
+       
+        ()
+        
+//    [<Test>]
+//    member this.Take() =
+//        // integer Seq
+//        
+//        let resultInt = PSeq.take 3 (seq [1;2;4;5;7])
+//       
+//        let expectedInt = seq [1;2;4]
+//        VerifyPSeqsEqual expectedInt resultInt
+//        
+//        // string Seq
+//       
+//        let resultStr =PSeq.take 2(seq ["str1";"str2";"str3";"str4"])
+//     
+//        let expectedStr = seq ["str1";"str2"]
+//        VerifyPSeqsEqual expectedStr resultStr
+//        
+//        // empty Seq 
+//        let resultEpt = PSeq.take 0 PSeq.empty 
+//      
+//        VerifyPSeqsEqual resultEpt PSeq.empty
+//        
+//         
+//        // null Seq
+//        CheckThrowsArgumentNullException(fun() -> PSeq.take 1 null |> ignore)
+//        ()
+        
+    [<Test>]
+    member this.takeWhile() =
+        // integer Seq
+        let funcInt x = (x < 6)
+        let resultInt = PSeq.takeWhile funcInt (seq [1;2;4;5;6;7])
+      
+        let expectedInt = seq [1;2;4;5]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let funcStr (x:string) = (x.Length < 4)
+        let resultStr =PSeq.takeWhile funcStr (seq ["a"; "ab"; "abc"; "abcd"; "abcde"])
+      
+        let expectedStr = seq ["a"; "ab"; "abc"]
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // empty Seq 
+        let resultEpt = PSeq.takeWhile funcInt PSeq.empty 
+        VerifyPSeqsEqual resultEpt PSeq.empty
+        
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.takeWhile funcInt null |> ignore)
+        ()
+        
+    [<Test>]
+    member this.To_Array() =
+        // integer Seq
+        let resultInt = PSeq.toArray(seq [1;2;4;5;7])
+     
+        let expectedInt = [|1;2;4;5;7|]
+        Assert.AreEqual(expectedInt,resultInt)
+        
+        // string Seq
+        let resultStr =PSeq.toArray (seq ["str1";"str2";"str3"])
+    
+        let expectedStr =  [|"str1";"str2";"str3"|]
+        Assert.AreEqual(expectedStr,resultStr)
+        
+        // empty Seq 
+        let resultEpt = PSeq.toArray PSeq.empty 
+        Assert.AreEqual([||],resultEpt)
+        
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.toArray null |> ignore)
+        ()
+    
+    [<Test>]
+    member this.To_List() =
+        // integer Seq
+        let resultInt = PSeq.toList (seq [1;2;4;5;7])
+        let expectedInt = [1;2;4;5;7]
+        Assert.AreEqual(expectedInt,resultInt)
+        
+        // string Seq
+        let resultStr =PSeq.toList (seq ["str1";"str2";"str3"])
+        let expectedStr =  ["str1";"str2";"str3"]
+        Assert.AreEqual(expectedStr,resultStr)
+        
+        // empty Seq 
+        let resultEpt = PSeq.toList PSeq.empty 
+        Assert.AreEqual([],resultEpt)
+         
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.toList null |> ignore)
+        ()
+        
+    [<Test>]
+    member this.Truncate() =
+        // integer Seq
+        let resultInt = PSeq.truncate 3 (seq [1;2;4;5;7])
+        let expectedInt = [1;2;4]
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let resultStr =PSeq.truncate 2 (seq ["str1";"str2";"str3"])
+        let expectedStr =  ["str1";"str2"]
+        VerifyPSeqsEqual expectedStr resultStr
+        
+        // empty Seq 
+        let resultEpt = PSeq.truncate 0 PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+        
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.truncate 1 null |> ignore)
+        ()
+        
+    [<Test>]
+    member this.tryFind() =
+        // integer Seq
+        let resultInt = PSeq.tryFind (fun x -> (x%2=0)) (seq [1;2;4;5;7])
+        Assert.AreEqual(Some(2), resultInt)
+        
+         // integer Seq - None
+        let resultInt = PSeq.tryFind (fun x -> (x%2=0)) (seq [1;3;5;7])
+        Assert.AreEqual(None, resultInt)
+        
+        // string Seq
+        let resultStr = PSeq.tryFind (fun (x:string) -> x.Contains("2")) (seq ["str1";"str2";"str3"])
+        Assert.AreEqual(Some("str2"),resultStr)
+        
+         // string Seq - None
+        let resultStr = PSeq.tryFind (fun (x:string) -> x.Contains("2")) (seq ["str1";"str4";"str3"])
+        Assert.AreEqual(None,resultStr)
+       
+        
+        // empty Seq 
+        let resultEpt = PSeq.tryFind (fun x -> (x%2=0)) PSeq.empty
+        Assert.AreEqual(None,resultEpt)
+
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.tryFind (fun x -> (x%2=0))  null |> ignore)
+        ()
+        
+    [<Test>]
+    member this.TryFindIndex() =
+
+        // integer Seq
+        let resultInt = PSeq.tryFindIndex (fun x -> (x % 5 = 0)) [8; 9; 10]
+        Assert.AreEqual(Some(2), resultInt)
+        
+         // integer Seq - None
+        let resultInt = PSeq.tryFindIndex (fun x -> (x % 5 = 0)) [9;3;11]
+        Assert.AreEqual(None, resultInt)
+        
+        // string Seq
+        let resultStr = PSeq.tryFindIndex (fun (x:string) -> x.Contains("2")) ["str1"; "str2"; "str3"]
+        Assert.AreEqual(Some(1),resultStr)
+        
+         // string Seq - None
+        let resultStr = PSeq.tryFindIndex (fun (x:string) -> x.Contains("2")) ["str1"; "str4"; "str3"]
+        Assert.AreEqual(None,resultStr)
+       
+        
+        // empty Seq 
+        let resultEpt = PSeq.tryFindIndex (fun x -> (x%2=0)) PSeq.empty
+        Assert.AreEqual(None, resultEpt)
+        
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.tryFindIndex (fun x -> (x % 2 = 0))  null |> ignore)
+        ()
+        
+//    [<Test>]
+//    member this.Unfold() =
+//        // integer Seq
+//        
+//        let resultInt = PSeq.unfold (fun x -> if x = 1 then Some(7,2) else  None) 1
+//        
+//        VerifyPSeqsEqual (seq [7]) resultInt
+//          
+//        // string Seq
+//        let resultStr =PSeq.unfold (fun (x:string) -> if x.Contains("unfold") then Some("a","b") else None) "unfold"
+//        VerifyPSeqsEqual (seq ["a"]) resultStr
+//        ()
+//        
+        
+//    [<Test>]
+//    member this.Windowed() =
+//        // integer Seq
+//        let resultInt = PSeq.windowed 5 (seq [1..10])
+//        let expectedInt = 
+//            seq { for i in 1..6 do
+//                    yield [| i; i+1; i+2; i+3; i+4 |] }
+//        VerifyPSeqsEqual expectedInt resultInt
+//        
+//        // string Seq
+//        let resultStr =PSeq.windowed 2 (seq ["str1";"str2";"str3";"str4"])
+//        let expectedStr = seq [ [|"str1";"str2"|];[|"str2";"str3"|];[|"str3";"str4"|]]
+//        VerifyPSeqsEqual expectedStr resultStr
+//      
+//        // empty Seq 
+//        let resultEpt = PSeq.windowed 2 PSeq.empty
+//        VerifyPSeqsEqual PSeq.empty resultEpt
+//          
+//        // null Seq
+//        CheckThrowsArgumentNullException(fun() -> PSeq.windowed 2 null |> ignore)
+//        ()
+        
+    [<Test>]
+    member this.Zip() =
+    
+        // integer Seq
+        let resultInt = PSeq.zip (seq [1..7]) (seq [11..17])
+        let expectedInt = 
+            seq { for i in 1..7 do
+                    yield i, i+10 }
+        VerifyPSeqsEqual expectedInt resultInt
+        
+        // string Seq
+        let resultStr =PSeq.zip (seq ["str3";"str4"]) (seq ["str1";"str2"])
+        let expectedStr = seq ["str3","str1";"str4","str2"]
+        VerifyPSeqsEqual expectedStr resultStr
+      
+        // empty Seq 
+        let resultEpt = PSeq.zip PSeq.empty PSeq.empty
+        VerifyPSeqsEqual PSeq.empty resultEpt
+          
+        // null Seq
+        CheckThrowsArgumentNullException(fun() -> PSeq.zip null null |> ignore)
+        CheckThrowsArgumentNullException(fun() -> PSeq.zip null (seq [1..7]) |> ignore)
+        CheckThrowsArgumentNullException(fun() -> PSeq.zip (seq [1..7]) null |> ignore)
+        ()
+        
+//    [<Test>]
+//    member this.Zip3() =
+//        // integer Seq
+//        let resultInt = PSeq.zip3 (seq [1..7]) (seq [11..17]) (seq [21..27])
+//        let expectedInt = 
+//            seq { for i in 1..7 do
+//                    yield i, (i + 10), (i + 20) }
+//        VerifyPSeqsEqual expectedInt resultInt
+//        
+//        // string Seq
+//        let resultStr =PSeq.zip3 (seq ["str1";"str2"]) (seq ["str11";"str12"]) (seq ["str21";"str22"])
+//        let expectedStr = seq ["str1","str11","str21";"str2","str12","str22" ]
+//        VerifyPSeqsEqual expectedStr resultStr
+//      
+//        // empty Seq 
+//        let resultEpt = PSeq.zip3 PSeq.empty PSeq.empty PSeq.empty
+//        VerifyPSeqsEqual PSeq.empty resultEpt
+//          
+//        // null Seq
+//        CheckThrowsArgumentNullException(fun() -> PSeq.zip3 null null null |> ignore)
+//        CheckThrowsArgumentNullException(fun() -> PSeq.zip3 null (seq [1..7]) (seq [1..7]) |> ignore)
+//        CheckThrowsArgumentNullException(fun() -> PSeq.zip3 (seq [1..7]) null (seq [1..7]) |> ignore)
+//        CheckThrowsArgumentNullException(fun() -> PSeq.zip3 (seq [1..7]) (seq [1..7]) null |> ignore)
+//        ()
+        
+//    [<Test>]
+//    member this.tryPick() =
+//         // integer Seq
+//        let resultInt = PSeq.tryPick (fun x-> if x = 1 then Some("got") else None) (seq [1..5])
+//         
+//        Assert.AreEqual(Some("got"),resultInt)
+//        
+//        // string Seq
+//        let resultStr = PSeq.tryPick (fun x-> if x = "Are" then Some("got") else None) (seq ["Lists"; "Are"])
+//        Assert.AreEqual(Some("got"),resultStr)
+//        
+//        // empty Seq   
+//        let resultEpt = PSeq.tryPick (fun x-> if x = 1 then Some("got") else None) PSeq.empty
+//        Assert.IsNull(resultEpt)
+//       
+//        // null Seq
+//        let nullSeq : seq<'a> = null 
+//        let funcNull x = Some(1)
+//        
+//        CheckThrowsArgumentNullException(fun () -> PSeq.tryPick funcNull nullSeq |> ignore)
+//   
+//        ()
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests.v40/Utilities.fs b/workyard/linq/FSharp.PowerPack.Unittests.v40/Utilities.fs
new file mode 100644
index 0000000..4e6d559
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests.v40/Utilities.fs
@@ -0,0 +1,129 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open System
+open System.Collections.Generic
+
+[<AutoOpen>]
+module Utilities = 
+    let test msg b = Assert.IsTrue(b, "MiniTest '" + msg + "'")
+    let logMessage msg = 
+        System.Console.WriteLine("LOG:" + msg)
+//        System.Diagnostics.Trace.WriteLine("LOG:" + msg)
+    let check msg v1 v2 = test msg (v1 = v2)
+    let checkEquals expected actual = 
+      Assert.AreSame(expected, actual) |> ignore
+    let checkContains v items = 
+      items |> Seq.exists ((=) v) |> Assert.IsTrue
+    let reportFailure msg = Assert.Fail msg
+    let numActiveEnumerators = ref 0
+    let throws f = try f() |> ignore; false with e -> true
+
+    let countEnumeratorsAndCheckedDisposedAtMostOnceAtEnd (seq: seq<'a>) =
+       let enumerator() = 
+                 numActiveEnumerators := !numActiveEnumerators + 1;
+                 let disposed = ref false in
+                 let endReached = ref false in
+                 let ie = seq.GetEnumerator() in
+                 { new System.Collections.Generic.IEnumerator<'a> with 
+                      member x.Current =
+                          test "rvlrve0" (not !endReached);
+                          test "rvlrve1" (not !disposed);
+                          ie.Current
+                      member x.Dispose() = 
+                          test "rvlrve2" !endReached;
+                          test "rvlrve4" (not !disposed);
+                          numActiveEnumerators := !numActiveEnumerators - 1;
+                          disposed := true;
+                          ie.Dispose() 
+                   interface System.Collections.IEnumerator with 
+                      member x.MoveNext() = 
+                          test "rvlrve0" (not !endReached);
+                          test "rvlrve3" (not !disposed);
+                          endReached := not (ie.MoveNext());
+                          not !endReached
+                      member x.Current = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          box ie.Current
+                      member x.Reset() = 
+                          ie.Reset()
+                   } in
+
+       { new seq<'a> with 
+             member x.GetEnumerator() =  enumerator() 
+         interface System.Collections.IEnumerable with 
+             member x.GetEnumerator() =  (enumerator() :> _) }
+
+    let countEnumeratorsAndCheckedDisposedAtMostOnce (seq: seq<'a>) =
+       let enumerator() = 
+                 let disposed = ref false in
+                 let endReached = ref false in
+                 let ie = seq.GetEnumerator() in
+                 numActiveEnumerators := !numActiveEnumerators + 1;
+                 { new System.Collections.Generic.IEnumerator<'a> with 
+                      member x.Current =
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          ie.Current
+                      member x.Dispose() = 
+                          test "qrvlrve4" (not !disposed);
+                          numActiveEnumerators := !numActiveEnumerators - 1;
+                          disposed := true;
+                          ie.Dispose() 
+                   interface System.Collections.IEnumerator with 
+                      member x.MoveNext() = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve3" (not !disposed);
+                          endReached := not (ie.MoveNext());
+                          not !endReached
+                      member x.Current = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          box ie.Current
+                      member x.Reset() = 
+                          ie.Reset()
+                   } in
+
+       { new seq<'a> with 
+             member x.GetEnumerator() =  enumerator() 
+         interface System.Collections.IEnumerable with 
+             member x.GetEnumerator() =  (enumerator() :> _) }
+
+    // Verifies two sequences are equal (same length, equiv elements)
+    let verifySeqsEqual seq1 seq2 =
+        if Seq.length seq1 <> Seq.length seq2 then Assert.Fail()
+        
+        let zippedElements = Seq.zip seq1 seq2
+        if zippedElements |> Seq.forall (fun (a, b) -> a = b) 
+        then ()
+        else Assert.Fail()
+        
+    /// Check that the lamda throws an exception of the given type. Otherwise
+    /// calls Assert.Fail()
+    let private checkThrowsExn<'a when 'a :> exn> (f : unit -> unit) =
+        let funcThrowsAsExpected =
+            try
+                let _ = f ()
+                false // Did not throw!
+            with
+            | :? 'a
+                -> true   // Thew null ref, OK
+            | _ -> false  // Did now throw a null ref exception!
+        if funcThrowsAsExpected
+        then ()
+        else Assert.Fail()
+
+    // Illegitimate exceptions. Once we've scrubbed the library, we should add an
+    // attribute to flag these exception's usage as a bug.
+    let checkThrowsNullRefException      f = checkThrowsExn<NullReferenceException>   f
+    let checkThrowsIndexOutRangException f = checkThrowsExn<IndexOutOfRangeException> f
+
+    // Legit exceptions
+    let checkThrowsNotSupportedException f = checkThrowsExn<NotSupportedException>    f
+    let checkThrowsArgumentException     f = checkThrowsExn<ArgumentException>        f
+    let checkThrowsArgumentNullException f = checkThrowsExn<ArgumentNullException>    f
+    let checkThrowsKeyNotFoundException  f = checkThrowsExn<KeyNotFoundException>     f
+    let checkThrowsDivideByZeroException f = checkThrowsExn<DivideByZeroException>    f
+    let checkThrowsInvalidOperationExn   f = checkThrowsExn<InvalidOperationException> f
+
+       
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/AsyncStreamReaderTest.fs b/workyard/linq/FSharp.PowerPack.Unittests/AsyncStreamReaderTest.fs
new file mode 100644
index 0000000..3bb29e6
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/AsyncStreamReaderTest.fs
@@ -0,0 +1,229 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open System
+open System.IO
+open System.Text
+
+[<TestFixture>]
+type AsyncStreamReaderTest() =
+    
+    let utf8Encoding : Encoding = downcast (new UTF8Encoding()).Clone()
+#if FX_NO_UTF32ENCODING
+#else
+    let utf32Encoding : Encoding = downcast (new UTF32Encoding()).Clone()
+#endif
+#if FX_NO_ASCII_ENCODING
+#else
+    let ASCIIEncoding : Encoding = downcast (new ASCIIEncoding()).Clone()
+    let win1251Encoding : Encoding = downcast (Encoding.GetEncoding("windows-1251")).Clone() // Russian
+#endif    
+    let encodings : (Encoding*bool) list = 
+        [   utf8Encoding, true; 
+#if FX_NO_UTF32ENCODING
+#else
+            utf32Encoding, true; 
+#endif
+#if FX_NO_ASCII_ENCODING
+#else
+            ASCIIEncoding,false; 
+            win1251Encoding,false
+#endif
+        ]
+#if FX_NO_ENCODER_FALLBACK    
+#else
+    do encodings |> List.iter (fun (e,_) -> e.EncoderFallback <- new EncoderExceptionFallback())
+#endif
+        
+        
+    let testAllEncodings (s:string) tester = 
+            for (e,detectable) in encodings do
+            let bytes, encodingOk =
+                try
+                    e.GetBytes(s), true
+                with
+                | :? EncoderFallbackException -> [| |], false
+            if encodingOk then
+                let ms = new MemoryStream(bytes)
+                let reader =  new AsyncStreamReader(ms, e)
+                tester reader (e.ToString())
+                if detectable then
+                    let preamble = e.GetPreamble()
+                    let newBytes = [preamble; bytes] |> Array.concat
+                    let ms = new MemoryStream(newBytes)
+                    let reader =  new AsyncStreamReader(ms)
+                    tester reader (sprintf "detectable %A" e)
+
+    let readToEndAndReadCharTest (s:string) =
+        testAllEncodings s
+            (fun (reader:AsyncStreamReader) encodingDescription ->
+                    let result = reader.ReadToEnd() |> Async.RunSynchronously
+                    Assert.AreEqual(s, result, (sprintf "ReadToEnd failure on %s" encodingDescription))
+                    Assert.IsTrue(reader.EndOfStream |> Async.RunSynchronously, "End of stream reached after ReadToEnd")
+                )
+        testAllEncodings s
+            (fun (reader:AsyncStreamReader) encodingDescription ->
+                let rec readAllChars =
+                    let sb = new StringBuilder()
+                    async {
+                        let! eof = reader.EndOfStream
+                        if eof then return sb.ToString()
+                        else
+                            let! c = reader.Read()
+                            sb.Append(c) |> ignore
+                            return! readAllChars
+                    }
+                let result = readAllChars |> Async.RunSynchronously
+                Assert.AreEqual(s, result, (sprintf "Read-all-charsToEnd failure on %s" encodingDescription))
+                Assert.IsTrue(reader.EndOfStream |> Async.RunSynchronously, "End of stream reached after ReadToEnd")
+            )
+        let readAllUsingBufferOfLength fdesc f n =
+            (fun (reader:AsyncStreamReader) encodingDescription ->
+                let rec readAllChars =
+                    let buffer = Array.create (2*n) ' '
+                    let sb = new StringBuilder()
+                    async {
+                        let! eof = reader.EndOfStream
+                        if eof then return sb.ToString()
+                        else
+                            let! count = f reader (buffer, 0, n)
+                            sb.Append(buffer, 0, count) |> ignore
+                            let! count = f reader (buffer, count, n)
+                            sb.Append(buffer, n, count) |> ignore
+                            return! readAllChars
+                    }
+                let result = readAllChars |> Async.RunSynchronously
+                Assert.AreEqual(s, result, (sprintf "%s buffer of length %d failure on %s" fdesc n encodingDescription))
+                Assert.IsTrue(reader.EndOfStream |> Async.RunSynchronously, sprintf "End of stream reached after %s using buffer of length %d" fdesc n)
+             )
+        for (fdesc,f) in [  "Read",         fun (reader:AsyncStreamReader) (buffer,index,count) -> reader.Read(buffer,index,count)
+                            "ReadExactly",  fun (reader:AsyncStreamReader) (buffer,index,count) -> reader.ReadExactly(buffer,index,count) ] do
+            testAllEncodings s (readAllUsingBufferOfLength fdesc f 1)
+            testAllEncodings s (readAllUsingBufferOfLength fdesc f 1024)
+            testAllEncodings s (readAllUsingBufferOfLength fdesc f 1999)
+            testAllEncodings s (readAllUsingBufferOfLength fdesc f s.Length)
+
+    let textBuilders =
+        [
+            yield "default separators",
+                fun (ss:string list) lastLine ->
+                    let sb = new StringBuilder()
+                    ss |> List.iter (fun s -> sb.AppendLine s |> ignore)
+                    sb.Append (lastLine:string) |> ignore
+                    sb.ToString()
+            for separator in ["\r"; "\n"; "\r\n"] do
+                yield separator.Replace("\r",@"\r").Replace("\n",@"\n"),
+                    fun (ss:string list) lastLine ->
+                        let sb = new StringBuilder()
+                        ss |> List.iter (fun s -> sb.Append s |> ignore; sb.Append separator |> ignore)
+                        sb.Append (lastLine:string) |> ignore
+                        sb.ToString()
+        ]
+   
+   
+    let readLinesTest (ss:string list) lastLine =
+        for (descr,textBuilder) in textBuilders do
+            testAllEncodings (textBuilder ss lastLine)
+                (fun (reader:AsyncStreamReader) encodingDescription ->
+                    let rec r acc = 
+                        async {
+                            let! eof = reader.EndOfStream
+                            if eof then return acc |> List.rev
+                            else
+                                let! nextLine = reader.ReadLine()
+                                return! r (nextLine::acc)
+                        }
+                    let result = r [] |> Async.RunSynchronously
+                    let expectedResult =
+                        if String.IsNullOrEmpty lastLine then ss else ss @ [lastLine]
+                            
+                    if expectedResult <> result then
+                        Assert.Fail(sprintf "ReadLinesTest: builder %s string list mismatch on %s" descr encodingDescription)
+                )
+    
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly on empty stream``() =
+        readToEndAndReadCharTest ""
+        
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly on short stream``() =
+        readToEndAndReadCharTest "fooBar"
+        
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly on multiple of buffer size``() =
+        let chars =
+            [| for i in 1..1024 do
+                    yield '0'
+                    yield '1'
+                    yield '2'
+            |] 
+        readToEndAndReadCharTest (new String(chars))
+
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly on non-multiple of buffer size``() =
+        let chars =
+            [| for i in 1..1024 do
+                    yield '0'
+                    yield '1'
+                    yield '2'
+               yield 'a'
+               yield 'b'
+            |] 
+        readToEndAndReadCharTest (new String(chars))
+        
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly on Russian chars``() =
+       readToEndAndReadCharTest "Однажды в студеную зимнюю пору\r\nЯ из лесу вышел\r\nБыл сильный мороз!"
+       
+    [<Test>]
+    member this.``ReadToEnd, Read and ReadExactly with surrogate codepoints``() =
+      let chars =
+        [| for i in 1..4096 do
+            yield 'a'
+            // surrogate pair
+            yield '\uD800' 
+            yield '\uDC00'
+        |]
+      readToEndAndReadCharTest (new String(chars))
+    
+    [<Test>]
+    member this.``ReadLine on empty file``() =
+        readLinesTest [] "" 
+    
+    [<Test>]
+    member this.``ReadLine with end on end of line``() =
+        readLinesTest ["a";"b";"c"] ""
+
+    [<Test>]
+    member this.``ReadLine with end not on end of line``() =
+        readLinesTest ["a";"b";"c"] "d"
+
+    [<Test>]
+    member this.``ReadLine with EOL mark starting at end-of-buffer``() =
+        readLinesTest
+            [ 
+                new String([|for i in 1..1024 do yield 'x'|])
+                new String([|for i in 1..1024 do yield 'y'|])
+                new String([|for i in 1..1024 do yield 'z'|])
+            ]
+            ""
+
+    [<Test>]
+    member this.``ReadLine with EOL mark breaking at end-of-buffer``() =
+        readLinesTest
+            [ 
+                new String([|for i in 1..1023 do yield 'x'|])
+                new String([|for i in 1..1022 do yield 'y'|])
+                new String([|for i in 1..1022 do yield 'z'|])
+            ]
+            ""
+
+    [<Test>]
+    member this.``ReadLine with EOL mark ending at end-of-buffer``() =
+        readLinesTest
+            [ 
+                new String([|for i in 1..1022 do yield 'x'|])
+                new String([|for i in 1..1022 do yield 'y'|])
+                new String([|for i in 1..1022 do yield 'z'|])
+            ]
+            ""
+
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/BigRationalTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/BigRationalTests.fs
new file mode 100644
index 0000000..c026497
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/BigRationalTests.fs
@@ -0,0 +1,611 @@
+
+namespace FSharp.PowerPack.Unittests
+
+open NUnit.Framework
+open System
+open System.Collections
+open System.Collections.Generic
+open System.Numerics
+
+
+[<TestFixture>]
+type public BigRationalTests() =
+
+    // BigRational Tests
+    // =================
+
+    // Notes: What cases to consider?
+    //   For (p,q) cases q=0, q=1, q<>1. [UPDATE: remove (x,0)]
+    //   For (p,q) when q=1 there could be 2 internal representations, either Z or Q.
+    //   For (p,0) this value can be signed, corresponds to +/- infinity point. [Update: remove it]
+    // Hashes on (p,1) for both representations must agree.
+    // For binary operators, try for result with and without HCF (normalisation).
+    // Also: 0/0 is an acceptable representation. See normalisation code. [Update: remove it].
+
+    // Overrides to test:
+    // .ToString()
+    // .GetHashCode()
+    // .Equals()
+    // IComparable.CompareTo()
+
+    // Misc construction.
+    let natA  n   = BigRational.FromInt n       // internally Z
+    let natB  n   = (natA n / natA 7) * natA 7  // internally Q
+    let ratio p q = BigRational.FromInt p / BigRational.FromInt q
+    let (/%)  b c = BigRational.FromBigInt b / BigRational.FromBigInt c
+
+    // Misc test values
+    let q0 = natA 0
+    let q1 = natA 1
+    let q2 = natA 2
+    let q3 = natA 3
+    let q4 = natA 4
+    let q5 = natA 5
+    let minIntI = bigint System.Int32.MinValue
+    let maxIntI = bigint System.Int32.MaxValue
+    let ran = System.Random()
+    let nextZ n = bigint (ran.Next(n))
+
+    // A selection of test points.
+    let points =
+        // A selection of integer and reciprical points
+        let points =
+            [for i in -13I .. 13I -> i,1I] @
+            [for i in -13I .. 13I -> 1I,i]
+        // Exclude x/0
+        let points = [for p,q in points do if q <> 0I then yield p,q ] // PROPOSE: (q,0) never a valid Q value, filter them out of tests...
+        // Scale by various values, including into BigInt range
+        let scale (kp,kq) (p,q) = (p*kp,q*kq)
+        let scales k pqs = List.map (scale k) pqs
+        let points = List.concat [points;
+                                  scales (10000I,1I) points;
+                                  scales (1I,10000I) points;
+                                  scales (maxIntI,1I) points;
+                                  scales (1I,maxIntI) points;
+                                 ]
+        points
+    let pointsNonZero = [for p,q in points do if p<>0I then yield p,q] // non zero points
+
+    let makeQs p q =     
+        if q = 1I && minIntI <= p && p <= maxIntI then
+            // (p,1) where p is int32
+            let p32 = int32 p
+            [natA p32;natB p32;BigRational.FromBigInt p]   // two reprs for int32 
+        else
+            [BigRational.FromBigInt p / BigRational.FromBigInt q]
+            
+    let miscQs = [for p,q in points do yield! makeQs p q]
+
+    let product xs ys = [for x in xs do for y in ys do yield x,y]
+    let vector1s = [for z in points -> z]
+    let vector2s = product points points
+
+    [<Test>]
+    member this.BasicTests1() = 
+        check "generic format h"  "1N" (sprintf "%A" 1N)
+        check "generic format q"  "-1N" (sprintf "%A" (-1N))
+
+        test "vliwe98"   (id -2N = - 2N)
+        test "d3oc002" (LanguagePrimitives.GenericZero<bignum> = 0N)
+        test "d3oc112w" (LanguagePrimitives.GenericOne<bignum> = 1N)
+
+        check "weioj3h" (sprintf "%O" 3N) "3" 
+        check "weioj3k" (sprintf "%O" (3N / 4N)) "3/4"
+        check "weioj3k" (sprintf "%O" (3N / 400000000N)) "3/400000000"
+        check "weioj3l" (sprintf "%O" (3N / 3N))  "1"
+        check "weioj3q" (sprintf "%O" (-3N))  "-3"
+        //check "weioj3w" (sprintf "%O" -3N) "-3"
+        check "weioj3e" (sprintf "%O" (-3N / -3N)) "1"
+
+        // The reason why we do not use hardcoded values is the the representation may change based on the NetFx we are targeting.
+        // For example, when targeting NetFx4.0, the result is "-3E+61" instead of "-3000....0N"
+        let v = -30000000000000000000000000000000000000000000000000000000000000N
+        check "weioj3r" (sprintf "%O" v) ((box v).ToString())
+
+  
+    [<Test>]
+    member this.BasicTests2() = 
+
+
+        // Test arithmetic ops: tests
+        let test2One name f check ((p,q),(pp,qq)) =     
+            // There may be several ways to construct the test rationals
+            let zs        = makeQs p  q
+            let zzs       = makeQs pp qq
+            let results   = [for z in zs do for zz in zzs do yield f (z,zz)]    
+            let refP,refQ = check (p,q) (pp,qq)    
+            let refResult = BigRational.FromBigInt refP / BigRational.FromBigInt refQ
+            let resOK (result:BigRational) = 
+                result.Numerator * refQ = refP * result.Denominator && 
+                BigRational.Equals(refResult,result)
+            match List.tryFind (fun result -> not (resOK result)) results with
+            | None        -> () // ok
+            | Some result -> printf "Test failed. %s (%A,%A) (%A,%A). Expected %A. Observed %A\n" name p q pp qq refResult result
+                             reportFailure "cejkew09"
+
+        let test2All name f check vectors = List.iter (test2One name f check) vectors
+
+        // Test arithmetic ops: call
+        test2All "add" (BigRational.(+))  (fun (p,q) (pp,qq) -> (p*qq + q*pp,q*qq)) vector2s
+        test2All "sub" (BigRational.(-))  (fun (p,q) (pp,qq) -> (p*qq - q*pp,q*qq)) vector2s
+        test2All "mul" (BigRational.(*))  (fun (p,q) (pp,qq) -> (p*pp,q*qq))        vector2s // *) <-- for EMACS
+        test2All "div" (BigRational.(/))  (fun (p,q) (pp,qq) -> (p*qq,q*pp))        (product points pointsNonZero)
+
+
+  
+    [<Test>]
+    member this.RangeTests() = 
+        // Test x0 .. dx .. x1
+        let checkRange3 (x0:BigRational) dx x1 k =
+            let f (x:BigRational) = x * BigRational.FromBigInt k |> BigRational.ToBigInt
+            let rangeA = {x0 .. dx .. x1} |> Seq.map f
+            let rangeB = {f x0 .. f dx .. f x1}
+            //printf "Length=%d\n" (Seq.length rangeA)
+            let same = Seq.forall2 (=) rangeA rangeB
+            check (sprintf "Range3 %A .. %A .. %A scaled to %A" x0 dx x1 k) same true
+            
+        checkRange3 (0I /% 1I)  (1I /% 7I) (100I /% 1I)  (7I*1I)
+        checkRange3 (0I /% 1I)  (1I /% 7I) (100I /% 11I) (7I*11I)
+        checkRange3 (1I /% 13I) (1I /% 7I) (100I /% 11I) (7I*11I*13I)
+        for i = 0 to 1000 do
+            let m = 1000 // max steps is -m to m in steps of 1/m i.e. 2.m^2
+            let p0,q0 = nextZ m     ,nextZ m + 1I
+            let p1,q1 = nextZ m     ,nextZ m + 1I
+            let pd,qd = nextZ m + 1I,nextZ m + 1I
+            checkRange3 (p0 /% q0) (pd /% qd) (p1 /% q1) (q0 * q1 * qd)
+
+
+        // Test x0 .. x1
+        let checkRange2 (x0:BigRational) x1 =
+            let z0  = BigRational.ToBigInt x0
+            let z01 = BigRational.ToBigInt (x1 - x0)    
+            let f (x:BigRational) = x |> BigRational.ToBigInt
+            let rangeA = [x0 .. x1] |> List.map f       // range with each item rounded down
+            let rangeB = [z0 .. z0 + z01]               // range of same length from the round down start point
+            check (sprintf "Range2: %A .. %A" x0 x1) rangeA rangeB
+
+        checkRange2 (0I /% 1I)  (100I /% 1I)  
+        checkRange2 (0I /% 1I)  (100I /% 11I) 
+        checkRange2 (1I /% 13I) (100I /% 11I) 
+        for i = 0 to 1000 do
+            let m = 10000 // max steps is -m to m in steps of 1 i.e. 2.m
+            let p0,q0 = nextZ m     ,nextZ m + 1I
+            let p1,q1 = nextZ m     ,nextZ m + 1I
+            checkRange2 (p0 /% q0) (p1 /% q1) //(q0 * q1 * qd)
+
+        // ToString()
+        // Cases: integer, computed integer, rational<1, rational>1, +/-infinity, nan
+        (natA 1).ToString()     |> check "ToString" "1" 
+        (natA 0).ToString()     |> check "ToString"  "0"
+        (natA (-12)).ToString() |> check "ToString" "-12"
+        (natB 1).ToString()     |> check "ToString" "1"
+        (natB 0).ToString()     |> check "ToString" "0"
+        (natB (-12)).ToString() |> check "ToString" "-12"
+        (1I /% 3I).ToString()   |> check "ToString" "1/3"
+        (12I /% 5I).ToString()  |> check "ToString" "12/5"
+        //(13I /% 0I).ToString()  |> check "ToString" "1/0"     // + 1/0. Plan to make this invalid value
+        //(-13I /% 0I).ToString() |> check "ToString" "1/0"     // - 1/0. Plan to make this invalid value
+        //(0I /% 0I).ToString()   |> check "ToString" "0/0"     //   0/0. Plan to make this invalid value
+
+        // GetHashCode
+        // Cases: zero, integer, computed integer, computed by multiple routes.
+        let checkSameHashGeneric a b                      = check (sprintf "GenericHash     %A %A" a b) (a.GetHashCode()) (b.GetHashCode())
+        let checkSameHash (a:BigRational) (b:BigRational) = check (sprintf "BigRationalHash %A %A" a b)  (a.GetHashCode()) (b.GetHashCode()); checkSameHashGeneric a b
+
+        List.iter (fun n -> checkSameHash (natA n) (natB n)) [-10 .. 10]
+        List.iter (fun n -> checkSameHash n ((n * q3 + n * q2) / q5)) miscQs
+
+        // bug 3488: should non-finite values be supported?
+        //let x = BigRational.FromBigInt (-1I) / BigRational.FromBigInt 0I
+        //let q2,q3,q5 = BigRational.FromInt 2,BigRational.FromInt 3,BigRational.FromInt 5
+        //let x2 = (x * q2 + x * q3) / q5
+        //x,x2,x = x2
+
+        // Test: Zero,One?
+        check "ZeroA" BigRational.Zero (natA 0)
+        check "ZeroA" BigRational.Zero (natA 0)
+        check "OneA"  BigRational.One  (natB 1)
+        check "OneB"  BigRational.One  (natB 1)
+
+    [<Test>]
+    member this.BinaryAndUnaryOperators() = 
+        // Test: generic bop
+        let testR2One name f check ((p,q),(pp,qq)) =     
+            // There may be several ways to construct the test rationals
+            let zs        = makeQs p  q
+            let zzs       = makeQs pp qq
+            let resultRef = check (p,q) (pp,qq) // : bool    
+            let args      = [for z in zs do for zz in zzs do yield (z,zz)]    
+            match List.tryFind (fun (z,zz) -> resultRef <> f (z,zz)) args with
+            | None        -> () // ok
+            | Some (z,zz) -> printf "Test failed. %s (%A,%A) (%A,%A) = %s %A %A. Expected %A.\n" name p q pp qq name z zz resultRef
+                             reportFailure "cknwe9"
+
+        // Test: generic uop
+        let testR1One name f check (p,q) =     
+            // There may be several ways to construct the test rationals
+            let zs        = makeQs p  q    
+            let resultRef = check (p,q) //: bool        
+            match List.tryFind (fun z -> resultRef <> f z) zs with
+            | None   -> () // ok
+            | Some z -> printf "Test failed. %s (%A,%A) = %s %A. Expected %A.\n" name p q name z resultRef
+                        reportFailure "vekjkrejvre0"
+                             
+        let testR2All name f check vectors = List.iter (testR2One name f check) vectors
+        let testR1All name f check vectors = List.iter (testR1One name f check) vectors
+
+        // Test: relations
+        let sign (i:BigInteger) = BigInteger(i.Sign)
+        testR2All "="  BigRational.(=)           (fun (p,q) (pp,qq) -> (p*qq =  q*pp)) vector2s
+        testR2All "="  BigRational.op_Equality   (fun (p,q) (pp,qq) -> (p*qq =  q*pp)) vector2s
+        testR2All "!=" BigRational.op_Inequality (fun (p,q) (pp,qq) -> (p*qq <> q*pp)) vector2s
+        //     p/q < pp/qq
+        // iff (p * sign q) / (q  * sign q)  < (pp * sign qq) / (qq * sign qq)
+        // iff (p * sign q) * (qq * sign qq) < (pp * sign qq) * (q  * sign q)           since q*sign q is always +ve.
+        testR2All "<"  BigRational.(<)  (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) < (pp * sign qq) * (q * sign q)) vector2s
+        testR2All ">"  BigRational.(>)  (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) > (pp * sign qq) * (q * sign q)) vector2s
+        testR2All "<=" BigRational.(<=) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) <= (pp * sign qq) * (q * sign q)) vector2s
+        testR2All ">=" BigRational.(>=) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) >= (pp * sign qq) * (q * sign q)) vector2s
+
+        // System.IComparable tests
+        let BigRationalCompareTo (p:BigRational,q:BigRational) = (p :> System.IComparable).CompareTo(q)
+        testR2All "IComparable.CompareTo" BigRationalCompareTo (fun (p,q) (pp,qq) -> compare ((p * sign q) * (qq * sign qq)) ((pp * sign qq) * (q * sign q))) vector2s
+
+        // Test: is negative, is positive
+        testR1All "IsNegative" (fun (x:BigRational) -> x.IsNegative) (fun (p,q) -> sign p * sign q = -1I) vector1s
+        testR1All "IsPositive" (fun (x:BigRational) -> x.IsPositive) (fun (p,q) -> sign p * sign q =  1I) vector1s
+        testR1All "IsZero"     (fun (x:BigRational) -> x = q0)       (fun (p,q) -> sign p = 0I)           vector1s
+
+
+        let test1One name f check (p,q) =     
+            // There may be several ways to construct the test rationals
+            let zs        = makeQs p  q    
+            let results   = [for z in zs -> f z]
+            let refP,refQ = check (p,q)   
+            let refResult = BigRational.FromBigInt refP / BigRational.FromBigInt refQ
+            let resOK (result:BigRational) = 
+               result.Numerator * refQ = refP * result.Denominator && 
+               BigRational.Equals(refResult,result)
+            match List.tryFind (fun result -> not (resOK result)) results with
+            | None        -> () // ok
+            | Some result -> printf "Test failed. %s (%A,%A). Expected %A. Observed %A\n" name p q refResult result
+                             reportFailure "klcwe09wek"
+
+        let test1All name f check vectors = List.iter (test1One name f check) vectors
+  
+        test1All "neg" (BigRational.(~-)) (fun (p,q)         -> (-p,q))             vector1s
+        test1All "pos" (BigRational.(~+)) (fun (p,q)         -> (p,q))              vector1s // why have ~+ ???
+
+        // Test: Abs,Sign
+        test1All  "Abs"         (BigRational.Abs)     (fun (p,q) -> (abs p,abs q)) vector1s
+        testR1All "Sign"        (fun (x:BigRational) -> x.Sign)    (fun (p,q) -> check "NonZeroDenom" (sign q <> 0I) true; (sign p * sign q) |> int32) vector1s
+
+        // Test: PowN
+        test1All  "PowN(x,2)"   (fun x -> BigRational.PowN(x,2))   (fun (p,q) -> (p*p,q*q)) vector1s
+        test1All  "PowN(x,1)"   (fun x -> BigRational.PowN(x,1))   (fun (p,q) -> (p,q)) vector1s
+        test1All  "PowN(x,0)"   (fun x -> BigRational.PowN(x,0))   (fun (p,q) -> (1I,1I)) vector1s
+
+        // MatteoT: moved to numbersVS2008\test.ml
+        //test1All  "PowN(x,200)" (fun x -> BigRational.PowN(x,200)) (fun (p,q) -> (BigInteger.Pow(p,200I),BigInteger.Pow(q,200I))) vector1s
+
+        // MatteoT: moved to numbersVS2008\test.ml
+        //let powers = [0I .. 100I]
+        //powers |> List.iter (fun i -> test1All  "PowN(x,i)" (fun x -> BigRational.PowN(x,int i)) (fun (p,q) -> (BigInteger.Pow(p,i),BigInteger.Pow(q,i))) vector1s)
+
+        // Test: PowN with negative powers - expect exception
+        testR1All  "PowN(x,-1)"  (fun x -> throws (fun () -> BigRational.PowN(x,-1))) (fun (p,q) -> true) vector1s
+        testR1All  "PowN(x,-4)"  (fun x -> throws (fun () -> BigRational.PowN(x,-4))) (fun (p,q) -> true) vector1s
+
+
+
+[<TestFixture>]
+type BigNumType() =
+    let g_positive1 = 1000000000000000000000000000000000018N
+    let g_positive2 = 1000000000000000000000000000000000000N
+    let g_negative1 = -1000000000000000000000000000000000018N
+    let g_negative2 = -1000000000000000000000000000000000000N
+    let g_negative3 = -1000000000000000000000000000000000036N
+    let g_zero      = 0N
+    let g_normal    = 88N
+    let g_bigintpositive    = 1000000000000000000000000000000000018I
+    let g_bigintnegative    = -1000000000000000000000000000000000018I
+    
+    // Interfaces
+    [<Test>]
+    member this.IComparable() =        
+        // Legit IC
+        let ic = g_positive1 :> IComparable    
+        Assert.AreEqual(ic.CompareTo(g_positive1),0) 
+        checkThrowsArgumentException( fun () -> ic.CompareTo(g_bigintpositive) |> ignore)
+    
+    // Base class methods
+    [<Test>]
+    member this.ObjectToString() =
+    
+        // Currently the CLR 4.0 and CLR 2.0 behavior of BigInt.ToString is different, causing this test to fail.
+        
+        Assert.AreEqual(g_positive1.ToString(),
+                        "1000000000000000000000000000000000018")
+        Assert.AreEqual(g_zero.ToString(),"0") 
+        Assert.AreEqual(g_normal.ToString(),"88")
+        
+        
+    [<Test; Ignore("Bug 5286 - Differences between CLR 2.0 BigInt and CLR 4.0 BigInt")>]
+    member this.System_Object_GetHashCode() =
+        Assert.AreEqual(g_negative1.GetHashCode(),1210897093)
+        Assert.AreEqual(g_normal.GetHashCode(),89)
+        Assert.AreEqual(g_zero.GetHashCode(),1)
+        ()
+    
+    // Static methods    
+    [<Test>]
+    member this.Abs() =
+        Assert.AreEqual(bignum.Abs(g_negative1), g_positive1)
+        Assert.AreEqual(bignum.Abs(g_negative2), g_positive2)
+        Assert.AreEqual(bignum.Abs(g_positive1), g_positive1)
+        Assert.AreEqual(bignum.Abs(g_normal),    g_normal)
+        Assert.AreEqual(bignum.Abs(g_zero),      g_zero)
+        ()
+        
+    [<Test>]
+    member this.FromBigInt() =
+        Assert.AreEqual(bignum.FromBigInt(g_bigintpositive),
+                        g_positive1)
+        Assert.AreEqual(bignum.FromBigInt(g_bigintnegative),
+                        g_negative1)
+        Assert.AreEqual(bignum.FromBigInt(0I),g_zero)
+        Assert.AreEqual(bignum.FromBigInt(88I),g_normal)
+        ()
+    
+    [<Test>]
+    member this.FromInt() =
+        Assert.AreEqual(bignum.FromInt(2147483647),   2147483647N)
+        Assert.AreEqual(bignum.FromInt(-2147483648), -2147483648N)
+        Assert.AreEqual(bignum.FromInt(0),   0N)
+        Assert.AreEqual(bignum.FromInt(88), 88N)
+        ()
+        
+    [<Test>]
+    member this.One() =
+        Assert.AreEqual(bignum.One,1N)
+        ()
+    
+    [<Test>]
+    member this.Parse() =
+        Assert.AreEqual(bignum.Parse("100"),   100N)
+        Assert.AreEqual(bignum.Parse("-100"), -100N)
+        Assert.AreEqual(bignum.Parse("0"),     g_zero)
+        Assert.AreEqual(bignum.Parse("88"),    g_normal)
+        ()
+        
+    [<Test>]
+    member this.PowN() =
+        Assert.AreEqual(bignum.PowN(100N,2), 10000N)
+        Assert.AreEqual(bignum.PowN(-3N,3),  -27N)
+        Assert.AreEqual(bignum.PowN(g_zero,2147483647), 0N)
+        Assert.AreEqual(bignum.PowN(g_normal,0),        1N)
+        ()
+        
+        
+    [<Test>]
+    member this.Sign() =
+        Assert.AreEqual(g_positive1.Sign,  1)
+        Assert.AreEqual(g_negative1.Sign, -1)
+        Assert.AreEqual(g_zero.Sign,   0)
+        Assert.AreEqual(g_normal.Sign, 1)
+        ()
+        
+    
+        
+    [<Test>]
+    member this.ToBigInt() =
+        Assert.AreEqual(bignum.ToBigInt(g_positive1), g_bigintpositive)
+        Assert.AreEqual(bignum.ToBigInt(g_negative1), g_bigintnegative)
+        Assert.AreEqual(bignum.ToBigInt(g_zero),   0I)
+        Assert.AreEqual(bignum.ToBigInt(g_normal), 88I)
+        ()
+        
+    
+        
+    [<Test>]
+    member this.ToDouble() =
+        Assert.AreEqual(bignum.ToDouble(179769N*1000000000000000N),   1.79769E+20)
+        Assert.AreEqual(bignum.ToDouble(-179769N*1000000000000000N), -1.79769E+20)
+        Assert.AreEqual(bignum.ToDouble(0N),0.0)
+        Assert.AreEqual(bignum.ToDouble(88N),88.0)
+        Assert.AreEqual(double(179769N*1000000000000000N),   1.79769E+20)
+        Assert.AreEqual(double(-179769N*1000000000000000N), -1.79769E+20)
+        Assert.AreEqual(double(0N),0.0)
+        Assert.AreEqual(double(88N),88.0)
+        ()
+        
+        
+    [<Test>]
+    member this.ToInt32() =
+        Assert.AreEqual(bignum.ToInt32(2147483647N),   2147483647)
+        Assert.AreEqual(bignum.ToInt32(-2147483648N), -2147483648)
+        Assert.AreEqual(bignum.ToInt32(0N),  0)
+        Assert.AreEqual(bignum.ToInt32(88N), 88)
+        Assert.AreEqual(int32(2147483647N),   2147483647)
+        Assert.AreEqual(int32(-2147483648N), -2147483648)
+        Assert.AreEqual(int32(0N),  0)
+        Assert.AreEqual(int32(88N), 88)
+        
+    
+        
+    [<Test>]
+    member this.Zero() =
+        Assert.AreEqual(bignum.Zero,0N)
+        ()
+       
+    // operator methods  
+    [<Test>]
+    member this.test_op_Addition() =
+        
+        Assert.AreEqual(100N + 200N, 300N)
+        Assert.AreEqual((-100N) + (-200N), -300N)
+        Assert.AreEqual(g_positive1 + g_negative1, 0N)
+        Assert.AreEqual(g_zero + g_zero,0N)
+        Assert.AreEqual(g_normal + g_normal, 176N)
+        Assert.AreEqual(g_normal + g_normal, 176N)
+        ()
+        
+        
+        
+    [<Test>]
+    member this.test_op_Division() =
+        Assert.AreEqual(g_positive1 / g_positive1, 1N)
+        Assert.AreEqual(-100N / 2N, -50N)
+        Assert.AreEqual(g_zero / g_positive1, 0N)
+        ()
+        
+    [<Test>]
+    member this.test_op_Equality() =
+        
+        Assert.IsTrue((g_positive1 = g_positive1))
+        Assert.IsTrue((g_negative1 = g_negative1))
+        Assert.IsTrue((g_zero = g_zero))
+        Assert.IsTrue((g_normal = g_normal))
+        ()
+        
+    [<Test>]
+    member this.test_op_GreaterThan() = 
+        Assert.AreEqual((g_positive1 > g_positive2), true)
+        Assert.AreEqual((g_negative1 > g_negative2), false)
+        Assert.AreEqual((g_zero > g_zero), false)
+        Assert.AreEqual((g_normal > g_normal), false)
+        
+        
+        ()
+    [<Test>]
+    member this.test_op_GreaterThanOrEqual() = 
+        Assert.AreEqual((g_positive1 >= g_positive2), true)
+        Assert.AreEqual((g_positive2 >= g_positive1), false)                                             
+        Assert.AreEqual((g_negative1 >= g_negative1), true)
+        Assert.AreEqual((0N >= g_zero), true)
+        
+        ()
+    [<Test>]  
+    member this.test_op_LessThan() = 
+        Assert.AreEqual((g_positive1 < g_positive2), false)
+        Assert.AreEqual((g_negative1 < g_negative3), false)
+        Assert.AreEqual((0N < g_zero), false)
+        
+        ()
+    [<Test>]
+    member this.test_op_LessThanOrEqual() = 
+        Assert.AreEqual((g_positive1 <= g_positive2), false)
+        Assert.AreEqual((g_positive2 <= g_positive1), true)                                             
+        Assert.AreEqual((g_negative1 <= g_negative1), true)
+        Assert.AreEqual((0N <= g_zero), true)
+       
+        ()
+    
+    [<Test>]
+    member this.test_op_Multiply() = 
+        Assert.AreEqual(3N * 5N, 15N)
+        Assert.AreEqual((-3N) * (-5N), 15N)
+        Assert.AreEqual((-3N) * 5N, -15N)
+        Assert.AreEqual(0N * 5N, 0N)
+        
+        ()
+        
+    [<Test>]
+    member this.test_op_Range() = 
+        let resultPos = [0N .. 2N]
+        let seqPos    = [0N; 1N; 2N]                                                                
+        verifySeqsEqual resultPos seqPos
+        
+        let resultNeg = [-2N .. 0N]                                       
+        let seqNeg =  [-2N; -1N; 0N]  
+        verifySeqsEqual resultNeg seqNeg
+        
+        let resultSmall = [0N ..5N]
+        let seqSmall = [0N; 1N; 2N; 3N; 4N; 5N]        
+        verifySeqsEqual resultSmall seqSmall
+           
+        ()
+        
+        
+    [<Test>]
+    member this.test_op_RangeStep() = 
+        let resultPos = [0N .. 3N .. 6N]
+        let seqPos    = [0N; 3N; 6N]                                                                
+        verifySeqsEqual resultPos seqPos
+        
+        let resultNeg = [-6N .. 3N .. 0N]                                        
+        let seqNeg =  [-6N; -3N; 0N]  
+        verifySeqsEqual resultNeg seqNeg
+        
+        let resultSmall = [0N .. 3N .. 9N]
+        let seqSmall = [0N; 3N; 6N; 9N]        
+        verifySeqsEqual resultSmall seqSmall
+                   
+        ()
+        
+    [<Test>]
+    member this.test_op_Subtraction() = 
+        Assert.AreEqual(g_positive1 - g_positive2,18N)
+        Assert.AreEqual(g_negative1 - g_negative3,18N)
+        Assert.AreEqual(0N-g_positive1, g_negative1)
+        ()
+        
+    [<Test>]
+    member this.test_op_UnaryNegation() = 
+        Assert.AreEqual(-g_positive1, g_negative1)
+        Assert.AreEqual(-g_negative1, g_positive1)
+        Assert.AreEqual(-0N,0N) 
+        
+        ()
+        
+    [<Test>]
+    member this.test_op_UnaryPlus() = 
+        Assert.AreEqual(+g_positive1,g_positive1)
+        Assert.AreEqual(+g_negative1,g_negative1)
+        Assert.AreEqual(+0N, 0N)
+        
+        ()
+    
+    // instance methods
+    [<Test>]
+    member this.Denominator() = 
+        Assert.AreEqual(g_positive1.Denominator, 1I)
+        Assert.AreEqual(g_negative1.Denominator, 1I)
+        Assert.AreEqual(0N.Denominator, 1I)
+        
+        ()       
+    
+    [<Test>]
+    member this.IsNegative() = 
+        Assert.IsFalse(g_positive1.IsNegative)
+        Assert.IsTrue(g_negative1.IsNegative)
+
+        Assert.IsFalse( 0N.IsNegative)
+        Assert.IsFalse(-0N.IsNegative)
+        
+        () 
+        
+        
+    [<Test>]
+    member this.IsPositive() = 
+
+        Assert.IsTrue(g_positive1.IsPositive)
+        Assert.IsFalse(g_negative1.IsPositive)
+
+        Assert.IsFalse( 0N.IsPositive)
+        Assert.IsFalse(-0N.IsPositive)
+        
+        ()     
+        
+    [<Test>]
+    member this.Numerator() = 
+        Assert.AreEqual(g_positive1.Numerator, g_bigintpositive)
+        Assert.AreEqual(g_negative1.Numerator, g_bigintnegative)
+        Assert.AreEqual(0N.Numerator, 0I)
+        
+        ()  
+        
+    
+        
+        
+   
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/ColllectionTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/ColllectionTests.fs
new file mode 100644
index 0000000..179548e
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/ColllectionTests.fs
@@ -0,0 +1,185 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+
+
+[<TestFixture>]
+type public ResizeArrayTests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+        let ra = ResizeArray.ofList
+        let (=?) a b = ResizeArray.toList a = b
+
+        test "ra_exists2_a" <| ResizeArray.exists2 (=)
+            (ra [1; 2; 3; 4; 5; 6])
+            (ra [2; 3; 4; 5; 6; 6])
+
+        test "exists2_b" <| not (ResizeArray.exists2 (=)
+            (ra [1; 2; 3; 4; 5; 6])
+            (ra [2; 3; 4; 5; 6; 7]))
+
+        test "ra_findIndex_a"
+            (ResizeArray.findIndex (fun i -> i >= 4) (ra [0..10]) = 4)
+
+        test "ra_findIndex_b"
+            (try ResizeArray.findIndex (fun i -> i >= 20) (ra [0..10]) |> ignore; false
+             with _ -> true)
+       
+        test "ra_find_indexi_a"
+            (ResizeArray.findIndexi (=) (ra [1; 2; 3; 3; 2; 1]) = 3)
+
+        test "ra_find_indexi_b"
+            (try ResizeArray.findIndexi (=) (ra [1..10]) |> ignore; false
+             with _ -> true)
+
+        test "ra_forall2_a"
+            (ResizeArray.forall2 (=) (ra [1..10]) (ra [1..10]))
+
+        test "ra_forall2_b" <| not
+            (ResizeArray.forall2 (=) (ra [1;2;3;4;5]) (ra [1;2;3;0;5]))
+
+        test "ra_isEmpty_a"
+            (ResizeArray.isEmpty (ra []))
+
+        test "ra_isEmpty_b" <| not
+            (ResizeArray.isEmpty (ra [1; 2]))
+
+        test "ra_mapi2"
+            (ResizeArray.mapi2 (fun i j k -> i+j+k) (ra [1..10]) (ra [1..10]) =? [2..+3..29])
+
+        test "ra_mapi2_b"
+            (try ResizeArray.mapi2 (fun i j k -> i+j+k) (ra []) (ra [1..10]) |> ignore; false
+             with _ -> true)
+
+        let c = ref 0
+        ResizeArray.iteri2 (fun i j k -> c := !c+i+j+k) (ra [1;2;3]) (ra [10;20;30])
+        test "ra_iteri2" (!c = 6+60+3)
+
+        test "ra_singleton"
+            (ResizeArray.singleton 42 =? [42])
+
+        test "ra_zip"
+            (ResizeArray.zip (ra [1..10]) (ra [1..10]) =? [for i in 1..10 -> i, i])
+
+        let unzip1, unzip2 = ResizeArray.unzip <| ra [for i in 1..10 -> i, i+1]
+        test "ra_unzip" (unzip1 =? [1..10] && unzip2 =? [2..11])
+
+        test "ra_reduce_left"
+            (ResizeArray.reduce (+) (ra [2;2;2;2]) = 8)
+
+        test "ra_reduce_right"
+            (ResizeArray.reduceBack (+) (ra [2;2;2;2]) = 8)
+
+        test "ra_fold2"
+            (ResizeArray.fold2 (fun i j k -> i+j+k) 100 (ra [1;2;3]) (ra [1;2;3]) = 112)
+
+        test "ra_fold2_b"
+            (ResizeArray.fold2 (fun i j k -> i-j-k) 100 (ra [1;2;3]) (ra [1;2;3]) = 100-12)
+
+        test "ra_foldBack2"
+            (ResizeArray.foldBack2 (fun i j k -> i+j+k) (ra [1;2;3]) (ra [1;2;3]) 100 = 112)
+
+        test "ra_foldBack2_b"
+            (ResizeArray.foldBack2 (fun i j k -> k-i-j) (ra [1;2;3]) (ra [1;2;3]) 100 = 100-12)
+
+        test "ra_scan"
+            (ResizeArray.scan (+) 0 (ra [1..5]) =? [0; 1; 3; 6; 10; 15])
+
+        test "ra_scanBack"
+            (ResizeArray.scanBack (+) (ra [1..5]) 0 =? [15; 14; 12; 9; 5; 0])
+
+        test "ra_tryfind_index"
+            (ResizeArray.tryFindIndex (fun x -> x = 4) (ra [0..10]) = Some 4)
+
+        test "ra_tryfind_index_b"
+            (ResizeArray.tryFindIndex (fun x -> x = 42) (ra [0..10]) = None)
+
+        test "ra_tryfind_indexi"
+            (ResizeArray.tryFindIndexi (=) (ra [1;2;3;4;4;3;2;1]) = Some 4)
+
+        test "ra_tryfind_indexi_b"
+            (ResizeArray.tryFindIndexi (=) (ra [1..10]) = None)
+
+        c := -1
+        ResizeArray.iter (fun x -> incr c; test "ra_iter" (x = !c)) (ra [0..100])
+        test "ra_iter" (!c = 100)
+
+        test "ra_map"
+            (ra [1..100] |> ResizeArray.map ((+) 1) =? [2..101])
+
+        test "ra_mapi"
+            (ra [0..100] |> ResizeArray.mapi (+) =? [0..+2..200])
+
+        c := -1
+        ResizeArray.iteri (fun i x -> incr c; test "ra_iteri" (x = !c && i = !c)) (ra [0..100])
+        test "ra_iteri" (!c = 100)
+
+        test "ra_exists"
+            (ra [1..100] |> ResizeArray.exists ((=) 50))
+
+        test "ra_exists b" <| not
+            (ra [1..100] |> ResizeArray.exists ((=) 150))
+
+        test "ra_forall"
+            (ra [1..100] |> ResizeArray.forall (fun x -> x < 150))
+
+        test "ra_forall b" <| not
+            (ra [1..100] |> ResizeArray.forall (fun x -> x < 80))
+
+        test "ra_find"
+            (ra [1..100] |> ResizeArray.find (fun x -> x > 50) = 51)
+
+        test "ra_find b"
+            (try ra [1..100] |> ResizeArray.find (fun x -> x > 180) |> ignore; false
+             with _ -> true)
+
+        test "ra_first"
+            (ra [1..100] |> ResizeArray.tryPick (fun x -> if x > 50 then Some (x*x) else None) = Some (51*51))
+
+        test "ra_first b"
+            (ra [1..100] |> ResizeArray.tryPick (fun x -> None) = None)
+            
+        test "ra_first c"
+            (ra [] |> ResizeArray.tryPick (fun _ -> Some 42) = None)
+
+        test "ra_tryfind"
+            (ra [1..100] |> ResizeArray.tryFind (fun x -> x > 50) = Some 51)
+
+        test "ra_tryfind b"
+            (ra [1..100] |> ResizeArray.tryFind (fun x -> x > 180) = None)
+
+        c := -1
+        ResizeArray.iter2 (fun x y -> incr c; test "ra_iter2" (!c = x && !c = y)) (ra [0..100]) (ra [0..100])
+        test "ra_iter2" (!c = 100)
+
+        test "ra_map2"
+            (ResizeArray.map2 (+) (ra [0..100]) (ra [0..100]) =? [0..+2..200])
+
+        test "ra_choose"
+            (ResizeArray.choose (fun x -> if x % 2 = 0 then Some (x/2) else None) (ra [0..100]) =? [0..50])
+
+        test "ra_filter"
+            (ResizeArray.filter (fun x -> x % 2 = 0) (ra [0..100]) =? [0..+2..100])
+
+        test "ra_filter b"
+            (ResizeArray.filter (fun x -> false) (ra [0..100]) =? [])
+
+        test "ra_filter c"
+            (ResizeArray.filter (fun x -> true) (ra [0..100]) =? [0..100])
+
+        let p1, p2 = ResizeArray.partition (fun x -> x % 2 = 0) (ra [0..100])
+        test "ra_partition"
+            (p1 =? [0..+2..100] && p2 =? [1..+2..100])
+
+        test "ra_rev"
+            (ResizeArray.rev (ra [0..100]) =? [100..-1 ..0])
+
+        test "ra_rev b"
+            (ResizeArray.rev (ra [1]) =? [1])
+
+        test "ra_rev c"
+            (ResizeArray.rev (ra []) =? [])
+
+        test "ra_rev d"
+            (ResizeArray.rev (ra [1; 2]) =? [2; 1])
+
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/CompatTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/CompatTests.fs
new file mode 100644
index 0000000..aa3c31f
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/CompatTests.fs
@@ -0,0 +1,792 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open System.Collections.Generic
+
+exception Foo
+
+#nowarn "44"
+
+[<TestFixture>]
+type public ArrayTests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+        let test_mem () = 
+          test "array.contains a" (not (Array.contains 3 [| 1; 2; 4 |]))
+          test "array.contains b" (Array.contains 3 [| 1; 3; 4 |])
+
+        let test_make_matrix () = 
+          let arr = Array.createJaggedMatrix 2 3 6 in
+          test "test2931: sdvjk2" (arr.[0].[0] = 6);
+          test "test2931: sdvjk2" (arr.[0].[1] = 6);
+          test "test2931: sdvjk2" (arr.[0].[2] = 6);
+          test "test2931: sdvjk2" (arr.[1].[0] = 6);
+          test "test2931: sdvjk2" (arr.[1].[1] = 6);
+          test "test2931: sdvjk2" (arr.[1].[2] = 6);
+          arr.[0].[0] <- 5;
+          arr.[0].[1] <- 5;
+          arr.[0].[2] <- 5;
+          arr.[1].[0] <- 4;
+          arr.[1].[1] <- 5;
+          arr.[1].[2] <- 5;
+          test "test2931: sdvjk2" (arr.[1].[0] = 4)
+
+        test_make_matrix ()
+        test_mem ()
+
+[<TestFixture>]
+type public ``Byte``() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+
+      test "vwknjewv0" (Byte.zero = 0uy);
+      test "vwknjewv0"  (Byte.add 0uy Byte.one = Byte.one);
+      test  "vwknjewv0" (Byte.add Byte.one 0uy  = Byte.one);
+      test  "vwknjewv0" (Byte.sub Byte.one 0uy  = Byte.one);
+      test  "vwknjewv0" (Byte.sub Byte.one Byte.one  = 0uy);
+      for i = 0 to 255 do 
+        test  "vwknjewv0" (int (byte i) = i);
+      for i = 0 to 255 do 
+        test  "vwknjewv0" (byte i = byte i);
+      stdout.WriteLine "mul i 1";
+      for i = 0 to 255 do 
+        test  "vwknjewv0"  (Byte.mul (byte i) (byte 1) = byte i);
+      stdout.WriteLine "add";
+      for i = 0 to 255 do 
+        for j = 0 to 255 do 
+          test  "vwknjewv0"  (int (Byte.add (byte i) (byte j)) = ((i + j) % 256));
+      stdout.WriteLine "mul i 1";
+      for i = 0 to 49032 do 
+        test  "vwknjewv0"  (int (byte i) = (i % 256));
+      for i = 0 to 255 do 
+        test  "vwknjewv0"  (Byte.div (byte i) (byte 1) = byte i);
+      for i = 0 to 255 do 
+        test  "vwknjewv0"  (Byte.rem (byte i) (byte 1) = byte 0);
+      for i = 0 to 254 do 
+        test  "vwknjewv0"  (Byte.succ (byte i) = Byte.add (byte i) Byte.one);
+      for i = 1 to 255 do 
+        test  "vwknjewv0"  (Byte.pred (byte i) = Byte.sub (byte i) Byte.one);
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test  "vwknjewv0"  (int (Byte.logand (byte i) (byte j)) = (&&&) i j);
+      stdout.WriteLine "logor";
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test  "vwknjewv0"  (int (Byte.logor (byte i) (byte j)) = (|||) i j);
+      stdout.WriteLine "logxor";
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test  "vwknjewv0"  (int (Byte.logxor (byte i) (byte j)) = (^^^) i j);
+      stdout.WriteLine "lognot";
+      for i = 1 to 255 do 
+          test  "vwknjewv0"  (Byte.lognot (byte i) = byte (~~~ i))
+      stdout.WriteLine "shift_left";
+      for i = 0 to 255 do 
+        for j = 0 to 7 do 
+          test  "vwknjewv0"  (Byte.shift_left (byte i) j = byte ( i <<< j))
+      stdout.WriteLine "shift_right";
+      for i = 0 to 255 do 
+        for j = 0 to 7 do 
+          test  "vwknjewv0"  (Byte.shift_right (byte i) j = byte (i >>> j))
+      stdout.WriteLine "to_string";
+      for i = 0 to 255 do 
+          test  "vwknjewv0"  (Byte.to_string (byte i) = sprintf "%d" i)
+      stdout.WriteLine "of_string";
+      for i = 0 to 255 do 
+          test  "vwknjewv0"  (Byte.of_string (string i) = byte i)
+      stdout.WriteLine "done";
+      ()    
+
+
+[<TestFixture>]
+type public Int32Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+      test "test1" (Int32.zero = Int32.zero);
+      test "test2" (Int32.add Int32.zero Int32.one = Int32.one);
+      test "test3" (Int32.add Int32.one Int32.zero  = Int32.one);
+      test "test4" (Int32.sub Int32.one Int32.zero  = Int32.one);
+      test "test5" (Int32.sub Int32.one Int32.one  = Int32.zero);
+      for i = 0 to 255 do 
+        test "test6" (Int32.to_int (Int32.of_int i) = i);
+      done;
+      for i = 0 to 255 do 
+        test "test7" (Int32.of_int i = Int32.of_int i);
+      done;
+      stdout.WriteLine "mul i 1";
+      for i = 0 to 255 do 
+        test "test8" (Int32.mul (Int32.of_int i) (Int32.of_int 1) = Int32.of_int i);
+      done;
+      stdout.WriteLine "add";
+      for i = 0 to 255 do 
+        for j = 0 to 255 do 
+          test "test" (Int32.to_int (Int32.add (Int32.of_int i) (Int32.of_int j)) = (i + j));
+        done;
+      done;
+      stdout.WriteLine "constants: min_int"; stdout.Flush();
+      test "testq" (Int32.min_int = -2147483648);
+      test "testw" (Int32.min_int = -2147483647 - 1);
+
+      stdout.WriteLine "constants: max_int";stdout.Flush();
+      test "teste" (Int32.max_int = 2147483647);
+      test "testr" (Int32.max_int = 2147483646 + 1);
+
+      stdout.WriteLine "constants: string max_int";stdout.Flush();
+      test "testt" (string Int32.max_int = "2147483647");
+      test "testy" (string Int32.min_int = "-2147483648");
+      test "testu" (Int32.to_string Int32.max_int = "2147483647");
+      test "testi" (Int32.to_string Int32.min_int = "-2147483648");
+
+      stdout.WriteLine "constants: max_int - 10";stdout.Flush();
+      test "testa" (Int32.max_int - 10 = 2147483637);
+
+      stdout.WriteLine "min int";stdout.Flush();
+      for i = Int32.min_int to Int32.min_int + 10 do 
+        test "testb" (Int32.to_int (Int32.of_int i) = i);
+      done;
+      stdout.WriteLine "max int";stdout.Flush();
+      for i = Int32.max_int - 10 to Int32.max_int - 1 do 
+        test "testc" (Int32.to_int (Int32.of_int i) = i);
+      done;
+      stdout.WriteLine "div";
+      for i = 0 to 255 do 
+        test "testd" (Int32.div (Int32.of_int i) (Int32.of_int 1) = Int32.of_int i);
+      done;
+      for i = 0 to 255 do 
+        test "teste" (Int32.rem (Int32.of_int i) (Int32.of_int 1) = Int32.of_int 0);
+      done;
+      for i = 0 to 254 do 
+        test "testf" (Int32.succ (Int32.of_int i) = Int32.add (Int32.of_int i) Int32.one);
+      done;
+      for i = 1 to 255 do 
+        test "testg" (Int32.pred (Int32.of_int i) = Int32.sub (Int32.of_int i) Int32.one);
+      done;
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test "testh" (Int32.to_int (Int32.logand (Int32.of_int i) (Int32.of_int j)) = (i &&& j));
+        done;
+      done;
+      stdout.WriteLine "logor";
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test "testj" (Int32.to_int (Int32.logor (Int32.of_int i) (Int32.of_int j)) = (i ||| j));
+        done;
+      done;
+      stdout.WriteLine "logxor";
+      for i = 1 to 255 do 
+        for j = 1 to 255 do 
+          test "testkkh" (Int32.to_int (Int32.logxor (Int32.of_int i) (Int32.of_int j)) = (i ^^^ j));
+        done;
+      done;
+      stdout.WriteLine "lognot";
+      for i = 1 to 255 do 
+          test "testqf" (Int32.lognot (Int32.of_int i) = Int32.of_int (~~~i))
+      done;
+      stdout.WriteLine "shift_left";
+      for i = 0 to 255 do 
+        for j = 0 to 7 do 
+          test "testcr4" (Int32.shift_left (Int32.of_int i) j = Int32.of_int (i <<< j))
+        done;
+      done;
+      stdout.WriteLine "shift_right";
+      for i = 0 to 255 do 
+        for j = 0 to 7 do 
+          test "testvt3q" (Int32.shift_right (Int32.of_int i) j = Int32.of_int (i >>> j))
+        done;
+      done;
+      test "testqvt4" (Int32.shift_right 2 1 = 1);
+      test "testvq3t" (Int32.shift_right 4 2 = 1);
+      stdout.WriteLine "shift_right_logical";
+      for i = 0 to 255 do 
+        for j = 0 to 7 do 
+          test "testvq34" (Int32.shift_right_logical (Int32.of_int i) j = Int32.of_int (Pervasives.(lsr) i j))
+        done;
+      done;
+      test "testvq3t" (Int32.shift_right_logical 0xFFFFFFFF 1 = 0x7FFFFFFF);
+      stdout.WriteLine "shift_right_logical (1)";
+      test "testvq3" (Int32.shift_right_logical 0xFFFFFFF2 1 = 0x7FFFFFF9);
+      stdout.WriteLine "shift_right_logical (2)";
+      test "testqvt4" (Int32.shift_right_logical 0x7FFFFFF2 1 = 0x3FFFFFF9);
+      stdout.WriteLine "shift_right_logical (3) ";
+      test "testqv3t" (Int32.shift_right_logical 0xFFFFFFFF 2 = 0x3FFFFFFF);
+      stdout.WriteLine "shift_right_logical (4)";
+      test "testb4y5" (Int32.shift_right_logical 0x80000004 2 = 0x20000001);
+      stdout.WriteLine "to_string";
+      for i = 0 to 255 do 
+          test "testbsyet" (Int32.to_string (Int32.of_int i) = string i)
+      done;
+      stdout.WriteLine "of_string";
+      for i = 0 to 255 do 
+          test "testvq4" (Int32.of_string (string i) = Int32.of_int i)
+      done;
+      stdout.WriteLine "constants (hex)";
+      test "testv4w" (Int32.of_string "0x0" = 0);
+      test "testv35" (Int32.of_string "0x1" = 1);
+      test "testvq3" (Int32.of_string "0x2" = 2);
+      test "testv3qt" (Int32.of_string "0xa" = 10);
+      test "testbwy4" (Int32.of_string "0xff" = 255);
+      stdout.WriteLine "constants (octal)";
+      test "testb4y5" (Int32.of_string "0o0" = 0);
+      test "testb4y" (Int32.of_string "0o1" = 1);
+      test "testby4" (Int32.of_string "0o2" = 2);
+      test "testbw4y" (Int32.of_string "0o7" = 7);
+      test "testb45" (Int32.of_string "0o10" = 8);
+      test "testbw4" (Int32.of_string "0o777" = 7*64 + 7*8 + 7);
+      test "test67n" (Int32.of_string "0o111" = 64 + 8 + 1);
+      stdout.WriteLine "constants (binary)";
+      test "test34q" (Int32.of_string "0b0" = 0);
+      test "testn" (Int32.of_string "0b1" = 1);
+      test "tester" (Int32.of_string "0b10" = 2);
+      test "testeyn" (Int32.of_string "0b11" = 3);
+      test "testynr" (Int32.of_string "0b00000000" = 0);
+      test "testnea" (Int32.of_string "0b11111111" = 0xFF);
+      test "testneayr" (Int32.of_string "0b1111111100000000" = 0xFF00);
+      test "testne" (Int32.of_string "0b11111111000000001111111100000000" = 0xFF00FF00);
+      test "testnaey" (Int32.of_string "0b11111111111111111111111111111111" = 0xFFFFFFFF);
+      test "testny" (Int32.of_string "0x7fffffff" = Int32.max_int);
+
+[<TestFixture>]
+type public UInt32Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+      stdout.WriteLine "constants (hex, unit32)";
+      test "testv4w" (UInt32.of_string "0x0" = 0u);
+      test "testv35" (UInt32.of_string "0x1" = 1u);
+      test "testvq3" (UInt32.of_string "0x2" = 2u);
+      test "testv3qt" (UInt32.of_string "0xa" = 10u);
+      test "testbwy4" (UInt32.of_string "0xff" = 255u);
+      stdout.WriteLine "constants (octal, unit32)";
+      test "testb4y5" (UInt32.of_string "0o0" = 0u);
+      test "testb4y" (UInt32.of_string "0o1" = 1u);
+      test "testby4" (UInt32.of_string "0o2" = 2u);
+      test "testbw4y" (UInt32.of_string "0o7" = 7u);
+      test "testb45" (UInt32.of_string "0o10" = 8u);
+      test "testbw4" (UInt32.of_string "0o777" = 7u*64u + 7u*8u + 7u);
+      test "test67n" (UInt32.of_string "0o111" = 64u + 8u + 1u);
+      stdout.WriteLine "constants (binary, unit32)";
+
+      test "test34q" (UInt32.of_string "0b0" = 0u);
+      test "testn" (UInt32.of_string "0b1" = 1u);
+      test "tester" (UInt32.of_string "0b10" = 2u);
+      test "testeyn" (UInt32.of_string "0b11" = 3u);
+      test "testynr" (UInt32.of_string "0b00000000" = 0u);
+      test "testnea" (UInt32.of_string "0b11111111" = 0xFFu);
+      test "testneayr" (UInt32.of_string "0b1111111100000000" = 0xFF00u);
+
+      test "testne" (UInt32.of_string "0b11111111000000001111111100000000" = 0xFF00FF00u);
+      test "testnaey" (UInt32.of_string "0b11111111111111111111111111111111" = 0xFFFFFFFFu);
+      test "testny" (UInt32.of_string "0xffffffff" = UInt32.max_int);
+
+      stdout.WriteLine "constants (decimal)";
+      test "test" (Int32.of_string "2147483647" = Int32.max_int);
+      test "test" (Int32.of_string "-0x80000000" = Int32.min_int);
+      test "test" (Int32.of_string "-2147483648" = Int32.min_int);
+      stdout.WriteLine "done";
+      ()    
+
+[<TestFixture>]
+type public Int64Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+          test  "vwknw4vkl"  (Int64.zero = Int64.zero);
+          test  "vwknw4vkl"  (Int64.add Int64.zero Int64.one = Int64.one);
+          test  "vwknw4vkl"  (Int64.add Int64.one Int64.zero  = Int64.one);
+          test  "vwknw4vkl"  (Int64.sub Int64.one Int64.zero  = Int64.one);
+          test  "vwknw4vkl"  (Int64.sub Int64.one Int64.one  = Int64.zero);
+          for i = 0 to 255 do 
+            test  "vwknw4vkl"  (Int64.to_int (Int64.of_int i) = i);
+          done;
+          for i = 0 to 255 do 
+            test  "vwknw4vkl"  (Int64.of_int i = Int64.of_int i);
+          done;
+          stdout.WriteLine "mul i 1";
+          for i = 0 to 255 do 
+            test  "vwknw4vkl"  (Int64.mul (Int64.of_int i) (Int64.of_int 1) = Int64.of_int i);
+          done;
+          stdout.WriteLine "add";
+          for i = 0 to 255 do 
+            for j = 0 to 255 do 
+              test  "vwknw4vkl"  (Int64.to_int (Int64.add (Int64.of_int i) (Int64.of_int j)) = (i + j));
+            done;
+          done;
+          stdout.WriteLine "div";
+          for i = 0 to 255 do 
+            test  "vwknw4vkl"  (Int64.div (Int64.of_int i) (Int64.of_int 1) = Int64.of_int i);
+          done;
+          for i = 0 to 255 do 
+            test  "vwknw4vkl"  (Int64.rem (Int64.of_int i) (Int64.of_int 1) = Int64.of_int 0);
+          done;
+          for i = 0 to 254 do 
+            test  "vwknw4vkl"  (Int64.succ (Int64.of_int i) = Int64.add (Int64.of_int i) Int64.one);
+          done;
+          for i = 1 to 255 do 
+            test  "vwknw4vkl"  (Int64.pred (Int64.of_int i) = Int64.sub (Int64.of_int i) Int64.one);
+          done;
+          for i = 1 to 255 do 
+            for j = 1 to 255 do 
+              test  "vwknw4vkl"  (Int64.to_int (Int64.logand (Int64.of_int i) (Int64.of_int j)) = Pervasives.(land) i j);
+            done;
+          done;
+          stdout.WriteLine "logor";
+          for i = 1 to 255 do 
+            for j = 1 to 255 do 
+              test  "vwknw4vkl"  (Int64.to_int (Int64.logor (Int64.of_int i) (Int64.of_int j)) = Pervasives.(lor) i j);
+            done;
+          done;
+          stdout.WriteLine "logxor";
+          for i = 1 to 255 do 
+            for j = 1 to 255 do 
+              test  "vwknw4vkl"  (Int64.to_int (Int64.logxor (Int64.of_int i) (Int64.of_int j)) = i ^^^ j);
+            done;
+          done;
+          stdout.WriteLine "lognot";
+          for i = 1 to 255 do 
+              test  "vwknw4vkl"  (Int64.lognot (Int64.of_int i) = Int64.of_int (~~~ i))
+          done;
+        #if NOTAILCALLS // NOTAILCALLS <-> MONO
+        #else
+          stdout.WriteLine "shift_left";
+          for i = 0 to 255 do 
+            for j = 0 to 7 do 
+              test  "vwknw4vkl"  (Int64.shift_left (Int64.of_int i) j = Int64.of_int (i <<< j))
+            done;
+          done;
+          stdout.WriteLine "shift_right";
+          for i = 0 to 255 do 
+            for j = 0 to 7 do 
+              test  "vwknw4vkl"  (Int64.shift_right (Int64.of_int i) j = Int64.of_int (i >>> j))
+            done;
+          done;
+          stdout.WriteLine "shift_right_logical";
+          for i = 0 to 255 do 
+            for j = 0 to 7 do 
+              test  "vwknw4vkl"  (Int64.shift_right_logical (Int64.of_int i) j = Int64.of_int (Pervasives.(lsr) i j))
+            done;
+          done;
+        #endif
+          stdout.WriteLine "to_string";
+          for i = 0 to 255 do 
+              test  "vwknw4vkl"  (Int64.to_string (Int64.of_int i) = string i)
+          done;
+          stdout.WriteLine "of_string";
+          for i = 0 to 255 do 
+              test  "vwknw4vkl"  (Int64.of_string (string i) = Int64.of_int i)
+          done;
+          stdout.WriteLine "constants (hex)";
+          test  "vwknw4vkl"  (Int64.of_string "0x0" = 0L);
+          test  "vwknw4vkl"  (Int64.of_string "0x1" = 1L);
+          test  "vwknw4vkl"  (Int64.of_string "0x2" = 2L);
+          test  "vwknw4vkl"  (Int64.of_string "0xa" = 10L);
+          test  "vwknw4vkl"  (Int64.of_string "0xff" = 255L);
+          stdout.WriteLine "constants (octal)";
+          test  "vwknw4vkl"  (Int64.of_string "0o0" = 0L);
+          test  "vwknw4vkl"  (Int64.of_string "0o1" = 1L);
+          test  "vwknw4vkl"  (Int64.of_string "0o2" = 2L);
+          test  "vwknw4vkl"  (Int64.of_string "0o7" = 7L);
+          test  "vwknw4vkl"  (Int64.of_string "0o10" = 8L);
+          test  "vwknw4vkl"  (Int64.of_string "0o777" = 7L*64L + 7L*8L + 7L);
+          test  "vwknw4vkl"  (Int64.of_string "0o111" = 64L + 8L + 1L);
+          stdout.WriteLine "constants (binary)";
+          test  "vwknw4vkl"  (Int64.of_string "0b0" = 0L);
+          test  "vwknw4vkl"  (Int64.of_string "0b1" = 1L);
+          test  "vwknw4vkl"  (Int64.of_string "0b10" = 2L);
+          test  "vwknw4vkl"  (Int64.of_string "0b11" = 3L);
+          test  "vwknw4vkl"  (Int64.of_string "0b00000000" = 0L);
+          test  "vwknw4vkl"  (Int64.of_string "0b11111111" = 0xFFL);
+          test  "vwknw4vkl"  (Int64.of_string "0b1111111100000000" = 0xFF00L);
+          test  "vwknw4vkl"  (Int64.of_string "0b11111111000000001111111100000000" = 0xFF00FF00L);
+          test  "vwknw4vkl"  (Int64.of_string "0b11111111111111111111111111111111" = 0xFFFFFFFFL);
+          test  "vwknw4vkl"  (Int64.of_string "0b1111111100000000111111110000000011111111000000001111111100000000" = 0xFF00FF00FF00FF00L);
+          test  "vwknw4vkl"  (Int64.of_string "0b1111111111111111111111111111111111111111111111111111111111111111" = 0xFFFFFFFFFFFFFFFFL);
+
+          stdout.WriteLine "of_string: min_int";
+          test  "vwknw4vkl"  (Int64.of_string "-0x8000000000000000" = Int64.min_int);
+          test  "vwknw4vkl"  (Int64.of_string "-9223372036854775808" = Int64.min_int);
+          test  "vwknw4vkl"  (-9223372036854775808L = Int64.min_int);
+          stdout.WriteLine "done";
+
+          stdout.WriteLine "constants (hex, UInt64)";
+          test  "vwknw4vkl"  (UInt64.of_string "0x0" = 0UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0x1" = 1UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0x2" = 2UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0xa" = 10UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0xff" = 255UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0xffffffffffffffff" = UInt64.max_int);
+          
+          stdout.WriteLine "constants (octal, UInt64)";
+          test  "vwknw4vkl"  (UInt64.of_string "0o0" = 0UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o1" = 1UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o2" = 2UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o7" = 7UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o10" = 8UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o777" = 7UL*64UL + 7UL*8UL + 7UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0o111" = 64UL + 8UL + 1UL);
+          
+          stdout.WriteLine "constants (binary, UInt64)";
+          test  "vwknw4vkl"  (UInt64.of_string "0b0" = 0UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b1" = 1UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b10" = 2UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b11" = 3UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b00000000" = 0UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b11111111" = 0xFFUL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b1111111100000000" = 0xFF00UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b11111111000000001111111100000000" = 0xFF00FF00UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b11111111111111111111111111111111" = 0xFFFFFFFFUL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b1111111100000000111111110000000011111111000000001111111100000000" = 0xFF00FF00FF00FF00UL);
+          test  "vwknw4vkl"  (UInt64.of_string "0b1111111111111111111111111111111111111111111111111111111111111111" = 0xFFFFFFFFFFFFFFFFUL);
+
+          stdout.WriteLine "done";
+          ()    
+
+
+[<TestFixture>]
+type public ListCompatTests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+        test "List.tryfind_indexi" (List.tryFindIndex ((=) 4) [1;2;3;4;4;3;2;1] = Some 3)
+
+
+
+
+[<TestFixture>]
+type public PervasivesTests() =
+
+    [<Test>]
+    member this.ExceptionMappings() = 
+        check "exception mappings"  true (try int_of_string "A" |> ignore; false with Failure _ -> true | _ -> false)
+        check "exception mappings"  true (try float_of_string "A" |> ignore; false with Failure _ -> true | _ -> false)
+
+    [<Test>]
+    member this.BasicTests() = 
+        test "tefwiu32" (try raise Not_found with Not_found -> true | _ -> false)
+
+        test "tefw38vj" (try raise Out_of_memory with Out_of_memory -> true | _ -> false)
+
+        test "tefw93mvj" (try raise Division_by_zero with Division_by_zero -> true | _ -> false)
+
+        test "tefwfewevj" (try raise Stack_overflow with Stack_overflow -> true | _ -> false)
+
+        test "tefw9ifmevj" (try raise End_of_file with End_of_file -> true | _ -> false)
+
+        test "atefwiu32" (try raise Not_found with Out_of_memory | Division_by_zero | Stack_overflow | End_of_file -> false | Not_found -> true | _ -> false)
+
+        test "btefwiu32" (try raise Out_of_memory with Not_found | Division_by_zero | Stack_overflow | End_of_file -> false | Out_of_memory -> true | _ -> false)
+
+        test "ctefwiu32" (try raise Division_by_zero with Not_found | Out_of_memory | Stack_overflow | End_of_file -> false | Division_by_zero -> true | _ -> false)
+
+        test "dtefwiu32" (try raise Stack_overflow with Not_found | Out_of_memory | Division_by_zero | End_of_file -> false | Stack_overflow -> true | _ -> false)
+
+        test "etefwiu32" (try raise End_of_file with Not_found | Out_of_memory | Division_by_zero |  Stack_overflow -> false | End_of_file -> true | _ -> false)
+
+        test "ftefwiu32" (try raise Foo with Not_found | Out_of_memory | Division_by_zero |  Stack_overflow -> false | Foo -> true | _ -> false)
+
+
+  
+    [<Test>]
+    member this.IO_EndOfLine_Translations() = 
+
+        let checkFileContentsUsingVariousTechniques(filename) =
+            using (open_in_bin filename) (fun is -> 
+                let buf = Array.create 5 0uy in
+                check "cewjk1" (input is buf 0 5) 5;
+                check "cewjk2" buf [|104uy; 101uy; 108uy; 108uy; 111uy|];
+                check "cewjk3" (input is buf 0 2) 2;
+                check "cewjk4" buf [|13uy; 10uy; 108uy; 108uy; 111uy|]);
+
+            using (open_in_bin filename) (fun is2 -> 
+
+                check "cewjk5" (is2.Peek()) 104;
+                check "cewjk6" (is2.Read()) 104;
+                check "cewjk7" (is2.Read()) 101;
+                check "cewjk8" (is2.Read()) 108;
+                check "cewjk9" (is2.Read()) 108;
+                check "cewjk0" (is2.Read()) 111;
+                check "cewjkq" (is2.Read()) 13;
+                check "cewjkw" (is2.Read()) 10;
+                check "cewjke" (is2.Read()) (-1));
+
+            using (open_in_bin filename) (fun is3 -> 
+
+                check "cewjkr" (input_char is3) 'h';
+                check "cewjkt" (input_char is3) 'e';
+                check "cewjky" (input_char is3) 'l';
+                check "cewjku" (input_char is3) 'l';
+                check "cewjki" (input_char is3) 'o';
+                check "cewjko" (input_char is3) '\r';
+                check "cewjkp" (input_char is3) '\n';
+                check "cewjka" (try input_char is3 |> ignore; false with End_of_file -> true) true);
+
+            using (open_in_bin filename) (fun is4 -> 
+
+                let buf4 = Array.create 5 '0' in
+                check "cewjks" (input_chars is4 buf4 0 5) 5;
+                check "cewjkd" (buf4) [|'h'; 'e'; 'l'; 'l'; 'o'; |];
+                check "cewjkf" (input_chars is4 buf4 0 2) 2;
+                check "cewjkd" (buf4) [|'\r'; '\n'; 'l'; 'l'; 'o'; |];
+                check "cewjkh" (input_chars is4 buf4 0 2) 0);
+            
+            using (open_in filename) (fun is5 -> 
+
+                let buf5 = Array.create 5 0uy in
+                check "veswhek1" (input is5 buf5 0 5) 5;
+                check "veswhek2" buf5 [|104uy; 101uy; 108uy; 108uy; 111uy|];
+                check "veswhek3" (input is5 buf5 0 2)  2;
+                check "veswhek4" buf5 [|13uy; 10uy; 108uy; 108uy; 111uy|];
+                check "veswhek5" (input is5 buf5 0 2) 0);
+            
+
+            using (open_in filename) (fun is2 -> 
+
+                check "veswhek6" (is2.Peek()) 104;
+                check "veswhek7" (is2.Read()) 104;
+                check "veswhek8" (is2.Read()) 101;
+                check "veswhek9" (is2.Read()) 108;
+                check "veswhek0" (is2.Read()) 108;
+                check "veswhekq" (is2.Read()) 111;
+                check "veswhekw" (is2.Read()) 13;
+                check "veswheke" (is2.Read()) 10;
+                check "veswhekr" (is2.Read()) (-1));
+
+
+            using (open_in filename) (fun is3 -> 
+
+                check "veswhekt" (input_char is3) 'h';
+                check "veswheky" (input_char is3) 'e';
+                check "veswheku" (input_char is3) 'l';
+                check "veswheko" (input_char is3) 'l';
+                check "veswhekp" (input_char is3) 'o';
+                check "veswheka" (input_char is3) '\r';
+                check "veswheks" (input_char is3) '\n';
+                check "veswhekd" (try input_char is3 |> ignore; false with End_of_file -> true) true)
+
+        using (open_out_bin "test.txt") (fun os -> fprintf os "hello\r\n")
+        checkFileContentsUsingVariousTechniques("test.txt")
+        using (open_out "test.txt") (fun os -> fprintf os "hello\r\n")
+        checkFileContentsUsingVariousTechniques("test.txt")
+        using (open_out "test.txt") (fun os -> os.Write (let s = "hello\r\n" in Array.init s.Length (fun i -> s.[i]) ))
+        checkFileContentsUsingVariousTechniques("test.txt")
+        using (open_out_bin "test.txt") (fun os -> os.Write (let s = "hello\r\n" in Array.init s.Length (fun i -> s.[i]) ))
+        checkFileContentsUsingVariousTechniques("test.txt")
+        using (open_out "test.txt") (fun os -> os.Write "hello\r\n")
+        checkFileContentsUsingVariousTechniques("test.txt")
+        using (open_out_bin "test.txt") (fun os -> os.Write "hello\r\n")
+        checkFileContentsUsingVariousTechniques("test.txt")
+
+#if FX_NO_BINARY_SERIALIZATION
+#else
+    [<Test>]
+    member this.BinarySerialization() = 
+
+        (* Andrez:
+           It appears to me that writing the empty list into a binary channel does not work.
+        *)   
+          
+          let file = open_out_bin "test.txt" in
+          output_value file ([]: int list);
+          close_out file;
+          let file = open_in_bin "test.txt" in
+          if (input_value file : int list) <> [] then (reportFailure "wnwve0ljkvwe");
+          close_in file;
+#endif
+
+
+
+[<TestFixture>]
+type public Filename_Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+        check "Filename.dirname1"  "C:" (Filename.dirname "C:")
+        check "Filename.dirname2"  "C:\\" (Filename.dirname "C:\\")
+        check "Filename.dirname3"  "c:\\" (Filename.dirname "c:\\")
+        check "Filename.dirname2"  "C:/" (Filename.dirname "C:/")
+        check "Filename.dirname3"  "c:/" (Filename.dirname "c:/")
+        check "Filename.dirname4"  "." (Filename.dirname "")
+        check "Filename.dirname5"  "\\" (Filename.dirname "\\")
+        check "Filename.dirname6"  "." (Filename.dirname "a")
+        // F# and OCaml do return different results for this one.
+        // F# preserves the double slashes.  That seems fair enough 
+        // do check "Filename.dirname2"  "\\" (Filename.dirname "\\\\")
+
+        check "is_relative1"  false (Filename.is_relative "C:")
+        check "is_relative2"  false (Filename.is_relative "C:\\")
+        check "is_relative3"  false (Filename.is_relative "c:\\")
+        check "is_relative4"  false (Filename.is_relative "C:/")
+        check "is_relative5"  false (Filename.is_relative "c:/")
+        check "is_relative6"  true (Filename.is_relative "")
+        check "is_relative7"  true (Filename.is_relative ".")
+        check "is_relative8"  true (Filename.is_relative "a")
+        check "is_relative9"  false (Filename.is_relative "\\")
+        check "is_relative10"  false (Filename.is_relative "\\\\")
+
+        check "is_relative8"  true (Filename.is_implicit "a")
+        check "is_relative8"  false (Filename.is_implicit ".\\a")
+        check "is_relative8"  false (Filename.is_implicit "..\\a")
+
+        let has_extension (s:string) = 
+          (String.length s >= 1 && String.get s (String.length s - 1) = '.') 
+          || System.IO.Path.HasExtension(s)
+
+        check "has_extension 1"  false (has_extension "C:")
+        check "has_extension 2"  false (has_extension "C:\\")
+        check "has_extension 3"  false (has_extension "c:\\")
+        check "has_extension 4"  false (has_extension "")
+        check "has_extension 5"  true (has_extension ".")
+        check "has_extension 6"  false (has_extension "a")
+        check "has_extension 7"  true (has_extension "a.b")
+        check "has_extension 8"  true (has_extension ".b")
+        check "has_extension 9"  true (has_extension "c:\\a.b")
+        check "has_extension 10"  true (has_extension "c:\\a.")
+
+
+        check "chop_extension1"  true (try ignore(Filename.chop_extension "C:"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension2"  true (try ignore(Filename.chop_extension "C:\\"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension3"  true (try ignore(Filename.chop_extension "c:\\"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension4"  true (try ignore(Filename.chop_extension "C:/"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension5"  true (try ignore(Filename.chop_extension "c:/"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension6"  true (try ignore(Filename.chop_extension ""); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension7"  true (try ignore(Filename.chop_extension "a"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension8"  true (try ignore(Filename.chop_extension "c:\\a"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension9"  true (try ignore(Filename.chop_extension "c:\\foo.b\\a"); false with Invalid_argument  "chop_extension" -> true)
+        check "chop_extension10"  "" (Filename.chop_extension ".")
+        check "chop_extension11"  "a" (Filename.chop_extension "a.")
+        check "chop_extension12"  "c:\\a" (Filename.chop_extension "c:\\a.")
+
+        check "Filename.dirname1"  "" (Filename.basename "C:")
+        check "Filename.dirname2"  "" (Filename.basename "C:\\")
+        check "Filename.dirname2"  "" (Filename.basename "c:\\")
+        check "Filename.dirname2"  "" (Filename.basename "")
+        check "Filename.dirname2"  "c" (Filename.basename "\\\\c")
+        check "Filename.dirname2"  "" (Filename.basename "\\\\")
+
+#if FX_NO_DOUBLE_BIT_CONVERTER
+#else
+[<TestFixture>]
+type public Float_Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+        check "FloatParse.1" (Float.to_bits (Float.of_string "0.0")) 0L
+        check "FloatParse.0" (Float.to_bits (Float.of_string "-0.0"))      0x8000000000000000L // (-9223372036854775808L)
+        check "FloatParse.2" (Float.to_bits (Float.of_string "-1E-127"))   0xa591544581b7dec2L // (-6516334528322609470L)
+        check "FloatParse.3" (Float.to_bits (Float.of_string "-1E-323"))   0x8000000000000002L // (-9223372036854775806L)
+        check "FloatParse.4" (Float.to_bits (Float.of_string "-1E-324"))   0x8000000000000000L // (-9223372036854775808L)
+        check "FloatParse.5" (Float.to_bits (Float.of_string "-1E-325"))   0x8000000000000000L // (-9223372036854775808L)
+        check "FloatParse.6" (Float.to_bits (Float.of_string "1E-325")) 0L
+        check "FloatParse.7" (Float.to_bits (Float.of_string "1E-322")) 20L
+        check "FloatParse.8" (Float.to_bits (Float.of_string "1E-323")) 2L
+        check "FloatParse.9" (Float.to_bits (Float.of_string "1E-324")) 0L
+        check "FloatParse.A" (Float.to_bits (Float.of_string "Infinity"))  0x7ff0000000000000L // 9218868437227405312L
+        check "FloatParse.B" (Float.to_bits (Float.of_string "-Infinity")) 0xfff0000000000000L // (-4503599627370496L)
+        check "FloatParse.C" (Float.to_bits (Float.of_string "NaN"))       0xfff8000000000000L  // (-2251799813685248L)
+        check "FloatParse.D" (Float.to_bits (Float.of_string "-NaN"))    ( // http://en.wikipedia.org/wiki/NaN
+                                                                  let bit64 = System.IntPtr.Size = 8 in
+                                                                  if bit64 && System.Environment.Version.Major < 4 then
+                                                                      // 64-bit (on NetFx2.0) seems to have same repr for -nan and nan
+                                                                      0xfff8000000000000L // (-2251799813685248L)
+                                                                  else
+                                                                      // 64-bit (on NetFx4.0) and 32-bit (any NetFx) seems to flip the sign bit on negation.
+                                                                      // However:
+                                                                      // it seems nan has the negative-bit set from the start,
+                                                                      // and -nan then has the negative-bit cleared!
+                                                                      0x7ff8000000000000L // 9221120237041090560L
+                                                                )
+#endif
+
+#if FX_NO_COMMAND_LINE_ARGS
+#else
+[<TestFixture>]
+type public Arg_Tests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+
+      let res = System.Text.StringBuilder()
+      let add (x:string) = res.Append("<"^x^">") |> ignore
+      Microsoft.FSharp.Compatibility.OCaml.Arg.parse_argv (ref 0) [|"main.exe";"otherA";"";"otherB"|] [] add "fred"
+      check "Bug3803" (res.ToString()) "<otherA><><otherB>"
+#endif  
+
+[<TestFixture>]
+type public SysTests() =
+  
+    [<Test>]
+    member this.TestFileExists() = 
+
+        test "dwe098" (not (Sys.file_exists "never-create-me"))
+
+    [<Test>]
+    member this.Test_Sys_remove() = 
+          let os = open_out "remove-me.txt" in
+          close_out os;
+          test "dwe098" (Sys.file_exists "remove-me.txt" && (Sys.remove "remove-me.txt"; not (Sys.file_exists "remove-me.txt")))
+
+    [<Test>]
+    member this.Test_Sys_rename() = 
+          let os = open_out "rename-me.txt" in
+          close_out os;
+          test "dwe098dw" (Sys.file_exists "rename-me.txt" && (Sys.rename "rename-me.txt" "remove-me.txt"; Sys.file_exists "remove-me.txt" && not (Sys.file_exists "rename-me.txt") && (Sys.remove "remove-me.txt"; not (Sys.file_exists "remove-me.txt"))))
+
+#if FX_NO_ENVIRONMENT
+#else
+    [<Test>]
+    member this.Test_Sys_getenv() = 
+          ignore (Sys.getenv "PATH");
+          test "w99ocwkm" (try ignore (Sys.getenv "VERY UNLIKELY VARIABLE"); false; with Not_found -> true)
+#endif
+
+    [<Test>]
+    member this.Test_Sys_getcwd() = 
+            
+          let p1 = Sys.getcwd() in 
+          Sys.chdir "..";
+          let p2 = Sys.getcwd() in 
+          test "eiojk" (p1 <> p2);
+          Sys.chdir p1;
+          let p3 = Sys.getcwd() in 
+          test "eiojk" (p1 = p3)
+
+#if FX_NO_PROCESS_START
+#else
+    [<Test>]
+    member this.Test_Sys_command() = 
+
+          test "ekj" (Sys.command "help.exe" |> ignore; true)
+#endif
+
+    [<Test>]
+    member this.Test_Sys_word_size() = 
+
+          test "ekdwq8uj" (Sys.word_size = 32 || Sys.word_size = 64)
+
+#if FX_NO_PROCESS_DIAGNOSTICS
+#else
+    [<Test>]
+    member this.Test_Sys_time() = 
+
+          let t1 = ref (Sys.time()) in 
+          for i = 1 to 30 do 
+            let t2 = Sys.time() in 
+            test "fe921lk30" (!t1 <= t2);
+            t1 := t2
+          done
+#endif
+
+[<TestFixture>]
+type public FuncConvertTests() =
+  
+    [<Test>]
+    member this.BasicTests() = 
+
+        check "dwe098ce1" ((Microsoft.FSharp.Core.FuncConvert.FuncFromTupled(fun (a,b) -> a + b)) 3 4) 7
+        check "dwe098ce2" ((Microsoft.FSharp.Core.FuncConvert.FuncFromTupled(fun (a,b,c) -> a + b + c)) 3 4 5) 12
+        check "dwe098ce3" ((Microsoft.FSharp.Core.FuncConvert.FuncFromTupled(fun (a,b,c,d) -> a + b + c + d)) 3 4 5 5) 17
+        check "dwe098ce4" ((Microsoft.FSharp.Core.FuncConvert.FuncFromTupled(fun (a,b,c,d,e) -> a + b + c + d + e)) 3 4 5 5 5) 22
+
+        check "dwe098ce1" ((Microsoft.FSharp.Core.FuncConvert.ToFSharpFunc(System.Converter(fun a -> a + 1))) 3) 4
+        check "dwe098ce1" ((Microsoft.FSharp.Core.FuncConvert.ToFSharpFunc(System.Action<_>(fun a -> ()))) 3) ()
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/ControlTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/ControlTests.fs
new file mode 100644
index 0000000..5cd9b39
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/ControlTests.fs
@@ -0,0 +1,527 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open System
+open System.IO
+open System.Threading
+
+#nowarn "40"
+
+
+module ControlTestUtilities = 
+
+    let syncObj = new obj()
+    let reportFailure s = 
+      lock syncObj (fun () ->
+         Assert.Fail (sprintf "FAILURE: %s failed" s)
+      )
+    let biggerThanTrampoliningLimit = 10000
+
+    let boxed(a:Async<'b>) : Async<obj> = async { let! res = a in return box res }
+        
+    type VStringRef(s) = 
+        [<VolatileField>]
+        let mutable contents : string = s 
+        
+        member x.Contents 
+            with get () = contents
+            and set v = contents <- v
+        
+    let (!) (x : VStringRef) = x.Contents
+    let (:=) (x : VStringRef) s = x.Contents <- s
+    let ref s = VStringRef(s)
+
+    // Useful class: put "checkpoints" in the code.
+    // Check they are called in the right order.
+    type Path(str) =
+        let mutable current = 0
+        member p.Check n = check (str + " #" + string (current+1)) n (current+1)
+                           current <- n
+
+    type Color = Blue | Red | Yellow
+
+    type Message =  Color * AsyncResultCell<Color option>
+
+open ControlTestUtilities
+
+[<TestFixture>]
+type public ZZZ_ControlTests() =
+    let writeAllBytes (path:string,bytes:byte[]) =
+#if FX_NO_FILEWRITEALL
+        use s = System.IO.File.OpenWrite(path)
+        s.Write(bytes,0,bytes.Length)
+#else
+        System.IO.File.WriteAllBytes(path, bytes)
+#endif
+    let writeAllText(path:string,contents:string) =
+#if FX_NO_FILEWRITEALL
+        use s = new System.IO.StreamWriter(path)
+        s.Write(contents)
+#else
+        System.IO.File.WriteAllText(path, contents)
+#endif
+
+
+    [<TestFixtureSetUp>]
+    member this.TestFixtureSetUp() = 
+        System.AppDomain.CurrentDomain.UnhandledException.AddHandler(
+               fun _ (args:System.UnhandledExceptionEventArgs) ->
+                  lock syncObj (fun () ->
+                        reportFailure ((args.ExceptionObject :?> System.Exception).ToString())
+                     )
+        )
+  
+    [<Test>]
+    member this.AsyncOpenReadTests() = 
+
+        // There should be no effects before running, e.g. no attempt to open the file
+        do System.IO.File.AsyncOpenRead "non exist ... file " |> ignore
+        do System.IO.File.AsyncOpenWrite "non exist ... file 2" |> ignore
+
+              
+        
+        check 
+            "c32398u1: AsyncOpenRead/AsyncRead"
+            (let _ = writeAllBytes("tmp.bin", "abcdefg"B)
+             Async.RunSynchronously 
+                 (async { use! is = System.IO.File.AsyncOpenRead "tmp.bin" 
+                          return! is.AsyncRead 5 }))
+            "abcde"B
+
+        do 
+            let n = 10000000
+            let bytes = Array.init n (fun i -> byte i)
+            check 
+                "c32398u1: AsyncOpenRead/AsyncRead"
+                (let _ = writeAllBytes("tmp.bin", bytes)
+                 Async.RunSynchronously 
+                     (async { use! is = System.IO.File.AsyncOpenRead "tmp.bin" 
+                              return! is.AsyncRead n }))
+                bytes
+
+        do 
+            let n = 10000000
+            let bytes = Array.init n (fun i -> byte i)
+            check 
+                "c32398u1: AsyncOpenRead/AsyncRead"
+                (let _ = writeAllBytes("tmp.bin", bytes)
+                 Async.RunSynchronously 
+#if FX_NO_FILE_OPTIONS
+                     (async { use! is = System.IO.File.AsyncOpen("tmp.bin",mode=FileMode.Open)
+#else
+                     (async { use! is = System.IO.File.AsyncOpen("tmp.bin",mode=FileMode.Open,options=FileOptions.Asynchronous)
+#endif
+                              return! is.AsyncRead n }))
+                bytes
+
+    [<Test>]
+    member this.AsyncOpenReadWriteTest1() = 
+        check 
+            "c32398u2: AsyncOpenRead/AsyncRead"
+            (let _ = writeAllBytes("tmp.bin", "abcdefg"B)
+             Async.RunSynchronously 
+                  (async { use! is = System.IO.File.AsyncOpenRead "tmp.bin" 
+                           return! is.AsyncRead 7 }))
+            "abcdefg"B
+
+    [<Test>]
+    member this.AsyncOpenReadWriteTest2() = 
+        check 
+            "c32398u3: AsyncOpenRead/AsyncRead"
+            (let _ = writeAllBytes("tmp.bin", "abcdefg"B)
+             Async.RunSynchronously 
+                 (async { let buffer = Array.zeroCreate<byte>(7)
+                          use! is = System.IO.File.AsyncOpenRead "tmp.bin" 
+                          let! count = is.AsyncRead(buffer,0,7) 
+                          return count, buffer }))
+            (7, "abcdefg"B)
+
+
+    [<Test>]
+    member this.AsyncOpenReadWriteTest3() = 
+        check 
+            "c32398u4: AsyncOpenRead/AsyncRead/AsyncOpenWrite/AsyncWrite"
+            (let _ = writeAllBytes("tmp.bin", "abcdefg"B)
+             Async.RunSynchronously 
+                 (async { do! async { let buffer = "qer"B
+                                      use! is = System.IO.File.AsyncOpenWrite "tmp.bin" 
+                                      do! is.AsyncWrite(buffer,0,3)  }
+                          let buffer = Array.zeroCreate<byte>(7)
+                          use! is = System.IO.File.AsyncOpenRead "tmp.bin" 
+                          let! count = is.AsyncRead(buffer,0,7) 
+                          return count, buffer }))
+            (7, "qerdefg"B)
+
+    [<Test>]
+    member this.AsyncOpenTextTest() = 
+        check 
+            "c32398u5: AsyncOpenText"
+            (let _ = writeAllText("tmp.txt", "abcdefg")
+             Async.RunSynchronously 
+                  (async { use! is = System.IO.File.AsyncOpenText "tmp.txt" 
+                           return is.ReadToEnd() }))
+            "abcdefg"
+
+#if FX_NO_WINDOWSFORMS
+#else
+    [<Test>]
+    member this.AsyncWorkerTest16() = 
+
+        let p = Path "test16 - basic worker"
+        let worker = async {
+            do p.Check 1
+            do! Async.Sleep 400
+            do p.Check 3
+        }
+        AsyncWorker(worker).RunAsync() |> ignore
+        System.Threading.Thread.Sleep 200
+        p.Check 2
+        System.Threading.Thread.Sleep 400
+        System.Windows.Forms.Application.DoEvents()
+        p.Check 4
+
+    [<Test>]
+    member this.AsyncWorkerTest17() = 
+        let p = Path "test17 - worker and completed event"
+        let work = async {
+            do p.Check 1
+            do! Async.Sleep 300
+            do p.Check 3
+            return 4
+        }
+        let worker = AsyncWorker(work)
+        worker.Completed.Add(fun n -> p.Check n)
+        worker.RunAsync() |> ignore
+        System.Threading.Thread.Sleep 100
+        p.Check 2
+        System.Threading.Thread.Sleep 400
+        System.Windows.Forms.Application.DoEvents()
+        p.Check 5
+
+    [<Test>]
+    member this.AsyncWorkerTest18() = 
+        // Worker and canceled event (using group.TriggerCancel)
+        let p = Path "test18 - worker & group.TriggerCancel"
+        let work = async {
+            do p.Check 1
+            do System.Threading.Thread.Sleep 200
+            do p.Check 3
+            let! _ = async { return 1 } 
+            do ()
+        }
+        let group = new System.Threading.CancellationTokenSource()
+        let worker = AsyncWorker(work, group.Token)
+        worker.Canceled.Add(fun e -> p.Check 4)
+        worker.RunAsync() |> ignore
+        System.Threading.Thread.Sleep 100
+        p.Check 2
+        group.Cancel()
+        System.Windows.Forms.Application.DoEvents()
+        System.Threading.Thread.Sleep 500
+        System.Windows.Forms.Application.DoEvents()
+        System.Threading.Thread.Sleep 500
+        p.Check 5
+
+    [<Test>]
+    member this.AsyncWorkerTest19() = 
+        // Worker and canceled event (using worker.CancelAsync)
+        let p = Path "test19 - worker & worker.CancelAsync"
+        let work = async {
+            do p.Check 1
+            do System.Threading.Thread.Sleep 200
+            do p.Check 3
+            let! _ = async { return 1 } 
+            do ()
+        }
+        let group = new System.Threading.CancellationTokenSource()
+        let worker = AsyncWorker(work)
+        worker.Canceled.Add(fun e -> p.Check 4)
+        worker.RunAsync() |> ignore
+        System.Threading.Thread.Sleep 100
+        p.Check 2
+        worker.CancelAsync("hello")
+        System.Threading.Thread.Sleep 500
+        System.Windows.Forms.Application.DoEvents()
+        p.Check 5
+
+
+    [<Test>]
+    member this.AsyncWorkerTest20() = 
+        // Worker and exceptions event
+        let p = Path "test20 - worker and exceptions"
+        let work = async {
+            do p.Check 1
+            do failwith "hello world"
+        }
+        let group = new System.Threading.CancellationTokenSource()
+        let worker = AsyncWorker(work, group.Token)
+        worker.Canceled.Add(fun _ -> p.Check -1)
+        worker.Completed.Add(fun _ -> p.Check -1)
+        worker.Error.Add(fun e -> test "test20" (e.Message = "hello world"); p.Check 2)
+        worker.RunAsync() |> ignore
+        System.Threading.Thread.Sleep 50
+        System.Windows.Forms.Application.DoEvents()
+        System.Threading.Thread.Sleep 50
+        p.Check 3
+
+    [<Test>]
+    member this.AsyncWorkerTest21() = 
+        // Worker and report progress
+        let p = Path "test21 - worker & report progress"
+        let rec work = async {
+            for i in 1 .. 49 do
+                do worker.ReportProgress i
+                do printfn "report %d" i
+                do System.Threading.Thread.Sleep 1
+          }
+        and worker: AsyncWorker<_> = AsyncWorker(work)
+        worker.ProgressChanged.Add(fun n -> p.Check n)
+        worker.RunAsync() |> ignore
+        for i in 1 .. 150 do
+            System.Threading.Thread.Sleep 10
+            System.Windows.Forms.Application.DoEvents()
+        p.Check 50
+
+(*
+    [<Test>]
+    member this.AsyncWorkerTest21() = 
+        let form = new System.Windows.Forms.Form()
+        form.Load.Add(fun _ ->
+            test16(); 
+            // ToDo: 7/25/2008: Disabled because of probable timing issue.  QA needs to re-enable post-CTP.
+            // Tracked by bug FSharp 1.0:2891
+            //test17(); 
+            test18(); 
+            test19(); 
+            test20(); 
+            test21()
+            System.Windows.Forms.Application.Exit())
+        System.Windows.Forms.Application.Run(form)
+        // Set the synchronization context back to its original value
+        System.Threading.SynchronizationContext.SetSynchronizationContext(null);
+*)
+
+#endif
+    [<Test>]
+    member this.AsyncResultCellTests() = 
+
+        
+        let doWait(e1 : WaitHandle) (e2 : WaitHandle) s1 s2 =
+            if e2.WaitOne() then
+                if e1.WaitOne() then
+                    (!s1) + (!s2)
+                else "e2WaitFailed"
+            else "e1WaitFailed"
+        
+        do 
+            for i in 1..50 do
+                check
+                    (sprintf "hdfegdfyw6732: AsyncResultCell %d" i)
+                    (let cell = new AsyncResultCell<string>()
+                     use e1 = new ManualResetEvent(false)
+                     let s1 = ref ""
+                     use e2 = new ManualResetEvent(false)
+                     let s2 = ref ""
+                     async { 
+                        do! Async.Sleep(100)
+                        let! result = cell.AsyncResult 
+                        //printfn "Here we are!(1)"
+                        s1 := result; e1.Set() |> ignore 
+                     } |> Async.Start
+                     async { 
+                        let! result = cell.AsyncResult 
+                        //printfn "Here we are!(2)"
+                        s2 := result; e2.Set() |> ignore 
+                     } |> Async.Start
+                     ThreadPool.QueueUserWorkItem(fun _ -> cell.RegisterResult(AsyncOk "hello")) |> ignore
+                     doWait e1 e2 s1 s2
+                    )
+                    "hellohello"
+
+
+        
+        do 
+            for i in 1..50 do
+                check
+                    (sprintf "hdfegdfyw6732: AsyncResultCell w/exception %d" i)
+                    (let cell = new AsyncResultCell<string>()
+                     use e1 = new ManualResetEvent(false)
+                     let s1 = ref ""
+                     use e2 = new ManualResetEvent(false)
+                     let s2 = ref ""
+                     let asyncToRun s (e:ManualResetEvent)=
+                        async {
+                            try 
+                                let! result = cell.AsyncResult in 
+                                s := result 
+                            with 
+                            |   ex -> s := ex.Message
+                            e.Set() |> ignore 
+                        }
+                     asyncToRun s1 e1 |> Async.Start
+                     asyncToRun s2 e2 |> Async.Start
+                     ThreadPool.QueueUserWorkItem(fun _ -> cell.RegisterResult(System.Exception("exn") |> AsyncException))  |> ignore
+                     doWait e1 e2 s1 s2        
+                    )
+                    "exnexn"
+
+        do check
+            "hdfegdfyw6732: AsyncResultCell + set result before wait starts"
+            (let cell = new AsyncResultCell<string>()
+             use e1 = new ManualResetEvent(false)
+             let s1 = ref ""
+             use e2 = new ManualResetEvent(false)
+             let s2 = ref ""
+             cell.RegisterResult(AsyncOk "hello") 
+             async { let! result = cell.AsyncResult in s1 := result; e1.Set() |> ignore } |> Async.Start
+             async { let! result = cell.AsyncResult in s2 := result; e2.Set() |> ignore } |> Async.Start
+             doWait e1 e2 s1 s2
+            )
+            "hellohello"
+            
+        do check
+            "hdfegdfyw6732: AsyncResultCell w/exception + set result before wait starts"
+            (let cell = new AsyncResultCell<string>()
+             use e1 = new ManualResetEvent(false)
+             let s1 = ref ""
+             use e2 = new ManualResetEvent(false)
+             let s2 = ref ""
+             let asyncToRun s (e:ManualResetEvent) =
+                async {
+                    try 
+                        let! result = cell.AsyncResult in 
+                        s := result 
+                    with 
+                    |  e -> s := e.Message
+                    e.Set() |> ignore 
+                }
+             cell.RegisterResult(Exception("exn") |> AsyncException) 
+             asyncToRun s1 e1 |> Async.Start
+             asyncToRun s2 e2 |> Async.Start
+             doWait e1 e2 s1 s2
+            )
+            "exnexn"
+
+    [<Test>]
+    member this.AsyncResultCellAgents() = 
+
+        let complement = function
+            | (Red, Yellow) | (Yellow, Red) -> Blue
+            | (Red, Blue) | (Blue, Red) -> Yellow
+            | (Yellow, Blue) | (Blue, Yellow) -> Red
+            | (Blue, Blue) -> Blue
+            | (Red, Red) -> Red
+            | (Yellow, Yellow) -> Yellow
+
+
+        let chameleon (meetingPlace : MailboxProcessor<Message>) initial = 
+            let rec loop c meets = async  {
+                    let resultCell = new AsyncResultCell<_>()
+                    meetingPlace.Post (c, resultCell)
+                    let! reply = resultCell.AsyncResult
+                    match reply with     
+                    | Some(newColor) -> return! loop newColor (meets + 1)
+                    | None -> return meets
+                }
+            loop initial 0
+            
+
+        let meetingPlace chams n = MailboxProcessor.Start(fun (processor : MailboxProcessor<Message>)->
+            let rec fadingLoop total = 
+                async   {
+                    if total <> 0 then
+                        let! (_, reply) = processor.Receive()
+                        reply.RegisterResult (AsyncOk None)
+                        return! fadingLoop (total - 1)
+                    else
+                        printfn "Done"
+                }
+            let rec mainLoop curr = 
+                async   {
+                    if (curr > 0) then
+                        let! (color1, reply1) = processor.Receive()
+                        let! (color2, reply2) = processor.Receive()
+                        let newColor = complement (color1, color2)
+                        reply1.RegisterResult(AsyncOk(Some(newColor)))
+                        reply2.RegisterResult(AsyncOk(Some(newColor)))
+                        return! mainLoop (curr - 1)
+                    else
+                        return! fadingLoop chams
+                }
+            mainLoop n
+            ) 
+            
+
+
+        let meetings = 100000
+        
+        let colors = [Blue; Red; Yellow; Blue]    
+        let mp = meetingPlace (colors.Length) meetings
+        let meets = 
+                colors 
+                    |> List.map (chameleon mp) 
+                    |> Async.Parallel 
+                    |> Async.RunSynchronously 
+
+        check "Chamenos" (Seq.sum meets) (meetings*2)
+
+    [<Test>]
+    member this.AsyncResultCellLightweightAgents() = 
+        let complement = function
+            | (Red, Yellow) | (Yellow, Red) -> Blue
+            | (Red, Blue) | (Blue, Red) -> Yellow
+            | (Yellow, Blue) | (Blue, Yellow) -> Red
+            | (Blue, Blue) -> Blue
+            | (Red, Red) -> Red
+            | (Yellow, Yellow) -> Yellow
+
+        let chameleon (meetingPlace : MailboxProcessor<Message>) initial = 
+            let rec loop c meets = async  {
+                    let resultCell = new AsyncResultCell<_>()
+                    meetingPlace.Post (c, resultCell)
+                    let! reply = resultCell.AsyncResult
+                    match reply with     
+                    | Some(newColor) -> return! loop newColor (meets + 1)
+                    | None -> return meets
+                }
+            loop initial 0
+            
+
+        let meetingPlace chams n = MailboxProcessor.Start(fun (processor : MailboxProcessor<Message>)->
+            let rec fadingLoop total = 
+                async   {
+                    if total <> 0 then
+                        let! (_, reply) = processor.Receive()
+                        reply.RegisterResult (AsyncOk None)
+                        return! fadingLoop (total - 1)
+                    else
+                        printfn "Done"
+                }
+            let rec mainLoop curr = 
+                async   {
+                    if (curr > 0) then
+                        let! (color1, reply1) = processor.Receive()
+                        let! (color2, reply2) = processor.Receive()
+                        let newColor = complement (color1, color2)
+                        reply1.RegisterResult(AsyncOk(Some(newColor)), reuseThread=true)
+                        reply2.RegisterResult(AsyncOk(Some(newColor)), reuseThread=true)
+                        return! mainLoop (curr - 1)
+                    else
+                        return! fadingLoop chams
+                }
+            mainLoop n
+            ) 
+
+
+
+        let meetings = 100000
+        
+        let colors = [Blue; Red; Yellow; Blue]    
+        let mp = meetingPlace (colors.Length) meetings
+        let meets = 
+                colors 
+                    |> List.map (chameleon mp) 
+                    |> Async.Parallel 
+                    |> Async.RunSynchronously 
+
+        check "Chamenos" (Seq.sum meets) (meetings*2)
+
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj b/workyard/linq/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj
new file mode 100644
index 0000000..87d0b48
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..</FSharpPowerPackSourcesRoot>
+    <TOOLS Condition=" '$(TOOLS)' == '' ">>..\..\tools</TOOLS>
+    <SccProjectName>SAK</SccProjectName>
+    <SccProvider>SAK</SccProvider>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E2A0F944-E76E-4C53-B037-A050FDF7378A}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>FSharp.PowerPack.Unittests</RootNamespace>
+    <AssemblyName>FSharp.PowerPack.Unittests</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <StrongName>false</StrongName>
+    <!--->ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB}</ProjectTypeGuids-->
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>62</NoWarn>
+    <OtherFlags>--mlcompatibility</OtherFlags>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>62</NoWarn>
+    <OtherFlags>--mlcompatibility</OtherFlags>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Condition="'$(TargetFramework)' == 'Silverlight'" Include="NUnitFrameworkShims.fs" />
+    <Compile Include="Utilities.fs" />
+    <Compile Include="HashtblTests.fs" />
+    <Compile Include="MatrixVectorTests.fs" />
+    <Compile Include="LazyListTests.fs" />
+    <Compile Include="CompatTests.fs" />
+    <Compile Include="ColllectionTests.fs" />
+    <Compile Include="ControlTests.fs" />
+    <Compile Include="SetMapTests.fs" />
+    <Compile Include="PermutationTests.fs" />
+    <Compile Condition="'$(TargetFramework)' == ''" Include="NativeArrayTests.fs" />
+    <Compile Include="BigRationalTests.fs" />
+    <Compile Include="QuotationEvalTests.fs" />
+    <Compile Include="StructuredFormatTests.fs" />
+    <Compile Condition="'$(TargetFramework)' == ''" Include="MetadataTests.fs" />
+    <Compile Condition="'$(TargetFramework)' == ''" Include="QueryTests.fs" />
+    <Compile Include="AsyncStreamReaderTest.fs" />
+    <Compile Condition="'$(TargetFramework)' == ''" Include="ASP.NET\AspNetTester.fs">
+      <Link>AspNetTester.fs</Link>
+    </Compile>
+    <None Include="blas.dll" />
+    <None Include="LAPACK.dll" />
+    <None Condition="'$(TargetFramework)' == ''" Include="NORTHWND.MDF" />
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Condition="'$(TargetFramework)'=='Silverlight'" Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.Common.targets" />
+  <ItemGroup>
+    <Reference Include="FSharp.Compiler.CodeDom">
+      <HintPath>..\..\..\Debug\bin\FSharp.Compiler.CodeDom.dll</HintPath>
+    </Reference>
+    <Reference Include="FSharp.PowerPack">
+      <HintPath>..\..\..\Debug\bin\FSharp.PowerPack.dll</HintPath>
+    </Reference>
+    <Reference Include="FSharp.PowerPack.Build.Tasks">
+      <HintPath>..\..\..\Debug\bin\FSharp.PowerPack.Build.Tasks.dll</HintPath>
+    </Reference>
+    <Reference Include="FSharp.PowerPack.Compatibility">
+      <HintPath>..\..\..\Debug\bin\FSharp.PowerPack.Compatibility.dll</HintPath>
+    </Reference>
+    <Reference Include="FSharp.PowerPack.Metadata">
+      <HintPath>..\..\..\Debug\bin\FSharp.PowerPack.Metadata.dll</HintPath>
+    </Reference>
+    <Reference Include="fshtmldoc">
+      <HintPath>..\..\..\Debug\bin\fshtmldoc.exe</HintPath>
+    </Reference>
+    <Reference Include="fslex">
+      <HintPath>..\..\..\Debug\bin\fslex.exe</HintPath>
+    </Reference>
+    <Reference Include="fsyacc">
+      <HintPath>..\..\..\Debug\bin\fsyacc.exe</HintPath>
+    </Reference>
+    <Reference Include="LinqToSql.Northwind">
+      <HintPath>Linq\LinqToSql.Northwind\bin\Debug\LinqToSql.Northwind.dll</HintPath>
+    </Reference>
+    <Reference Condition="'$(TargetFramework)' == ''" Include="nunit.framework">
+      <HintPath>$(TOOLS)\NUnit\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Condition="'$(TargetFramework)' == ''" Include="System.Data" />
+    <Reference Condition="'$(TargetFramework)' == ''" Include="System.Data.Linq" />
+    <Reference Condition="'$(TargetFramework)' == ''" Include="System.Drawing" />
+    <Reference Condition="'$(TargetFramework)' == ''" Include="System.Windows.Forms" />
+    <ProjectReference Include="..\FSharp.PowerPack.Linq\FSharp.PowerPack.Linq.fsproj">
+      <Project>{4C2ED03B-5ACE-427B-8285-AD333E60F35E}</Project>
+      <Name>FSharp.PowerPack.Linq</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj.vspscc b/workyard/linq/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj.vspscc
new file mode 100644
index 0000000..b6d3289
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/FSharp.PowerPack.Unittests.fsproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/HashtblTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/HashtblTests.fs
new file mode 100644
index 0000000..c8390e2
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/HashtblTests.fs
@@ -0,0 +1,93 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+
+#nowarn "40"
+
+[<TestFixture>]
+type public HashtblTests() =
+
+  
+    [<Test>]
+    member this.BasicTests() = 
+
+            printf "I am running";
+            let map1 = Hashtbl.create 5 in
+            Hashtbl.add map1 5 5;
+            Hashtbl.add map1 17 17;
+            Hashtbl.add map1 94 94;
+            let map2 = Hashtbl.copy map1 in
+            Hashtbl.replace map1 5 7;
+            Hashtbl.replace map1 17 19;
+            check "21980d3" (Hashtbl.find map1 17) 19;    
+            check "21980d3" (Hashtbl.find map1 5) 7;    
+            check "21980d3" (Hashtbl.find map1 94) 94;    
+
+            check "21980d3" (Hashtbl.find_all map1 17) [19];    
+            check "21980d3" (Hashtbl.find_all map1 5) [7];    
+            check "21980d3" (Hashtbl.find_all map1 94) [94];    
+
+            check "21980d3" (Hashtbl.find map2 5) 5;    
+            check "21980d3" (Hashtbl.find map2 17) 17;    
+            check "21980d3" (Hashtbl.find map2 94) 94;    
+
+            check "21980d3" (Hashtbl.find_all map2 5) [5];    
+            check "21980d3" (Hashtbl.find_all map2 17) [17];    
+            check "21980d3" (Hashtbl.find_all map2 94) [94];    
+            printf "I am done"
+
+    [<Test>]
+    member this.NameResolutions() = 
+
+        // check name resolutions
+        let topEnvTable1 = new Microsoft.FSharp.Collections.HashSet<string>(10, HashIdentity.Structural)
+        let topEnvTable2 = new Microsoft.FSharp.Collections.HashMultiMap<string,int>(10, HashIdentity.Structural)
+        ()
+
+    [<Test>]
+    member this.MiscSamples() = 
+        let SampleHashtbl1() =
+            let tab = Microsoft.FSharp.Collections.HashMultiMap(30, HashIdentity.Structural) 
+            let data = "The quick brown fox jumps over the lazy dog" 
+            for i = 0 to data.Length - 1 do 
+                let c = data.Chars(i) 
+                match tab.TryFind(c) with 
+                | None -> tab.Add(c,1)
+                | Some v -> tab.Replace(c,v+1)
+            tab |> Seq.iter (fun (KeyValue(c,v)) -> printf "Number of '%c' characters = %d\n" c v) 
+          
+        let SampleHashtbl1b() =
+            let tab = Microsoft.FSharp.Collections.HashMultiMap<_,_>(30, HashIdentity.Structural) 
+            let data = "The quick brown fox jumps over the lazy dog" 
+            for i = 0 to data.Length - 1 do 
+                let c = data.Chars(i) 
+                match tab.TryFind(c) with 
+                | None -> tab.Add(c,1)
+                | Some v -> tab.Replace(c,v+1)
+            tab |> Seq.iter (fun (KeyValue(c,v)) -> printf "Number of '%c' characters = %d\n" c v) 
+          
+
+        let SampleHashtbl2() =
+            let tab = Hashtbl.create 30 
+            let data = "The quick brown fox jumps over the lazy dog" 
+            for i = 0 to data.Length - 1 do 
+                let c = data.Chars(i) 
+                match Hashtbl.tryfind tab c with 
+                | None -> Hashtbl.add tab c 1
+                | Some v -> Hashtbl.replace tab c (v+1)
+            Hashtbl.iter (fun c v -> printf "Number of '%c' characters = %d\n" c v) tab
+          
+          
+        let x1 = new HashMultiMap<int,int>(10, HashIdentity.Structural)
+        let x2 = HashMultiMap<int,Set<int>>(10, HashIdentity.Structural)
+        let x3 = HashMultiMap<int,Set<Set<int>>>(10, HashIdentity.Structural)
+        let x4 = HashMultiMap<int,Set<Set<Set<int>>>>(10, HashIdentity.Structural)
+        let x5 = HashMultiMap<int,Set<Set<Set<int>> >>(10, HashIdentity.Structural)
+        let x6 = HashMultiMap<int,Set<Set<Set<int> > >>(10, HashIdentity.Structural)
+        let x7 = HashMultiMap<int,Set<Set<Set<int> > > >(10, HashIdentity.Structural)
+        let x8 = HashMultiMap<int,Set<Set<Set<int>>> >(10, HashIdentity.Structural)
+        let x9 = HashMultiMap<Set<Set<int>>,int>(10, HashIdentity.Structural)
+        let x10 = HashMultiMap<Set<Set<int>>,Set<int>>(10, HashIdentity.Structural)
+        let x11 = HashMultiMap<Set<Set<int>>,Set<Set<int>>>(10, HashIdentity.Structural)
+        ()
+        
+
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/LazyListTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/LazyListTests.fs
new file mode 100644
index 0000000..936f022
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/LazyListTests.fs
@@ -0,0 +1,137 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+
+#nowarn "40"
+
+[<TestFixture>]
+type public ZZZ_LazyListTests() =
+  
+    [<Test>]
+    member this.BasicTests1() = 
+
+        let l = LazyList.ofList [1;2;3] in
+        let res = ref 2 in 
+        for i in (LazyList.toSeq l) do res := !res + i done;
+        check "test2398984: LazyList.toSeq" 8 !res;
+        let res = ref 2 in 
+        for i in LazyList.toSeq l do 
+            res := !res + i 
+        done;
+        check "test2398984: LazyList.toSeq" 8 !res
+  
+    [<Test>]
+    member this.BasicTests2() = 
+        let l = LazyList.ofList [1;2;3] in
+        let res = ref 2 in 
+        Seq.iter (fun i -> res := !res + i) (LazyList.toSeq l) 
+        check "test2398994: foreach, LazyList.toSeq" 8 !res
+
+    [<Test>]
+    member this.BasicTests3() = 
+
+        test "se1" (LazyList.isEmpty LazyList.empty)
+        test "se2" (not (LazyList.isEmpty (LazyList.cons 1 LazyList.empty)))
+        test "se3" (not (LazyList.isEmpty (LazyList.repeat 1)))
+        test "se4" (not (LazyList.isEmpty (LazyList.unfold (fun z -> Some (z,z+1)) 0)))
+
+        test "seq1" (LazyList.head (LazyList.cons 1 LazyList.empty) = 1)
+        test "seq2" (LazyList.head (LazyList.cons 1 (LazyList.cons 2 LazyList.empty)) = 1)
+        test "seq3" (LazyList.head (LazyList.tail (LazyList.cons 1 (LazyList.cons 2 LazyList.empty))) = 2)
+
+        let nats = LazyList.unfold (fun z -> Some (z,z+1)) 0 
+        test "take1" (LazyList.toList (LazyList.take 4 nats) = [0;1;2;3])
+        test "drop1" (LazyList.head (LazyList.skip 4 nats) = 4)
+        test "drop1" (LazyList.head (LazyList.skip 0 nats) = 0)
+
+        test "repeat" (LazyList.toList (LazyList.take 4 (LazyList.repeat 1)) = [1;1;1;1])
+        test "append" (LazyList.toList (LazyList.take 4 (LazyList.append (LazyList.cons 77 (LazyList.empty)) nats)) = [77;0;1;2])
+        test "zip"  (LazyList.toList (LazyList.take 3 (LazyList.zip nats (LazyList.skip 6 nats))) = [0,6;1,7; 2,8])
+        test "firstS" (LazyList.tryFind (fun x -> x>=8) nats = Some 8)
+        test "firstN" (LazyList.tryFind (fun x -> x>=8) (LazyList.take 5 nats) = None)
+        test "find S" (LazyList.find (fun x -> x>=8) nats = 8)
+        test "find N" (let res =
+                              try
+                                LazyList.find (fun x -> x>=8) (LazyList.take 5 nats)
+                              with
+                                  Not_found -> 9999
+                       res = 9999) (* testing for exception *)
+
+        let rec diverge () = diverge ()
+        test "consfA"       (LazyList.head (LazyList.consDelayed 1 diverge) = 1)
+        test "consfB"       (let ss = LazyList.tail (LazyList.consDelayed 1 diverge) in true) (* testing for lazy divergence *)
+        test "dropDiverge1" (let ss = LazyList.skip 1 (LazyList.consDelayed 1 diverge) in true) (* testing for lazy divergence *)
+        test "dropDiverge0" (let ss = LazyList.skip 0 (LazyList.delayed (fun () -> failwith "errors")) in true) (* testing for lazy divergence *)
+        test "takedrop" (LazyList.toList (LazyList.take 3 (LazyList.skip 4 nats)) = [4;5;6])
+
+        test "filter" (LazyList.toList (LazyList.take 4 (LazyList.filter (fun x -> x mod 2 = 0) nats))     = [0;2;4;6])
+        test "map"    (LazyList.toList (LazyList.take 4 (LazyList.map    (fun x -> x+1) nats))             = [1;2;3;4])
+        test "map2"   (LazyList.toList (LazyList.take 4 (LazyList.map2   (fun x y -> x*y) nats (LazyList.tail nats))) = [0*1;1*2;2*3;3*4])
+
+        test "array"  (Array.toList (LazyList.toArray (LazyList.take 6 nats)) = LazyList.toList (LazyList.take 6 nats))
+        test "array"  (LazyList.toList (LazyList.ofArray [|1;2;3;4|]) = LazyList.toList (LazyList.ofList [1;2;3;4]))
+
+        // This checks that LazyList.map, LazyList.length etc. are tail recursive
+        check "LazyList.length" (LazyList.ofSeq (Seq.init 100 (fun c -> c)) |> LazyList.length) 100
+        check "LazyList.length" (LazyList.ofSeq (Seq.init 1000000 (fun c -> c)) |> LazyList.length) 1000000
+        check "LazyList.length" (LazyList.ofSeq (Seq.init 0 (fun c -> c)) |> LazyList.length) 0
+        check "LazyList.map" (LazyList.map (fun x -> x + 1) (LazyList.ofSeq (Seq.init 1000000 (fun c -> c))) |> Seq.length) 1000000
+        check "LazyList.filter" (LazyList.filter (fun x -> x % 2 = 0) (LazyList.ofSeq (Seq.init 1000000 (fun c -> c))) |> Seq.length) 500000
+        check "LazyList.iter" (let count = ref 0 in LazyList.iter (fun x -> incr count) (LazyList.ofSeq (Seq.init 0 (fun c -> c))); !count) 0
+        check "LazyList.iter" (let count = ref 0 in LazyList.iter (fun x -> incr count) (LazyList.ofSeq (Seq.init 1000000 (fun c -> c))); !count) 1000000
+        check "LazyList.toList" (LazyList.toList (LazyList.ofSeq (Seq.init 200000 (fun c -> c))) |> Seq.length) 200000
+        check "LazyList.toArray" (LazyList.toArray (LazyList.ofSeq (Seq.init 200000 (fun c -> c))) |> Seq.length) 200000
+
+        /// check exists on an infinite stream terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (LazyList.repeat "a" |> LazyList.toSeq)) true
+        /// check a succeeding 'exists' on a concat of an infinite number of finite streams terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (Seq.concat (LazyList.repeat [| "a"; "b"|] |> LazyList.toSeq))) true
+        /// check a succeeding 'exists' on a concat of an infinite number of infinite streams terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (Seq.concat (LazyList.repeat (LazyList.repeat "a" |> LazyList.toSeq) |> LazyList.toSeq))) true
+        /// check a failing for_all on an infinite stream terminates
+        check "IEnumerableTest.exists" (Seq.forall ((=) "a" >> not) (LazyList.repeat "a" |> LazyList.toSeq)) false
+        /// check a failing for_all on a concat of an infinite number of finite streams terminates
+        check "IEnumerableTest.exists" (Seq.forall ((=) "a" >> not) (Seq.concat (LazyList.repeat [| "a"; "b"|] |> LazyList.toSeq))) false
+        check "IEnumerableTest.append, infinite, infinite, then take" (Seq.take 2 (Seq.append (LazyList.repeat "a" |> LazyList.toSeq) (LazyList.repeat "b" |> LazyList.toSeq)) |> Seq.toList) [ "a"; "a" ]
+        /// check exists on an infinite stream terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (LazyList.repeat "a" |> LazyList.toSeq |> countEnumeratorsAndCheckedDisposedAtMostOnce)) true
+        check "<dispoal>" !numActiveEnumerators 0
+        /// check a succeeding 'exists' on a concat of an infinite number of finite streams terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (Seq.concat (LazyList.repeat [| "a"; "b"|] |> LazyList.toSeq |> countEnumeratorsAndCheckedDisposedAtMostOnce))) true
+        check "<dispoal>" !numActiveEnumerators 0
+        /// check a succeeding 'exists' on a concat of an infinite number of infinite streams terminates
+        check "IEnumerableTest.exists" (Seq.exists ((=) "a") (Seq.concat (LazyList.repeat (LazyList.repeat "a" |> LazyList.toSeq) |> LazyList.toSeq |> countEnumeratorsAndCheckedDisposedAtMostOnce))) true
+        check "<dispoal>" !numActiveEnumerators 0
+        /// check a failing for_all on an infinite stream terminates
+        check "IEnumerableTest.exists" (Seq.forall ((=) "a" >> not) (LazyList.repeat "a" |> LazyList.toSeq |> countEnumeratorsAndCheckedDisposedAtMostOnce)) false
+        check "<dispoal>" !numActiveEnumerators 0
+
+        /// check a failing for_all on a concat of an infinite number of finite streams terminates
+        check "<dispoal>" !numActiveEnumerators 0
+        check "IEnumerableTest.exists" (Seq.forall ((=) "a" >> not) (Seq.concat (LazyList.repeat [| "a"; "b"|] |> LazyList.toSeq |> countEnumeratorsAndCheckedDisposedAtMostOnce))) false
+        check "<dispoal>" !numActiveEnumerators 0
+        check "IEnumerableTest.append, infinite, infinite, then take" (Seq.take 2 (Seq.append (LazyList.repeat "a" |> LazyList.toSeq) (LazyList.repeat "b" |> LazyList.toSeq)) |> countEnumeratorsAndCheckedDisposedAtMostOnceAtEnd |> Seq.toList) [ "a"; "a" ]
+        check "<dispoal>" !numActiveEnumerators 0
+    
+
+    [<Test>]
+    member this.PatternsTests() = 
+
+        let matchTwo ll = 
+            match ll with 
+            | LazyList.Cons(h1,LazyList.Cons(h2,t)) -> printf "%O,%O\n" h1 h2
+            | LazyList.Cons(h1,t) -> printf "%O\n" h1
+            | LazyList.Nil() -> printf "empty!\n" 
+
+        let rec pairReduce xs =
+          match xs with
+            | LazyList.Cons (x, LazyList.Cons (y,ys)) -> LazyList.consDelayed (x+y) (fun () -> pairReduce ys)
+            | LazyList.Cons (x, LazyList.Nil)      -> LazyList.cons x LazyList.empty
+            | LazyList.Nil                 -> LazyList.empty 
+
+        let rec inf = LazyList.consDelayed 0 (fun () -> LazyList.map (fun x -> x + 1) inf)
+
+        let ll = LazyList.ofList [1;2;3;4]
+        check "we09wek" (sprintf "%A" (LazyList.toList (LazyList.take 10 (pairReduce inf)))) "[1; 5; 9; 13; 17; 21; 25; 29; 33; 37]"
+
+        check "we09wek" (LazyList.scan (+) 0 (LazyList.ofList [1;2])  |> LazyList.toList)  [0;1;3]
+        check "we09wek" (LazyList.scan (+) 0 (LazyList.ofList [])  |> LazyList.toList)  [0]
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/LibraryTestFx.fs b/workyard/linq/FSharp.PowerPack.Unittests/LibraryTestFx.fs
new file mode 100644
index 0000000..fd6eb4e
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/LibraryTestFx.fs
@@ -0,0 +1,47 @@
+
+module FSharp.PowerPack.LibraryTestFx
+
+open System
+open System.Collections.Generic
+
+open NUnit.Framework
+
+// Workaround for bug 3601, we are issuing an unnecessary warning
+#nowarn "0004"
+
+/// Check that the lamda throws an exception of the given type. Otherwise
+/// calls Assert.Fail()
+let private CheckThrowsExn<'a when 'a :> exn> (f : unit -> unit) =
+    let funcThrowsAsExpected =
+        try
+            let _ = f ()
+            false // Did not throw!
+        with
+        | :? 'a
+            -> true   // Thew null ref, OK
+        | _ -> false  // Did now throw a null ref exception!
+    if funcThrowsAsExpected
+    then ()
+    else Assert.Fail()
+
+// Illegitimate exceptions. Once we've scrubbed the library, we should add an
+// attribute to flag these exception's usage as a bug.
+let CheckThrowsNullRefException      f = CheckThrowsExn<NullReferenceException>   f
+let CheckThrowsIndexOutRangException f = CheckThrowsExn<IndexOutOfRangeException> f
+
+// Legit exceptions
+let CheckThrowsNotSupportedException f = CheckThrowsExn<NotSupportedException>    f
+let CheckThrowsArgumentException     f = CheckThrowsExn<ArgumentException>        f
+let CheckThrowsArgumentNullException f = CheckThrowsExn<ArgumentNullException>    f
+let CheckThrowsKeyNotFoundException  f = CheckThrowsExn<KeyNotFoundException>     f
+let CheckThrowsDivideByZeroException f = CheckThrowsExn<DivideByZeroException>    f
+let CheckThrowsInvalidOperationExn   f = CheckThrowsExn<InvalidOperationException> f
+
+// Verifies two sequences are equal (same length, equiv elements)
+let VerifySeqsEqual seq1 seq2 =
+    if Seq.length seq1 <> Seq.length seq2 then Assert.Fail()
+    
+    let zippedElements = Seq.zip seq1 seq2
+    if zippedElements |> Seq.forall (fun (a, b) -> a = b) 
+    then ()
+    else Assert.Fail()
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Entities.Northwind.csproj b/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Entities.Northwind.csproj
new file mode 100644
index 0000000..9c26dd0
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Entities.Northwind.csproj
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{A8A3D712-9EEA-4F84-B062-349EA3CA1267}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Entities.Northwind</RootNamespace>
+    <AssemblyName>Entities.Northwind</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data.Entity" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Security" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Northwind.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Northwind.edmx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <EntityDeploy Include="Northwind.edmx">
+      <Generator>EntityModelCodeGenerator</Generator>
+      <LastGenOutput>Northwind.Designer.cs</LastGenOutput>
+    </EntityDeploy>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Northwind.Designer.cs b/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Northwind.Designer.cs
new file mode 100644
index 0000000..72f4fb3
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Northwind.Designer.cs
@@ -0,0 +1,6713 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+using System;
+using System.Data.Objects;
+using System.Data.Objects.DataClasses;
+using System.Data.EntityClient;
+using System.ComponentModel;
+using System.Xml.Serialization;
+using System.Runtime.Serialization;
+
+[assembly: EdmSchemaAttribute()]
+#region EDM Relationship Metadata
+
+[assembly: EdmRelationshipAttribute("Northwind", "FK_Products_Categories", "Categories", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(Entities.Northwind.Category), "Products", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Product), true)]
+[assembly: EdmRelationshipAttribute("Northwind", "FK_Orders_Customers", "Customers", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(Entities.Northwind.Customer), "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Order), true)]
+[assembly: EdmRelationshipAttribute("Northwind", "FK_Employees_Employees", "Employees", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(Entities.Northwind.Employee), "Employees1", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Employee), true)]
+[assembly: EdmRelationshipAttribute("Northwind", "FK_Orders_Employees", "Employees", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(Entities.Northwind.Employee), "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Order), true)]
+[assembly: EdmRelationshipAttribute("Northwind", "FK_Order_Details_Orders", "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(Entities.Northwind.Order), "Order_Details", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Order_Detail), true)]
+[assembly: EdmRelationshipAttribute("Northwind", "FK_Order_Details_Products", "Products", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(Entities.Northwind.Product), "Order_Details", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Order_Detail), true)]
+[assembly: EdmRelationshipAttribute("Northwind", "FK_Orders_Shippers", "Shippers", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(Entities.Northwind.Shipper), "Orders", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Order), true)]
+[assembly: EdmRelationshipAttribute("Northwind", "FK_Products_Suppliers", "Suppliers", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(Entities.Northwind.Supplier), "Products", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Product), true)]
+[assembly: EdmRelationshipAttribute("Northwind", "FK_Territories_Region", "Region", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(Entities.Northwind.Region), "Territories", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Territory), true)]
+[assembly: EdmRelationshipAttribute("Northwind", "CustomerCustomerDemo", "CustomerDemographics", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.CustomerDemographic), "Customers", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Customer))]
+[assembly: EdmRelationshipAttribute("Northwind", "EmployeeTerritories", "Employees", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Employee), "Territories", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Entities.Northwind.Territory))]
+
+#endregion
+
+namespace Entities.Northwind
+{
+    #region Contexts
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    public partial class Entities : ObjectContext
+    {
+        #region Constructors
+    
+        /// <summary>
+        /// Initializes a new Entities object using the connection string found in the 'Entities' section of the application configuration file.
+        /// </summary>
+        public Entities() : base("name=Entities", "Entities")
+        {
+            this.ContextOptions.LazyLoadingEnabled = true;
+            OnContextCreated();
+        }
+    
+        /// <summary>
+        /// Initialize a new Entities object.
+        /// </summary>
+        public Entities(string connectionString) : base(connectionString, "Entities")
+        {
+            this.ContextOptions.LazyLoadingEnabled = true;
+            OnContextCreated();
+        }
+    
+        /// <summary>
+        /// Initialize a new Entities object.
+        /// </summary>
+        public Entities(EntityConnection connection) : base(connection, "Entities")
+        {
+            this.ContextOptions.LazyLoadingEnabled = true;
+            OnContextCreated();
+        }
+    
+        #endregion
+    
+        #region Partial Methods
+    
+        partial void OnContextCreated();
+    
+        #endregion
+    
+        #region ObjectSet Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Category> Categories
+        {
+            get
+            {
+                if ((_Categories == null))
+                {
+                    _Categories = base.CreateObjectSet<Category>("Categories");
+                }
+                return _Categories;
+            }
+        }
+        private ObjectSet<Category> _Categories;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<CustomerDemographic> CustomerDemographics
+        {
+            get
+            {
+                if ((_CustomerDemographics == null))
+                {
+                    _CustomerDemographics = base.CreateObjectSet<CustomerDemographic>("CustomerDemographics");
+                }
+                return _CustomerDemographics;
+            }
+        }
+        private ObjectSet<CustomerDemographic> _CustomerDemographics;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Customer> Customers
+        {
+            get
+            {
+                if ((_Customers == null))
+                {
+                    _Customers = base.CreateObjectSet<Customer>("Customers");
+                }
+                return _Customers;
+            }
+        }
+        private ObjectSet<Customer> _Customers;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Employee> Employees
+        {
+            get
+            {
+                if ((_Employees == null))
+                {
+                    _Employees = base.CreateObjectSet<Employee>("Employees");
+                }
+                return _Employees;
+            }
+        }
+        private ObjectSet<Employee> _Employees;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Order_Detail> Order_Details
+        {
+            get
+            {
+                if ((_Order_Details == null))
+                {
+                    _Order_Details = base.CreateObjectSet<Order_Detail>("Order_Details");
+                }
+                return _Order_Details;
+            }
+        }
+        private ObjectSet<Order_Detail> _Order_Details;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Order> Orders
+        {
+            get
+            {
+                if ((_Orders == null))
+                {
+                    _Orders = base.CreateObjectSet<Order>("Orders");
+                }
+                return _Orders;
+            }
+        }
+        private ObjectSet<Order> _Orders;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Product> Products
+        {
+            get
+            {
+                if ((_Products == null))
+                {
+                    _Products = base.CreateObjectSet<Product>("Products");
+                }
+                return _Products;
+            }
+        }
+        private ObjectSet<Product> _Products;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Region> Regions
+        {
+            get
+            {
+                if ((_Regions == null))
+                {
+                    _Regions = base.CreateObjectSet<Region>("Regions");
+                }
+                return _Regions;
+            }
+        }
+        private ObjectSet<Region> _Regions;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Shipper> Shippers
+        {
+            get
+            {
+                if ((_Shippers == null))
+                {
+                    _Shippers = base.CreateObjectSet<Shipper>("Shippers");
+                }
+                return _Shippers;
+            }
+        }
+        private ObjectSet<Shipper> _Shippers;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Supplier> Suppliers
+        {
+            get
+            {
+                if ((_Suppliers == null))
+                {
+                    _Suppliers = base.CreateObjectSet<Supplier>("Suppliers");
+                }
+                return _Suppliers;
+            }
+        }
+        private ObjectSet<Supplier> _Suppliers;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Territory> Territories
+        {
+            get
+            {
+                if ((_Territories == null))
+                {
+                    _Territories = base.CreateObjectSet<Territory>("Territories");
+                }
+                return _Territories;
+            }
+        }
+        private ObjectSet<Territory> _Territories;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Alphabetical_list_of_product> Alphabetical_list_of_products
+        {
+            get
+            {
+                if ((_Alphabetical_list_of_products == null))
+                {
+                    _Alphabetical_list_of_products = base.CreateObjectSet<Alphabetical_list_of_product>("Alphabetical_list_of_products");
+                }
+                return _Alphabetical_list_of_products;
+            }
+        }
+        private ObjectSet<Alphabetical_list_of_product> _Alphabetical_list_of_products;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Category_Sales_for_1997> Category_Sales_for_1997
+        {
+            get
+            {
+                if ((_Category_Sales_for_1997 == null))
+                {
+                    _Category_Sales_for_1997 = base.CreateObjectSet<Category_Sales_for_1997>("Category_Sales_for_1997");
+                }
+                return _Category_Sales_for_1997;
+            }
+        }
+        private ObjectSet<Category_Sales_for_1997> _Category_Sales_for_1997;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Current_Product_List> Current_Product_Lists
+        {
+            get
+            {
+                if ((_Current_Product_Lists == null))
+                {
+                    _Current_Product_Lists = base.CreateObjectSet<Current_Product_List>("Current_Product_Lists");
+                }
+                return _Current_Product_Lists;
+            }
+        }
+        private ObjectSet<Current_Product_List> _Current_Product_Lists;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Customer_and_Suppliers_by_City> Customer_and_Suppliers_by_Cities
+        {
+            get
+            {
+                if ((_Customer_and_Suppliers_by_Cities == null))
+                {
+                    _Customer_and_Suppliers_by_Cities = base.CreateObjectSet<Customer_and_Suppliers_by_City>("Customer_and_Suppliers_by_Cities");
+                }
+                return _Customer_and_Suppliers_by_Cities;
+            }
+        }
+        private ObjectSet<Customer_and_Suppliers_by_City> _Customer_and_Suppliers_by_Cities;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Invoice> Invoices
+        {
+            get
+            {
+                if ((_Invoices == null))
+                {
+                    _Invoices = base.CreateObjectSet<Invoice>("Invoices");
+                }
+                return _Invoices;
+            }
+        }
+        private ObjectSet<Invoice> _Invoices;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Order_Details_Extended> Order_Details_Extendeds
+        {
+            get
+            {
+                if ((_Order_Details_Extendeds == null))
+                {
+                    _Order_Details_Extendeds = base.CreateObjectSet<Order_Details_Extended>("Order_Details_Extendeds");
+                }
+                return _Order_Details_Extendeds;
+            }
+        }
+        private ObjectSet<Order_Details_Extended> _Order_Details_Extendeds;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Order_Subtotal> Order_Subtotals
+        {
+            get
+            {
+                if ((_Order_Subtotals == null))
+                {
+                    _Order_Subtotals = base.CreateObjectSet<Order_Subtotal>("Order_Subtotals");
+                }
+                return _Order_Subtotals;
+            }
+        }
+        private ObjectSet<Order_Subtotal> _Order_Subtotals;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Orders_Qry> Orders_Qries
+        {
+            get
+            {
+                if ((_Orders_Qries == null))
+                {
+                    _Orders_Qries = base.CreateObjectSet<Orders_Qry>("Orders_Qries");
+                }
+                return _Orders_Qries;
+            }
+        }
+        private ObjectSet<Orders_Qry> _Orders_Qries;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Product_Sales_for_1997> Product_Sales_for_1997
+        {
+            get
+            {
+                if ((_Product_Sales_for_1997 == null))
+                {
+                    _Product_Sales_for_1997 = base.CreateObjectSet<Product_Sales_for_1997>("Product_Sales_for_1997");
+                }
+                return _Product_Sales_for_1997;
+            }
+        }
+        private ObjectSet<Product_Sales_for_1997> _Product_Sales_for_1997;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Products_Above_Average_Price> Products_Above_Average_Prices
+        {
+            get
+            {
+                if ((_Products_Above_Average_Prices == null))
+                {
+                    _Products_Above_Average_Prices = base.CreateObjectSet<Products_Above_Average_Price>("Products_Above_Average_Prices");
+                }
+                return _Products_Above_Average_Prices;
+            }
+        }
+        private ObjectSet<Products_Above_Average_Price> _Products_Above_Average_Prices;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Products_by_Category> Products_by_Categories
+        {
+            get
+            {
+                if ((_Products_by_Categories == null))
+                {
+                    _Products_by_Categories = base.CreateObjectSet<Products_by_Category>("Products_by_Categories");
+                }
+                return _Products_by_Categories;
+            }
+        }
+        private ObjectSet<Products_by_Category> _Products_by_Categories;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Sales_by_Category> Sales_by_Categories
+        {
+            get
+            {
+                if ((_Sales_by_Categories == null))
+                {
+                    _Sales_by_Categories = base.CreateObjectSet<Sales_by_Category>("Sales_by_Categories");
+                }
+                return _Sales_by_Categories;
+            }
+        }
+        private ObjectSet<Sales_by_Category> _Sales_by_Categories;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Sales_Totals_by_Amount> Sales_Totals_by_Amounts
+        {
+            get
+            {
+                if ((_Sales_Totals_by_Amounts == null))
+                {
+                    _Sales_Totals_by_Amounts = base.CreateObjectSet<Sales_Totals_by_Amount>("Sales_Totals_by_Amounts");
+                }
+                return _Sales_Totals_by_Amounts;
+            }
+        }
+        private ObjectSet<Sales_Totals_by_Amount> _Sales_Totals_by_Amounts;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Summary_of_Sales_by_Quarter> Summary_of_Sales_by_Quarters
+        {
+            get
+            {
+                if ((_Summary_of_Sales_by_Quarters == null))
+                {
+                    _Summary_of_Sales_by_Quarters = base.CreateObjectSet<Summary_of_Sales_by_Quarter>("Summary_of_Sales_by_Quarters");
+                }
+                return _Summary_of_Sales_by_Quarters;
+            }
+        }
+        private ObjectSet<Summary_of_Sales_by_Quarter> _Summary_of_Sales_by_Quarters;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Summary_of_Sales_by_Year> Summary_of_Sales_by_Years
+        {
+            get
+            {
+                if ((_Summary_of_Sales_by_Years == null))
+                {
+                    _Summary_of_Sales_by_Years = base.CreateObjectSet<Summary_of_Sales_by_Year>("Summary_of_Sales_by_Years");
+                }
+                return _Summary_of_Sales_by_Years;
+            }
+        }
+        private ObjectSet<Summary_of_Sales_by_Year> _Summary_of_Sales_by_Years;
+
+        #endregion
+        #region AddTo Methods
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Categories EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToCategories(Category category)
+        {
+            base.AddObject("Categories", category);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the CustomerDemographics EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToCustomerDemographics(CustomerDemographic customerDemographic)
+        {
+            base.AddObject("CustomerDemographics", customerDemographic);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Customers EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToCustomers(Customer customer)
+        {
+            base.AddObject("Customers", customer);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Employees EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToEmployees(Employee employee)
+        {
+            base.AddObject("Employees", employee);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Order_Details EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToOrder_Details(Order_Detail order_Detail)
+        {
+            base.AddObject("Order_Details", order_Detail);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Orders EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToOrders(Order order)
+        {
+            base.AddObject("Orders", order);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Products EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToProducts(Product product)
+        {
+            base.AddObject("Products", product);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Regions EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToRegions(Region region)
+        {
+            base.AddObject("Regions", region);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Shippers EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToShippers(Shipper shipper)
+        {
+            base.AddObject("Shippers", shipper);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Suppliers EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToSuppliers(Supplier supplier)
+        {
+            base.AddObject("Suppliers", supplier);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Territories EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToTerritories(Territory territory)
+        {
+            base.AddObject("Territories", territory);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Alphabetical_list_of_products EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToAlphabetical_list_of_products(Alphabetical_list_of_product alphabetical_list_of_product)
+        {
+            base.AddObject("Alphabetical_list_of_products", alphabetical_list_of_product);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Category_Sales_for_1997 EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToCategory_Sales_for_1997(Category_Sales_for_1997 category_Sales_for_1997)
+        {
+            base.AddObject("Category_Sales_for_1997", category_Sales_for_1997);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Current_Product_Lists EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToCurrent_Product_Lists(Current_Product_List current_Product_List)
+        {
+            base.AddObject("Current_Product_Lists", current_Product_List);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Customer_and_Suppliers_by_Cities EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToCustomer_and_Suppliers_by_Cities(Customer_and_Suppliers_by_City customer_and_Suppliers_by_City)
+        {
+            base.AddObject("Customer_and_Suppliers_by_Cities", customer_and_Suppliers_by_City);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Invoices EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToInvoices(Invoice invoice)
+        {
+            base.AddObject("Invoices", invoice);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Order_Details_Extendeds EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToOrder_Details_Extendeds(Order_Details_Extended order_Details_Extended)
+        {
+            base.AddObject("Order_Details_Extendeds", order_Details_Extended);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Order_Subtotals EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToOrder_Subtotals(Order_Subtotal order_Subtotal)
+        {
+            base.AddObject("Order_Subtotals", order_Subtotal);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Orders_Qries EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToOrders_Qries(Orders_Qry orders_Qry)
+        {
+            base.AddObject("Orders_Qries", orders_Qry);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Product_Sales_for_1997 EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToProduct_Sales_for_1997(Product_Sales_for_1997 product_Sales_for_1997)
+        {
+            base.AddObject("Product_Sales_for_1997", product_Sales_for_1997);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Products_Above_Average_Prices EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToProducts_Above_Average_Prices(Products_Above_Average_Price products_Above_Average_Price)
+        {
+            base.AddObject("Products_Above_Average_Prices", products_Above_Average_Price);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Products_by_Categories EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToProducts_by_Categories(Products_by_Category products_by_Category)
+        {
+            base.AddObject("Products_by_Categories", products_by_Category);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Sales_by_Categories EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToSales_by_Categories(Sales_by_Category sales_by_Category)
+        {
+            base.AddObject("Sales_by_Categories", sales_by_Category);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Sales_Totals_by_Amounts EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToSales_Totals_by_Amounts(Sales_Totals_by_Amount sales_Totals_by_Amount)
+        {
+            base.AddObject("Sales_Totals_by_Amounts", sales_Totals_by_Amount);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Summary_of_Sales_by_Quarters EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToSummary_of_Sales_by_Quarters(Summary_of_Sales_by_Quarter summary_of_Sales_by_Quarter)
+        {
+            base.AddObject("Summary_of_Sales_by_Quarters", summary_of_Sales_by_Quarter);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Summary_of_Sales_by_Years EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead.
+        /// </summary>
+        public void AddToSummary_of_Sales_by_Years(Summary_of_Sales_by_Year summary_of_Sales_by_Year)
+        {
+            base.AddObject("Summary_of_Sales_by_Years", summary_of_Sales_by_Year);
+        }
+
+        #endregion
+    }
+    
+
+    #endregion
+    
+    #region Entities
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Alphabetical_list_of_product")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Alphabetical_list_of_product : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Alphabetical_list_of_product object.
+        /// </summary>
+        /// <param name="productID">Initial value of the ProductID property.</param>
+        /// <param name="productName">Initial value of the ProductName property.</param>
+        /// <param name="discontinued">Initial value of the Discontinued property.</param>
+        /// <param name="categoryName">Initial value of the CategoryName property.</param>
+        public static Alphabetical_list_of_product CreateAlphabetical_list_of_product(global::System.Int32 productID, global::System.String productName, global::System.Boolean discontinued, global::System.String categoryName)
+        {
+            Alphabetical_list_of_product alphabetical_list_of_product = new Alphabetical_list_of_product();
+            alphabetical_list_of_product.ProductID = productID;
+            alphabetical_list_of_product.ProductName = productName;
+            alphabetical_list_of_product.Discontinued = discontinued;
+            alphabetical_list_of_product.CategoryName = categoryName;
+            return alphabetical_list_of_product;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 ProductID
+        {
+            get
+            {
+                return _ProductID;
+            }
+            set
+            {
+                if (_ProductID != value)
+                {
+                    OnProductIDChanging(value);
+                    ReportPropertyChanging("ProductID");
+                    _ProductID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("ProductID");
+                    OnProductIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _ProductID;
+        partial void OnProductIDChanging(global::System.Int32 value);
+        partial void OnProductIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String ProductName
+        {
+            get
+            {
+                return _ProductName;
+            }
+            set
+            {
+                if (_ProductName != value)
+                {
+                    OnProductNameChanging(value);
+                    ReportPropertyChanging("ProductName");
+                    _ProductName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("ProductName");
+                    OnProductNameChanged();
+                }
+            }
+        }
+        private global::System.String _ProductName;
+        partial void OnProductNameChanging(global::System.String value);
+        partial void OnProductNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int32> SupplierID
+        {
+            get
+            {
+                return _SupplierID;
+            }
+            set
+            {
+                OnSupplierIDChanging(value);
+                ReportPropertyChanging("SupplierID");
+                _SupplierID = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("SupplierID");
+                OnSupplierIDChanged();
+            }
+        }
+        private Nullable<global::System.Int32> _SupplierID;
+        partial void OnSupplierIDChanging(Nullable<global::System.Int32> value);
+        partial void OnSupplierIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int32> CategoryID
+        {
+            get
+            {
+                return _CategoryID;
+            }
+            set
+            {
+                OnCategoryIDChanging(value);
+                ReportPropertyChanging("CategoryID");
+                _CategoryID = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("CategoryID");
+                OnCategoryIDChanged();
+            }
+        }
+        private Nullable<global::System.Int32> _CategoryID;
+        partial void OnCategoryIDChanging(Nullable<global::System.Int32> value);
+        partial void OnCategoryIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String QuantityPerUnit
+        {
+            get
+            {
+                return _QuantityPerUnit;
+            }
+            set
+            {
+                OnQuantityPerUnitChanging(value);
+                ReportPropertyChanging("QuantityPerUnit");
+                _QuantityPerUnit = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("QuantityPerUnit");
+                OnQuantityPerUnitChanged();
+            }
+        }
+        private global::System.String _QuantityPerUnit;
+        partial void OnQuantityPerUnitChanging(global::System.String value);
+        partial void OnQuantityPerUnitChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> UnitPrice
+        {
+            get
+            {
+                return _UnitPrice;
+            }
+            set
+            {
+                OnUnitPriceChanging(value);
+                ReportPropertyChanging("UnitPrice");
+                _UnitPrice = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("UnitPrice");
+                OnUnitPriceChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _UnitPrice;
+        partial void OnUnitPriceChanging(Nullable<global::System.Decimal> value);
+        partial void OnUnitPriceChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int16> UnitsInStock
+        {
+            get
+            {
+                return _UnitsInStock;
+            }
+            set
+            {
+                OnUnitsInStockChanging(value);
+                ReportPropertyChanging("UnitsInStock");
+                _UnitsInStock = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("UnitsInStock");
+                OnUnitsInStockChanged();
+            }
+        }
+        private Nullable<global::System.Int16> _UnitsInStock;
+        partial void OnUnitsInStockChanging(Nullable<global::System.Int16> value);
+        partial void OnUnitsInStockChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int16> UnitsOnOrder
+        {
+            get
+            {
+                return _UnitsOnOrder;
+            }
+            set
+            {
+                OnUnitsOnOrderChanging(value);
+                ReportPropertyChanging("UnitsOnOrder");
+                _UnitsOnOrder = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("UnitsOnOrder");
+                OnUnitsOnOrderChanged();
+            }
+        }
+        private Nullable<global::System.Int16> _UnitsOnOrder;
+        partial void OnUnitsOnOrderChanging(Nullable<global::System.Int16> value);
+        partial void OnUnitsOnOrderChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int16> ReorderLevel
+        {
+            get
+            {
+                return _ReorderLevel;
+            }
+            set
+            {
+                OnReorderLevelChanging(value);
+                ReportPropertyChanging("ReorderLevel");
+                _ReorderLevel = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ReorderLevel");
+                OnReorderLevelChanged();
+            }
+        }
+        private Nullable<global::System.Int16> _ReorderLevel;
+        partial void OnReorderLevelChanging(Nullable<global::System.Int16> value);
+        partial void OnReorderLevelChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Boolean Discontinued
+        {
+            get
+            {
+                return _Discontinued;
+            }
+            set
+            {
+                if (_Discontinued != value)
+                {
+                    OnDiscontinuedChanging(value);
+                    ReportPropertyChanging("Discontinued");
+                    _Discontinued = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("Discontinued");
+                    OnDiscontinuedChanged();
+                }
+            }
+        }
+        private global::System.Boolean _Discontinued;
+        partial void OnDiscontinuedChanging(global::System.Boolean value);
+        partial void OnDiscontinuedChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CategoryName
+        {
+            get
+            {
+                return _CategoryName;
+            }
+            set
+            {
+                if (_CategoryName != value)
+                {
+                    OnCategoryNameChanging(value);
+                    ReportPropertyChanging("CategoryName");
+                    _CategoryName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CategoryName");
+                    OnCategoryNameChanged();
+                }
+            }
+        }
+        private global::System.String _CategoryName;
+        partial void OnCategoryNameChanging(global::System.String value);
+        partial void OnCategoryNameChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Category")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Category : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Category object.
+        /// </summary>
+        /// <param name="categoryID">Initial value of the CategoryID property.</param>
+        /// <param name="categoryName">Initial value of the CategoryName property.</param>
+        public static Category CreateCategory(global::System.Int32 categoryID, global::System.String categoryName)
+        {
+            Category category = new Category();
+            category.CategoryID = categoryID;
+            category.CategoryName = categoryName;
+            return category;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 CategoryID
+        {
+            get
+            {
+                return _CategoryID;
+            }
+            set
+            {
+                if (_CategoryID != value)
+                {
+                    OnCategoryIDChanging(value);
+                    ReportPropertyChanging("CategoryID");
+                    _CategoryID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("CategoryID");
+                    OnCategoryIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _CategoryID;
+        partial void OnCategoryIDChanging(global::System.Int32 value);
+        partial void OnCategoryIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CategoryName
+        {
+            get
+            {
+                return _CategoryName;
+            }
+            set
+            {
+                OnCategoryNameChanging(value);
+                ReportPropertyChanging("CategoryName");
+                _CategoryName = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("CategoryName");
+                OnCategoryNameChanged();
+            }
+        }
+        private global::System.String _CategoryName;
+        partial void OnCategoryNameChanging(global::System.String value);
+        partial void OnCategoryNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Description
+        {
+            get
+            {
+                return _Description;
+            }
+            set
+            {
+                OnDescriptionChanging(value);
+                ReportPropertyChanging("Description");
+                _Description = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Description");
+                OnDescriptionChanged();
+            }
+        }
+        private global::System.String _Description;
+        partial void OnDescriptionChanging(global::System.String value);
+        partial void OnDescriptionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.Byte[] Picture
+        {
+            get
+            {
+                return StructuralObject.GetValidValue(_Picture);
+            }
+            set
+            {
+                OnPictureChanging(value);
+                ReportPropertyChanging("Picture");
+                _Picture = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Picture");
+                OnPictureChanged();
+            }
+        }
+        private global::System.Byte[] _Picture;
+        partial void OnPictureChanging(global::System.Byte[] value);
+        partial void OnPictureChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Products_Categories", "Products")]
+        public EntityCollection<Product> Products
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Product>("Northwind.FK_Products_Categories", "Products");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Product>("Northwind.FK_Products_Categories", "Products", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Category_Sales_for_1997")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Category_Sales_for_1997 : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Category_Sales_for_1997 object.
+        /// </summary>
+        /// <param name="categoryName">Initial value of the CategoryName property.</param>
+        public static Category_Sales_for_1997 CreateCategory_Sales_for_1997(global::System.String categoryName)
+        {
+            Category_Sales_for_1997 category_Sales_for_1997 = new Category_Sales_for_1997();
+            category_Sales_for_1997.CategoryName = categoryName;
+            return category_Sales_for_1997;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CategoryName
+        {
+            get
+            {
+                return _CategoryName;
+            }
+            set
+            {
+                if (_CategoryName != value)
+                {
+                    OnCategoryNameChanging(value);
+                    ReportPropertyChanging("CategoryName");
+                    _CategoryName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CategoryName");
+                    OnCategoryNameChanged();
+                }
+            }
+        }
+        private global::System.String _CategoryName;
+        partial void OnCategoryNameChanging(global::System.String value);
+        partial void OnCategoryNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> CategorySales
+        {
+            get
+            {
+                return _CategorySales;
+            }
+            set
+            {
+                OnCategorySalesChanging(value);
+                ReportPropertyChanging("CategorySales");
+                _CategorySales = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("CategorySales");
+                OnCategorySalesChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _CategorySales;
+        partial void OnCategorySalesChanging(Nullable<global::System.Decimal> value);
+        partial void OnCategorySalesChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Current_Product_List")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Current_Product_List : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Current_Product_List object.
+        /// </summary>
+        /// <param name="productID">Initial value of the ProductID property.</param>
+        /// <param name="productName">Initial value of the ProductName property.</param>
+        public static Current_Product_List CreateCurrent_Product_List(global::System.Int32 productID, global::System.String productName)
+        {
+            Current_Product_List current_Product_List = new Current_Product_List();
+            current_Product_List.ProductID = productID;
+            current_Product_List.ProductName = productName;
+            return current_Product_List;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 ProductID
+        {
+            get
+            {
+                return _ProductID;
+            }
+            set
+            {
+                if (_ProductID != value)
+                {
+                    OnProductIDChanging(value);
+                    ReportPropertyChanging("ProductID");
+                    _ProductID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("ProductID");
+                    OnProductIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _ProductID;
+        partial void OnProductIDChanging(global::System.Int32 value);
+        partial void OnProductIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String ProductName
+        {
+            get
+            {
+                return _ProductName;
+            }
+            set
+            {
+                if (_ProductName != value)
+                {
+                    OnProductNameChanging(value);
+                    ReportPropertyChanging("ProductName");
+                    _ProductName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("ProductName");
+                    OnProductNameChanged();
+                }
+            }
+        }
+        private global::System.String _ProductName;
+        partial void OnProductNameChanging(global::System.String value);
+        partial void OnProductNameChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Customer")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Customer : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Customer object.
+        /// </summary>
+        /// <param name="customerID">Initial value of the CustomerID property.</param>
+        /// <param name="companyName">Initial value of the CompanyName property.</param>
+        public static Customer CreateCustomer(global::System.String customerID, global::System.String companyName)
+        {
+            Customer customer = new Customer();
+            customer.CustomerID = customerID;
+            customer.CompanyName = companyName;
+            return customer;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CustomerID
+        {
+            get
+            {
+                return _CustomerID;
+            }
+            set
+            {
+                if (_CustomerID != value)
+                {
+                    OnCustomerIDChanging(value);
+                    ReportPropertyChanging("CustomerID");
+                    _CustomerID = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CustomerID");
+                    OnCustomerIDChanged();
+                }
+            }
+        }
+        private global::System.String _CustomerID;
+        partial void OnCustomerIDChanging(global::System.String value);
+        partial void OnCustomerIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CompanyName
+        {
+            get
+            {
+                return _CompanyName;
+            }
+            set
+            {
+                OnCompanyNameChanging(value);
+                ReportPropertyChanging("CompanyName");
+                _CompanyName = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("CompanyName");
+                OnCompanyNameChanged();
+            }
+        }
+        private global::System.String _CompanyName;
+        partial void OnCompanyNameChanging(global::System.String value);
+        partial void OnCompanyNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ContactName
+        {
+            get
+            {
+                return _ContactName;
+            }
+            set
+            {
+                OnContactNameChanging(value);
+                ReportPropertyChanging("ContactName");
+                _ContactName = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ContactName");
+                OnContactNameChanged();
+            }
+        }
+        private global::System.String _ContactName;
+        partial void OnContactNameChanging(global::System.String value);
+        partial void OnContactNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ContactTitle
+        {
+            get
+            {
+                return _ContactTitle;
+            }
+            set
+            {
+                OnContactTitleChanging(value);
+                ReportPropertyChanging("ContactTitle");
+                _ContactTitle = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ContactTitle");
+                OnContactTitleChanged();
+            }
+        }
+        private global::System.String _ContactTitle;
+        partial void OnContactTitleChanging(global::System.String value);
+        partial void OnContactTitleChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Address
+        {
+            get
+            {
+                return _Address;
+            }
+            set
+            {
+                OnAddressChanging(value);
+                ReportPropertyChanging("Address");
+                _Address = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Address");
+                OnAddressChanged();
+            }
+        }
+        private global::System.String _Address;
+        partial void OnAddressChanging(global::System.String value);
+        partial void OnAddressChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String City
+        {
+            get
+            {
+                return _City;
+            }
+            set
+            {
+                OnCityChanging(value);
+                ReportPropertyChanging("City");
+                _City = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("City");
+                OnCityChanged();
+            }
+        }
+        private global::System.String _City;
+        partial void OnCityChanging(global::System.String value);
+        partial void OnCityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Region
+        {
+            get
+            {
+                return _Region;
+            }
+            set
+            {
+                OnRegionChanging(value);
+                ReportPropertyChanging("Region");
+                _Region = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Region");
+                OnRegionChanged();
+            }
+        }
+        private global::System.String _Region;
+        partial void OnRegionChanging(global::System.String value);
+        partial void OnRegionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String PostalCode
+        {
+            get
+            {
+                return _PostalCode;
+            }
+            set
+            {
+                OnPostalCodeChanging(value);
+                ReportPropertyChanging("PostalCode");
+                _PostalCode = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("PostalCode");
+                OnPostalCodeChanged();
+            }
+        }
+        private global::System.String _PostalCode;
+        partial void OnPostalCodeChanging(global::System.String value);
+        partial void OnPostalCodeChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Country
+        {
+            get
+            {
+                return _Country;
+            }
+            set
+            {
+                OnCountryChanging(value);
+                ReportPropertyChanging("Country");
+                _Country = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Country");
+                OnCountryChanged();
+            }
+        }
+        private global::System.String _Country;
+        partial void OnCountryChanging(global::System.String value);
+        partial void OnCountryChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Phone
+        {
+            get
+            {
+                return _Phone;
+            }
+            set
+            {
+                OnPhoneChanging(value);
+                ReportPropertyChanging("Phone");
+                _Phone = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Phone");
+                OnPhoneChanged();
+            }
+        }
+        private global::System.String _Phone;
+        partial void OnPhoneChanging(global::System.String value);
+        partial void OnPhoneChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Fax
+        {
+            get
+            {
+                return _Fax;
+            }
+            set
+            {
+                OnFaxChanging(value);
+                ReportPropertyChanging("Fax");
+                _Fax = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Fax");
+                OnFaxChanged();
+            }
+        }
+        private global::System.String _Fax;
+        partial void OnFaxChanging(global::System.String value);
+        partial void OnFaxChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Orders_Customers", "Orders")]
+        public EntityCollection<Order> Orders
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Order>("Northwind.FK_Orders_Customers", "Orders");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Order>("Northwind.FK_Orders_Customers", "Orders", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "CustomerCustomerDemo", "CustomerDemographics")]
+        public EntityCollection<CustomerDemographic> CustomerDemographics
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<CustomerDemographic>("Northwind.CustomerCustomerDemo", "CustomerDemographics");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<CustomerDemographic>("Northwind.CustomerCustomerDemo", "CustomerDemographics", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Customer_and_Suppliers_by_City")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Customer_and_Suppliers_by_City : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Customer_and_Suppliers_by_City object.
+        /// </summary>
+        /// <param name="companyName">Initial value of the CompanyName property.</param>
+        /// <param name="relationship">Initial value of the Relationship property.</param>
+        public static Customer_and_Suppliers_by_City CreateCustomer_and_Suppliers_by_City(global::System.String companyName, global::System.String relationship)
+        {
+            Customer_and_Suppliers_by_City customer_and_Suppliers_by_City = new Customer_and_Suppliers_by_City();
+            customer_and_Suppliers_by_City.CompanyName = companyName;
+            customer_and_Suppliers_by_City.Relationship = relationship;
+            return customer_and_Suppliers_by_City;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String City
+        {
+            get
+            {
+                return _City;
+            }
+            set
+            {
+                OnCityChanging(value);
+                ReportPropertyChanging("City");
+                _City = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("City");
+                OnCityChanged();
+            }
+        }
+        private global::System.String _City;
+        partial void OnCityChanging(global::System.String value);
+        partial void OnCityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CompanyName
+        {
+            get
+            {
+                return _CompanyName;
+            }
+            set
+            {
+                if (_CompanyName != value)
+                {
+                    OnCompanyNameChanging(value);
+                    ReportPropertyChanging("CompanyName");
+                    _CompanyName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CompanyName");
+                    OnCompanyNameChanged();
+                }
+            }
+        }
+        private global::System.String _CompanyName;
+        partial void OnCompanyNameChanging(global::System.String value);
+        partial void OnCompanyNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ContactName
+        {
+            get
+            {
+                return _ContactName;
+            }
+            set
+            {
+                OnContactNameChanging(value);
+                ReportPropertyChanging("ContactName");
+                _ContactName = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ContactName");
+                OnContactNameChanged();
+            }
+        }
+        private global::System.String _ContactName;
+        partial void OnContactNameChanging(global::System.String value);
+        partial void OnContactNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String Relationship
+        {
+            get
+            {
+                return _Relationship;
+            }
+            set
+            {
+                if (_Relationship != value)
+                {
+                    OnRelationshipChanging(value);
+                    ReportPropertyChanging("Relationship");
+                    _Relationship = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("Relationship");
+                    OnRelationshipChanged();
+                }
+            }
+        }
+        private global::System.String _Relationship;
+        partial void OnRelationshipChanging(global::System.String value);
+        partial void OnRelationshipChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="CustomerDemographic")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class CustomerDemographic : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new CustomerDemographic object.
+        /// </summary>
+        /// <param name="customerTypeID">Initial value of the CustomerTypeID property.</param>
+        public static CustomerDemographic CreateCustomerDemographic(global::System.String customerTypeID)
+        {
+            CustomerDemographic customerDemographic = new CustomerDemographic();
+            customerDemographic.CustomerTypeID = customerTypeID;
+            return customerDemographic;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CustomerTypeID
+        {
+            get
+            {
+                return _CustomerTypeID;
+            }
+            set
+            {
+                if (_CustomerTypeID != value)
+                {
+                    OnCustomerTypeIDChanging(value);
+                    ReportPropertyChanging("CustomerTypeID");
+                    _CustomerTypeID = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CustomerTypeID");
+                    OnCustomerTypeIDChanged();
+                }
+            }
+        }
+        private global::System.String _CustomerTypeID;
+        partial void OnCustomerTypeIDChanging(global::System.String value);
+        partial void OnCustomerTypeIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String CustomerDesc
+        {
+            get
+            {
+                return _CustomerDesc;
+            }
+            set
+            {
+                OnCustomerDescChanging(value);
+                ReportPropertyChanging("CustomerDesc");
+                _CustomerDesc = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("CustomerDesc");
+                OnCustomerDescChanged();
+            }
+        }
+        private global::System.String _CustomerDesc;
+        partial void OnCustomerDescChanging(global::System.String value);
+        partial void OnCustomerDescChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "CustomerCustomerDemo", "Customers")]
+        public EntityCollection<Customer> Customers
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Customer>("Northwind.CustomerCustomerDemo", "Customers");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Customer>("Northwind.CustomerCustomerDemo", "Customers", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Employee")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Employee : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Employee object.
+        /// </summary>
+        /// <param name="employeeID">Initial value of the EmployeeID property.</param>
+        /// <param name="lastName">Initial value of the LastName property.</param>
+        /// <param name="firstName">Initial value of the FirstName property.</param>
+        public static Employee CreateEmployee(global::System.Int32 employeeID, global::System.String lastName, global::System.String firstName)
+        {
+            Employee employee = new Employee();
+            employee.EmployeeID = employeeID;
+            employee.LastName = lastName;
+            employee.FirstName = firstName;
+            return employee;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 EmployeeID
+        {
+            get
+            {
+                return _EmployeeID;
+            }
+            set
+            {
+                if (_EmployeeID != value)
+                {
+                    OnEmployeeIDChanging(value);
+                    ReportPropertyChanging("EmployeeID");
+                    _EmployeeID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("EmployeeID");
+                    OnEmployeeIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _EmployeeID;
+        partial void OnEmployeeIDChanging(global::System.Int32 value);
+        partial void OnEmployeeIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String LastName
+        {
+            get
+            {
+                return _LastName;
+            }
+            set
+            {
+                OnLastNameChanging(value);
+                ReportPropertyChanging("LastName");
+                _LastName = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("LastName");
+                OnLastNameChanged();
+            }
+        }
+        private global::System.String _LastName;
+        partial void OnLastNameChanging(global::System.String value);
+        partial void OnLastNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String FirstName
+        {
+            get
+            {
+                return _FirstName;
+            }
+            set
+            {
+                OnFirstNameChanging(value);
+                ReportPropertyChanging("FirstName");
+                _FirstName = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("FirstName");
+                OnFirstNameChanged();
+            }
+        }
+        private global::System.String _FirstName;
+        partial void OnFirstNameChanging(global::System.String value);
+        partial void OnFirstNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Title
+        {
+            get
+            {
+                return _Title;
+            }
+            set
+            {
+                OnTitleChanging(value);
+                ReportPropertyChanging("Title");
+                _Title = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Title");
+                OnTitleChanged();
+            }
+        }
+        private global::System.String _Title;
+        partial void OnTitleChanging(global::System.String value);
+        partial void OnTitleChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String TitleOfCourtesy
+        {
+            get
+            {
+                return _TitleOfCourtesy;
+            }
+            set
+            {
+                OnTitleOfCourtesyChanging(value);
+                ReportPropertyChanging("TitleOfCourtesy");
+                _TitleOfCourtesy = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("TitleOfCourtesy");
+                OnTitleOfCourtesyChanged();
+            }
+        }
+        private global::System.String _TitleOfCourtesy;
+        partial void OnTitleOfCourtesyChanging(global::System.String value);
+        partial void OnTitleOfCourtesyChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> BirthDate
+        {
+            get
+            {
+                return _BirthDate;
+            }
+            set
+            {
+                OnBirthDateChanging(value);
+                ReportPropertyChanging("BirthDate");
+                _BirthDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("BirthDate");
+                OnBirthDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _BirthDate;
+        partial void OnBirthDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnBirthDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> HireDate
+        {
+            get
+            {
+                return _HireDate;
+            }
+            set
+            {
+                OnHireDateChanging(value);
+                ReportPropertyChanging("HireDate");
+                _HireDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("HireDate");
+                OnHireDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _HireDate;
+        partial void OnHireDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnHireDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Address
+        {
+            get
+            {
+                return _Address;
+            }
+            set
+            {
+                OnAddressChanging(value);
+                ReportPropertyChanging("Address");
+                _Address = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Address");
+                OnAddressChanged();
+            }
+        }
+        private global::System.String _Address;
+        partial void OnAddressChanging(global::System.String value);
+        partial void OnAddressChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String City
+        {
+            get
+            {
+                return _City;
+            }
+            set
+            {
+                OnCityChanging(value);
+                ReportPropertyChanging("City");
+                _City = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("City");
+                OnCityChanged();
+            }
+        }
+        private global::System.String _City;
+        partial void OnCityChanging(global::System.String value);
+        partial void OnCityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Region
+        {
+            get
+            {
+                return _Region;
+            }
+            set
+            {
+                OnRegionChanging(value);
+                ReportPropertyChanging("Region");
+                _Region = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Region");
+                OnRegionChanged();
+            }
+        }
+        private global::System.String _Region;
+        partial void OnRegionChanging(global::System.String value);
+        partial void OnRegionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String PostalCode
+        {
+            get
+            {
+                return _PostalCode;
+            }
+            set
+            {
+                OnPostalCodeChanging(value);
+                ReportPropertyChanging("PostalCode");
+                _PostalCode = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("PostalCode");
+                OnPostalCodeChanged();
+            }
+        }
+        private global::System.String _PostalCode;
+        partial void OnPostalCodeChanging(global::System.String value);
+        partial void OnPostalCodeChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Country
+        {
+            get
+            {
+                return _Country;
+            }
+            set
+            {
+                OnCountryChanging(value);
+                ReportPropertyChanging("Country");
+                _Country = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Country");
+                OnCountryChanged();
+            }
+        }
+        private global::System.String _Country;
+        partial void OnCountryChanging(global::System.String value);
+        partial void OnCountryChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String HomePhone
+        {
+            get
+            {
+                return _HomePhone;
+            }
+            set
+            {
+                OnHomePhoneChanging(value);
+                ReportPropertyChanging("HomePhone");
+                _HomePhone = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("HomePhone");
+                OnHomePhoneChanged();
+            }
+        }
+        private global::System.String _HomePhone;
+        partial void OnHomePhoneChanging(global::System.String value);
+        partial void OnHomePhoneChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Extension
+        {
+            get
+            {
+                return _Extension;
+            }
+            set
+            {
+                OnExtensionChanging(value);
+                ReportPropertyChanging("Extension");
+                _Extension = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Extension");
+                OnExtensionChanged();
+            }
+        }
+        private global::System.String _Extension;
+        partial void OnExtensionChanging(global::System.String value);
+        partial void OnExtensionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.Byte[] Photo
+        {
+            get
+            {
+                return StructuralObject.GetValidValue(_Photo);
+            }
+            set
+            {
+                OnPhotoChanging(value);
+                ReportPropertyChanging("Photo");
+                _Photo = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Photo");
+                OnPhotoChanged();
+            }
+        }
+        private global::System.Byte[] _Photo;
+        partial void OnPhotoChanging(global::System.Byte[] value);
+        partial void OnPhotoChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Notes
+        {
+            get
+            {
+                return _Notes;
+            }
+            set
+            {
+                OnNotesChanging(value);
+                ReportPropertyChanging("Notes");
+                _Notes = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Notes");
+                OnNotesChanged();
+            }
+        }
+        private global::System.String _Notes;
+        partial void OnNotesChanging(global::System.String value);
+        partial void OnNotesChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int32> ReportsTo
+        {
+            get
+            {
+                return _ReportsTo;
+            }
+            set
+            {
+                OnReportsToChanging(value);
+                ReportPropertyChanging("ReportsTo");
+                _ReportsTo = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ReportsTo");
+                OnReportsToChanged();
+            }
+        }
+        private Nullable<global::System.Int32> _ReportsTo;
+        partial void OnReportsToChanging(Nullable<global::System.Int32> value);
+        partial void OnReportsToChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String PhotoPath
+        {
+            get
+            {
+                return _PhotoPath;
+            }
+            set
+            {
+                OnPhotoPathChanging(value);
+                ReportPropertyChanging("PhotoPath");
+                _PhotoPath = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("PhotoPath");
+                OnPhotoPathChanged();
+            }
+        }
+        private global::System.String _PhotoPath;
+        partial void OnPhotoPathChanging(global::System.String value);
+        partial void OnPhotoPathChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Employees_Employees", "Employees1")]
+        public EntityCollection<Employee> Employees1
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Employee>("Northwind.FK_Employees_Employees", "Employees1");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Employee>("Northwind.FK_Employees_Employees", "Employees1", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Employees_Employees", "Employees")]
+        public Employee Employee1
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Employee>("Northwind.FK_Employees_Employees", "Employees").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Employee>("Northwind.FK_Employees_Employees", "Employees").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Employee> Employee1Reference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Employee>("Northwind.FK_Employees_Employees", "Employees");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Employee>("Northwind.FK_Employees_Employees", "Employees", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Orders_Employees", "Orders")]
+        public EntityCollection<Order> Orders
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Order>("Northwind.FK_Orders_Employees", "Orders");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Order>("Northwind.FK_Orders_Employees", "Orders", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "EmployeeTerritories", "Territories")]
+        public EntityCollection<Territory> Territories
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Territory>("Northwind.EmployeeTerritories", "Territories");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Territory>("Northwind.EmployeeTerritories", "Territories", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Invoice")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Invoice : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Invoice object.
+        /// </summary>
+        /// <param name="customerName">Initial value of the CustomerName property.</param>
+        /// <param name="salesperson">Initial value of the Salesperson property.</param>
+        /// <param name="orderID">Initial value of the OrderID property.</param>
+        /// <param name="shipperName">Initial value of the ShipperName property.</param>
+        /// <param name="productID">Initial value of the ProductID property.</param>
+        /// <param name="productName">Initial value of the ProductName property.</param>
+        /// <param name="unitPrice">Initial value of the UnitPrice property.</param>
+        /// <param name="quantity">Initial value of the Quantity property.</param>
+        /// <param name="discount">Initial value of the Discount property.</param>
+        public static Invoice CreateInvoice(global::System.String customerName, global::System.String salesperson, global::System.Int32 orderID, global::System.String shipperName, global::System.Int32 productID, global::System.String productName, global::System.Decimal unitPrice, global::System.Int16 quantity, global::System.Single discount)
+        {
+            Invoice invoice = new Invoice();
+            invoice.CustomerName = customerName;
+            invoice.Salesperson = salesperson;
+            invoice.OrderID = orderID;
+            invoice.ShipperName = shipperName;
+            invoice.ProductID = productID;
+            invoice.ProductName = productName;
+            invoice.UnitPrice = unitPrice;
+            invoice.Quantity = quantity;
+            invoice.Discount = discount;
+            return invoice;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipName
+        {
+            get
+            {
+                return _ShipName;
+            }
+            set
+            {
+                OnShipNameChanging(value);
+                ReportPropertyChanging("ShipName");
+                _ShipName = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipName");
+                OnShipNameChanged();
+            }
+        }
+        private global::System.String _ShipName;
+        partial void OnShipNameChanging(global::System.String value);
+        partial void OnShipNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipAddress
+        {
+            get
+            {
+                return _ShipAddress;
+            }
+            set
+            {
+                OnShipAddressChanging(value);
+                ReportPropertyChanging("ShipAddress");
+                _ShipAddress = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipAddress");
+                OnShipAddressChanged();
+            }
+        }
+        private global::System.String _ShipAddress;
+        partial void OnShipAddressChanging(global::System.String value);
+        partial void OnShipAddressChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipCity
+        {
+            get
+            {
+                return _ShipCity;
+            }
+            set
+            {
+                OnShipCityChanging(value);
+                ReportPropertyChanging("ShipCity");
+                _ShipCity = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipCity");
+                OnShipCityChanged();
+            }
+        }
+        private global::System.String _ShipCity;
+        partial void OnShipCityChanging(global::System.String value);
+        partial void OnShipCityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipRegion
+        {
+            get
+            {
+                return _ShipRegion;
+            }
+            set
+            {
+                OnShipRegionChanging(value);
+                ReportPropertyChanging("ShipRegion");
+                _ShipRegion = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipRegion");
+                OnShipRegionChanged();
+            }
+        }
+        private global::System.String _ShipRegion;
+        partial void OnShipRegionChanging(global::System.String value);
+        partial void OnShipRegionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipPostalCode
+        {
+            get
+            {
+                return _ShipPostalCode;
+            }
+            set
+            {
+                OnShipPostalCodeChanging(value);
+                ReportPropertyChanging("ShipPostalCode");
+                _ShipPostalCode = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipPostalCode");
+                OnShipPostalCodeChanged();
+            }
+        }
+        private global::System.String _ShipPostalCode;
+        partial void OnShipPostalCodeChanging(global::System.String value);
+        partial void OnShipPostalCodeChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipCountry
+        {
+            get
+            {
+                return _ShipCountry;
+            }
+            set
+            {
+                OnShipCountryChanging(value);
+                ReportPropertyChanging("ShipCountry");
+                _ShipCountry = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipCountry");
+                OnShipCountryChanged();
+            }
+        }
+        private global::System.String _ShipCountry;
+        partial void OnShipCountryChanging(global::System.String value);
+        partial void OnShipCountryChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String CustomerID
+        {
+            get
+            {
+                return _CustomerID;
+            }
+            set
+            {
+                OnCustomerIDChanging(value);
+                ReportPropertyChanging("CustomerID");
+                _CustomerID = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("CustomerID");
+                OnCustomerIDChanged();
+            }
+        }
+        private global::System.String _CustomerID;
+        partial void OnCustomerIDChanging(global::System.String value);
+        partial void OnCustomerIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CustomerName
+        {
+            get
+            {
+                return _CustomerName;
+            }
+            set
+            {
+                if (_CustomerName != value)
+                {
+                    OnCustomerNameChanging(value);
+                    ReportPropertyChanging("CustomerName");
+                    _CustomerName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CustomerName");
+                    OnCustomerNameChanged();
+                }
+            }
+        }
+        private global::System.String _CustomerName;
+        partial void OnCustomerNameChanging(global::System.String value);
+        partial void OnCustomerNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Address
+        {
+            get
+            {
+                return _Address;
+            }
+            set
+            {
+                OnAddressChanging(value);
+                ReportPropertyChanging("Address");
+                _Address = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Address");
+                OnAddressChanged();
+            }
+        }
+        private global::System.String _Address;
+        partial void OnAddressChanging(global::System.String value);
+        partial void OnAddressChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String City
+        {
+            get
+            {
+                return _City;
+            }
+            set
+            {
+                OnCityChanging(value);
+                ReportPropertyChanging("City");
+                _City = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("City");
+                OnCityChanged();
+            }
+        }
+        private global::System.String _City;
+        partial void OnCityChanging(global::System.String value);
+        partial void OnCityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Region
+        {
+            get
+            {
+                return _Region;
+            }
+            set
+            {
+                OnRegionChanging(value);
+                ReportPropertyChanging("Region");
+                _Region = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Region");
+                OnRegionChanged();
+            }
+        }
+        private global::System.String _Region;
+        partial void OnRegionChanging(global::System.String value);
+        partial void OnRegionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String PostalCode
+        {
+            get
+            {
+                return _PostalCode;
+            }
+            set
+            {
+                OnPostalCodeChanging(value);
+                ReportPropertyChanging("PostalCode");
+                _PostalCode = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("PostalCode");
+                OnPostalCodeChanged();
+            }
+        }
+        private global::System.String _PostalCode;
+        partial void OnPostalCodeChanging(global::System.String value);
+        partial void OnPostalCodeChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Country
+        {
+            get
+            {
+                return _Country;
+            }
+            set
+            {
+                OnCountryChanging(value);
+                ReportPropertyChanging("Country");
+                _Country = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Country");
+                OnCountryChanged();
+            }
+        }
+        private global::System.String _Country;
+        partial void OnCountryChanging(global::System.String value);
+        partial void OnCountryChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String Salesperson
+        {
+            get
+            {
+                return _Salesperson;
+            }
+            set
+            {
+                if (_Salesperson != value)
+                {
+                    OnSalespersonChanging(value);
+                    ReportPropertyChanging("Salesperson");
+                    _Salesperson = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("Salesperson");
+                    OnSalespersonChanged();
+                }
+            }
+        }
+        private global::System.String _Salesperson;
+        partial void OnSalespersonChanging(global::System.String value);
+        partial void OnSalespersonChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 OrderID
+        {
+            get
+            {
+                return _OrderID;
+            }
+            set
+            {
+                if (_OrderID != value)
+                {
+                    OnOrderIDChanging(value);
+                    ReportPropertyChanging("OrderID");
+                    _OrderID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("OrderID");
+                    OnOrderIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _OrderID;
+        partial void OnOrderIDChanging(global::System.Int32 value);
+        partial void OnOrderIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> OrderDate
+        {
+            get
+            {
+                return _OrderDate;
+            }
+            set
+            {
+                OnOrderDateChanging(value);
+                ReportPropertyChanging("OrderDate");
+                _OrderDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("OrderDate");
+                OnOrderDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _OrderDate;
+        partial void OnOrderDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnOrderDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> RequiredDate
+        {
+            get
+            {
+                return _RequiredDate;
+            }
+            set
+            {
+                OnRequiredDateChanging(value);
+                ReportPropertyChanging("RequiredDate");
+                _RequiredDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("RequiredDate");
+                OnRequiredDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _RequiredDate;
+        partial void OnRequiredDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnRequiredDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> ShippedDate
+        {
+            get
+            {
+                return _ShippedDate;
+            }
+            set
+            {
+                OnShippedDateChanging(value);
+                ReportPropertyChanging("ShippedDate");
+                _ShippedDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ShippedDate");
+                OnShippedDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _ShippedDate;
+        partial void OnShippedDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnShippedDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String ShipperName
+        {
+            get
+            {
+                return _ShipperName;
+            }
+            set
+            {
+                if (_ShipperName != value)
+                {
+                    OnShipperNameChanging(value);
+                    ReportPropertyChanging("ShipperName");
+                    _ShipperName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("ShipperName");
+                    OnShipperNameChanged();
+                }
+            }
+        }
+        private global::System.String _ShipperName;
+        partial void OnShipperNameChanging(global::System.String value);
+        partial void OnShipperNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 ProductID
+        {
+            get
+            {
+                return _ProductID;
+            }
+            set
+            {
+                if (_ProductID != value)
+                {
+                    OnProductIDChanging(value);
+                    ReportPropertyChanging("ProductID");
+                    _ProductID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("ProductID");
+                    OnProductIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _ProductID;
+        partial void OnProductIDChanging(global::System.Int32 value);
+        partial void OnProductIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String ProductName
+        {
+            get
+            {
+                return _ProductName;
+            }
+            set
+            {
+                if (_ProductName != value)
+                {
+                    OnProductNameChanging(value);
+                    ReportPropertyChanging("ProductName");
+                    _ProductName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("ProductName");
+                    OnProductNameChanged();
+                }
+            }
+        }
+        private global::System.String _ProductName;
+        partial void OnProductNameChanging(global::System.String value);
+        partial void OnProductNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Decimal UnitPrice
+        {
+            get
+            {
+                return _UnitPrice;
+            }
+            set
+            {
+                if (_UnitPrice != value)
+                {
+                    OnUnitPriceChanging(value);
+                    ReportPropertyChanging("UnitPrice");
+                    _UnitPrice = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("UnitPrice");
+                    OnUnitPriceChanged();
+                }
+            }
+        }
+        private global::System.Decimal _UnitPrice;
+        partial void OnUnitPriceChanging(global::System.Decimal value);
+        partial void OnUnitPriceChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int16 Quantity
+        {
+            get
+            {
+                return _Quantity;
+            }
+            set
+            {
+                if (_Quantity != value)
+                {
+                    OnQuantityChanging(value);
+                    ReportPropertyChanging("Quantity");
+                    _Quantity = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("Quantity");
+                    OnQuantityChanged();
+                }
+            }
+        }
+        private global::System.Int16 _Quantity;
+        partial void OnQuantityChanging(global::System.Int16 value);
+        partial void OnQuantityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Single Discount
+        {
+            get
+            {
+                return _Discount;
+            }
+            set
+            {
+                if (_Discount != value)
+                {
+                    OnDiscountChanging(value);
+                    ReportPropertyChanging("Discount");
+                    _Discount = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("Discount");
+                    OnDiscountChanged();
+                }
+            }
+        }
+        private global::System.Single _Discount;
+        partial void OnDiscountChanging(global::System.Single value);
+        partial void OnDiscountChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> ExtendedPrice
+        {
+            get
+            {
+                return _ExtendedPrice;
+            }
+            set
+            {
+                OnExtendedPriceChanging(value);
+                ReportPropertyChanging("ExtendedPrice");
+                _ExtendedPrice = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ExtendedPrice");
+                OnExtendedPriceChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _ExtendedPrice;
+        partial void OnExtendedPriceChanging(Nullable<global::System.Decimal> value);
+        partial void OnExtendedPriceChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> Freight
+        {
+            get
+            {
+                return _Freight;
+            }
+            set
+            {
+                OnFreightChanging(value);
+                ReportPropertyChanging("Freight");
+                _Freight = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("Freight");
+                OnFreightChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _Freight;
+        partial void OnFreightChanging(Nullable<global::System.Decimal> value);
+        partial void OnFreightChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Order")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Order : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Order object.
+        /// </summary>
+        /// <param name="orderID">Initial value of the OrderID property.</param>
+        public static Order CreateOrder(global::System.Int32 orderID)
+        {
+            Order order = new Order();
+            order.OrderID = orderID;
+            return order;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 OrderID
+        {
+            get
+            {
+                return _OrderID;
+            }
+            set
+            {
+                if (_OrderID != value)
+                {
+                    OnOrderIDChanging(value);
+                    ReportPropertyChanging("OrderID");
+                    _OrderID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("OrderID");
+                    OnOrderIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _OrderID;
+        partial void OnOrderIDChanging(global::System.Int32 value);
+        partial void OnOrderIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String CustomerID
+        {
+            get
+            {
+                return _CustomerID;
+            }
+            set
+            {
+                OnCustomerIDChanging(value);
+                ReportPropertyChanging("CustomerID");
+                _CustomerID = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("CustomerID");
+                OnCustomerIDChanged();
+            }
+        }
+        private global::System.String _CustomerID;
+        partial void OnCustomerIDChanging(global::System.String value);
+        partial void OnCustomerIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int32> EmployeeID
+        {
+            get
+            {
+                return _EmployeeID;
+            }
+            set
+            {
+                OnEmployeeIDChanging(value);
+                ReportPropertyChanging("EmployeeID");
+                _EmployeeID = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("EmployeeID");
+                OnEmployeeIDChanged();
+            }
+        }
+        private Nullable<global::System.Int32> _EmployeeID;
+        partial void OnEmployeeIDChanging(Nullable<global::System.Int32> value);
+        partial void OnEmployeeIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> OrderDate
+        {
+            get
+            {
+                return _OrderDate;
+            }
+            set
+            {
+                OnOrderDateChanging(value);
+                ReportPropertyChanging("OrderDate");
+                _OrderDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("OrderDate");
+                OnOrderDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _OrderDate;
+        partial void OnOrderDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnOrderDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> RequiredDate
+        {
+            get
+            {
+                return _RequiredDate;
+            }
+            set
+            {
+                OnRequiredDateChanging(value);
+                ReportPropertyChanging("RequiredDate");
+                _RequiredDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("RequiredDate");
+                OnRequiredDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _RequiredDate;
+        partial void OnRequiredDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnRequiredDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> ShippedDate
+        {
+            get
+            {
+                return _ShippedDate;
+            }
+            set
+            {
+                OnShippedDateChanging(value);
+                ReportPropertyChanging("ShippedDate");
+                _ShippedDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ShippedDate");
+                OnShippedDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _ShippedDate;
+        partial void OnShippedDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnShippedDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int32> ShipVia
+        {
+            get
+            {
+                return _ShipVia;
+            }
+            set
+            {
+                OnShipViaChanging(value);
+                ReportPropertyChanging("ShipVia");
+                _ShipVia = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ShipVia");
+                OnShipViaChanged();
+            }
+        }
+        private Nullable<global::System.Int32> _ShipVia;
+        partial void OnShipViaChanging(Nullable<global::System.Int32> value);
+        partial void OnShipViaChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> Freight
+        {
+            get
+            {
+                return _Freight;
+            }
+            set
+            {
+                OnFreightChanging(value);
+                ReportPropertyChanging("Freight");
+                _Freight = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("Freight");
+                OnFreightChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _Freight;
+        partial void OnFreightChanging(Nullable<global::System.Decimal> value);
+        partial void OnFreightChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipName
+        {
+            get
+            {
+                return _ShipName;
+            }
+            set
+            {
+                OnShipNameChanging(value);
+                ReportPropertyChanging("ShipName");
+                _ShipName = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipName");
+                OnShipNameChanged();
+            }
+        }
+        private global::System.String _ShipName;
+        partial void OnShipNameChanging(global::System.String value);
+        partial void OnShipNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipAddress
+        {
+            get
+            {
+                return _ShipAddress;
+            }
+            set
+            {
+                OnShipAddressChanging(value);
+                ReportPropertyChanging("ShipAddress");
+                _ShipAddress = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipAddress");
+                OnShipAddressChanged();
+            }
+        }
+        private global::System.String _ShipAddress;
+        partial void OnShipAddressChanging(global::System.String value);
+        partial void OnShipAddressChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipCity
+        {
+            get
+            {
+                return _ShipCity;
+            }
+            set
+            {
+                OnShipCityChanging(value);
+                ReportPropertyChanging("ShipCity");
+                _ShipCity = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipCity");
+                OnShipCityChanged();
+            }
+        }
+        private global::System.String _ShipCity;
+        partial void OnShipCityChanging(global::System.String value);
+        partial void OnShipCityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipRegion
+        {
+            get
+            {
+                return _ShipRegion;
+            }
+            set
+            {
+                OnShipRegionChanging(value);
+                ReportPropertyChanging("ShipRegion");
+                _ShipRegion = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipRegion");
+                OnShipRegionChanged();
+            }
+        }
+        private global::System.String _ShipRegion;
+        partial void OnShipRegionChanging(global::System.String value);
+        partial void OnShipRegionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipPostalCode
+        {
+            get
+            {
+                return _ShipPostalCode;
+            }
+            set
+            {
+                OnShipPostalCodeChanging(value);
+                ReportPropertyChanging("ShipPostalCode");
+                _ShipPostalCode = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipPostalCode");
+                OnShipPostalCodeChanged();
+            }
+        }
+        private global::System.String _ShipPostalCode;
+        partial void OnShipPostalCodeChanging(global::System.String value);
+        partial void OnShipPostalCodeChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipCountry
+        {
+            get
+            {
+                return _ShipCountry;
+            }
+            set
+            {
+                OnShipCountryChanging(value);
+                ReportPropertyChanging("ShipCountry");
+                _ShipCountry = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipCountry");
+                OnShipCountryChanged();
+            }
+        }
+        private global::System.String _ShipCountry;
+        partial void OnShipCountryChanging(global::System.String value);
+        partial void OnShipCountryChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Orders_Customers", "Customers")]
+        public Customer Customer
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Customer>("Northwind.FK_Orders_Customers", "Customers").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Customer>("Northwind.FK_Orders_Customers", "Customers").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Customer> CustomerReference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Customer>("Northwind.FK_Orders_Customers", "Customers");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Customer>("Northwind.FK_Orders_Customers", "Customers", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Orders_Employees", "Employees")]
+        public Employee Employee
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Employee>("Northwind.FK_Orders_Employees", "Employees").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Employee>("Northwind.FK_Orders_Employees", "Employees").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Employee> EmployeeReference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Employee>("Northwind.FK_Orders_Employees", "Employees");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Employee>("Northwind.FK_Orders_Employees", "Employees", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Order_Details_Orders", "Order_Details")]
+        public EntityCollection<Order_Detail> Order_Details
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Order_Detail>("Northwind.FK_Order_Details_Orders", "Order_Details");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Order_Detail>("Northwind.FK_Order_Details_Orders", "Order_Details", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Orders_Shippers", "Shippers")]
+        public Shipper Shipper
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Shipper>("Northwind.FK_Orders_Shippers", "Shippers").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Shipper>("Northwind.FK_Orders_Shippers", "Shippers").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Shipper> ShipperReference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Shipper>("Northwind.FK_Orders_Shippers", "Shippers");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Shipper>("Northwind.FK_Orders_Shippers", "Shippers", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Order_Detail")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Order_Detail : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Order_Detail object.
+        /// </summary>
+        /// <param name="orderID">Initial value of the OrderID property.</param>
+        /// <param name="productID">Initial value of the ProductID property.</param>
+        /// <param name="unitPrice">Initial value of the UnitPrice property.</param>
+        /// <param name="quantity">Initial value of the Quantity property.</param>
+        /// <param name="discount">Initial value of the Discount property.</param>
+        public static Order_Detail CreateOrder_Detail(global::System.Int32 orderID, global::System.Int32 productID, global::System.Decimal unitPrice, global::System.Int16 quantity, global::System.Single discount)
+        {
+            Order_Detail order_Detail = new Order_Detail();
+            order_Detail.OrderID = orderID;
+            order_Detail.ProductID = productID;
+            order_Detail.UnitPrice = unitPrice;
+            order_Detail.Quantity = quantity;
+            order_Detail.Discount = discount;
+            return order_Detail;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 OrderID
+        {
+            get
+            {
+                return _OrderID;
+            }
+            set
+            {
+                if (_OrderID != value)
+                {
+                    OnOrderIDChanging(value);
+                    ReportPropertyChanging("OrderID");
+                    _OrderID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("OrderID");
+                    OnOrderIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _OrderID;
+        partial void OnOrderIDChanging(global::System.Int32 value);
+        partial void OnOrderIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 ProductID
+        {
+            get
+            {
+                return _ProductID;
+            }
+            set
+            {
+                if (_ProductID != value)
+                {
+                    OnProductIDChanging(value);
+                    ReportPropertyChanging("ProductID");
+                    _ProductID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("ProductID");
+                    OnProductIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _ProductID;
+        partial void OnProductIDChanging(global::System.Int32 value);
+        partial void OnProductIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Decimal UnitPrice
+        {
+            get
+            {
+                return _UnitPrice;
+            }
+            set
+            {
+                OnUnitPriceChanging(value);
+                ReportPropertyChanging("UnitPrice");
+                _UnitPrice = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("UnitPrice");
+                OnUnitPriceChanged();
+            }
+        }
+        private global::System.Decimal _UnitPrice;
+        partial void OnUnitPriceChanging(global::System.Decimal value);
+        partial void OnUnitPriceChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int16 Quantity
+        {
+            get
+            {
+                return _Quantity;
+            }
+            set
+            {
+                OnQuantityChanging(value);
+                ReportPropertyChanging("Quantity");
+                _Quantity = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("Quantity");
+                OnQuantityChanged();
+            }
+        }
+        private global::System.Int16 _Quantity;
+        partial void OnQuantityChanging(global::System.Int16 value);
+        partial void OnQuantityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Single Discount
+        {
+            get
+            {
+                return _Discount;
+            }
+            set
+            {
+                OnDiscountChanging(value);
+                ReportPropertyChanging("Discount");
+                _Discount = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("Discount");
+                OnDiscountChanged();
+            }
+        }
+        private global::System.Single _Discount;
+        partial void OnDiscountChanging(global::System.Single value);
+        partial void OnDiscountChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Order_Details_Orders", "Orders")]
+        public Order Order
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Order>("Northwind.FK_Order_Details_Orders", "Orders").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Order>("Northwind.FK_Order_Details_Orders", "Orders").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Order> OrderReference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Order>("Northwind.FK_Order_Details_Orders", "Orders");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Order>("Northwind.FK_Order_Details_Orders", "Orders", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Order_Details_Products", "Products")]
+        public Product Product
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Product>("Northwind.FK_Order_Details_Products", "Products").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Product>("Northwind.FK_Order_Details_Products", "Products").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Product> ProductReference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Product>("Northwind.FK_Order_Details_Products", "Products");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Product>("Northwind.FK_Order_Details_Products", "Products", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Order_Details_Extended")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Order_Details_Extended : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Order_Details_Extended object.
+        /// </summary>
+        /// <param name="orderID">Initial value of the OrderID property.</param>
+        /// <param name="productID">Initial value of the ProductID property.</param>
+        /// <param name="productName">Initial value of the ProductName property.</param>
+        /// <param name="unitPrice">Initial value of the UnitPrice property.</param>
+        /// <param name="quantity">Initial value of the Quantity property.</param>
+        /// <param name="discount">Initial value of the Discount property.</param>
+        public static Order_Details_Extended CreateOrder_Details_Extended(global::System.Int32 orderID, global::System.Int32 productID, global::System.String productName, global::System.Decimal unitPrice, global::System.Int16 quantity, global::System.Single discount)
+        {
+            Order_Details_Extended order_Details_Extended = new Order_Details_Extended();
+            order_Details_Extended.OrderID = orderID;
+            order_Details_Extended.ProductID = productID;
+            order_Details_Extended.ProductName = productName;
+            order_Details_Extended.UnitPrice = unitPrice;
+            order_Details_Extended.Quantity = quantity;
+            order_Details_Extended.Discount = discount;
+            return order_Details_Extended;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 OrderID
+        {
+            get
+            {
+                return _OrderID;
+            }
+            set
+            {
+                if (_OrderID != value)
+                {
+                    OnOrderIDChanging(value);
+                    ReportPropertyChanging("OrderID");
+                    _OrderID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("OrderID");
+                    OnOrderIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _OrderID;
+        partial void OnOrderIDChanging(global::System.Int32 value);
+        partial void OnOrderIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 ProductID
+        {
+            get
+            {
+                return _ProductID;
+            }
+            set
+            {
+                if (_ProductID != value)
+                {
+                    OnProductIDChanging(value);
+                    ReportPropertyChanging("ProductID");
+                    _ProductID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("ProductID");
+                    OnProductIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _ProductID;
+        partial void OnProductIDChanging(global::System.Int32 value);
+        partial void OnProductIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String ProductName
+        {
+            get
+            {
+                return _ProductName;
+            }
+            set
+            {
+                if (_ProductName != value)
+                {
+                    OnProductNameChanging(value);
+                    ReportPropertyChanging("ProductName");
+                    _ProductName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("ProductName");
+                    OnProductNameChanged();
+                }
+            }
+        }
+        private global::System.String _ProductName;
+        partial void OnProductNameChanging(global::System.String value);
+        partial void OnProductNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Decimal UnitPrice
+        {
+            get
+            {
+                return _UnitPrice;
+            }
+            set
+            {
+                if (_UnitPrice != value)
+                {
+                    OnUnitPriceChanging(value);
+                    ReportPropertyChanging("UnitPrice");
+                    _UnitPrice = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("UnitPrice");
+                    OnUnitPriceChanged();
+                }
+            }
+        }
+        private global::System.Decimal _UnitPrice;
+        partial void OnUnitPriceChanging(global::System.Decimal value);
+        partial void OnUnitPriceChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int16 Quantity
+        {
+            get
+            {
+                return _Quantity;
+            }
+            set
+            {
+                if (_Quantity != value)
+                {
+                    OnQuantityChanging(value);
+                    ReportPropertyChanging("Quantity");
+                    _Quantity = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("Quantity");
+                    OnQuantityChanged();
+                }
+            }
+        }
+        private global::System.Int16 _Quantity;
+        partial void OnQuantityChanging(global::System.Int16 value);
+        partial void OnQuantityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Single Discount
+        {
+            get
+            {
+                return _Discount;
+            }
+            set
+            {
+                if (_Discount != value)
+                {
+                    OnDiscountChanging(value);
+                    ReportPropertyChanging("Discount");
+                    _Discount = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("Discount");
+                    OnDiscountChanged();
+                }
+            }
+        }
+        private global::System.Single _Discount;
+        partial void OnDiscountChanging(global::System.Single value);
+        partial void OnDiscountChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> ExtendedPrice
+        {
+            get
+            {
+                return _ExtendedPrice;
+            }
+            set
+            {
+                OnExtendedPriceChanging(value);
+                ReportPropertyChanging("ExtendedPrice");
+                _ExtendedPrice = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ExtendedPrice");
+                OnExtendedPriceChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _ExtendedPrice;
+        partial void OnExtendedPriceChanging(Nullable<global::System.Decimal> value);
+        partial void OnExtendedPriceChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Order_Subtotal")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Order_Subtotal : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Order_Subtotal object.
+        /// </summary>
+        /// <param name="orderID">Initial value of the OrderID property.</param>
+        public static Order_Subtotal CreateOrder_Subtotal(global::System.Int32 orderID)
+        {
+            Order_Subtotal order_Subtotal = new Order_Subtotal();
+            order_Subtotal.OrderID = orderID;
+            return order_Subtotal;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 OrderID
+        {
+            get
+            {
+                return _OrderID;
+            }
+            set
+            {
+                if (_OrderID != value)
+                {
+                    OnOrderIDChanging(value);
+                    ReportPropertyChanging("OrderID");
+                    _OrderID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("OrderID");
+                    OnOrderIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _OrderID;
+        partial void OnOrderIDChanging(global::System.Int32 value);
+        partial void OnOrderIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> Subtotal
+        {
+            get
+            {
+                return _Subtotal;
+            }
+            set
+            {
+                OnSubtotalChanging(value);
+                ReportPropertyChanging("Subtotal");
+                _Subtotal = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("Subtotal");
+                OnSubtotalChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _Subtotal;
+        partial void OnSubtotalChanging(Nullable<global::System.Decimal> value);
+        partial void OnSubtotalChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Orders_Qry")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Orders_Qry : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Orders_Qry object.
+        /// </summary>
+        /// <param name="orderID">Initial value of the OrderID property.</param>
+        /// <param name="companyName">Initial value of the CompanyName property.</param>
+        public static Orders_Qry CreateOrders_Qry(global::System.Int32 orderID, global::System.String companyName)
+        {
+            Orders_Qry orders_Qry = new Orders_Qry();
+            orders_Qry.OrderID = orderID;
+            orders_Qry.CompanyName = companyName;
+            return orders_Qry;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 OrderID
+        {
+            get
+            {
+                return _OrderID;
+            }
+            set
+            {
+                if (_OrderID != value)
+                {
+                    OnOrderIDChanging(value);
+                    ReportPropertyChanging("OrderID");
+                    _OrderID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("OrderID");
+                    OnOrderIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _OrderID;
+        partial void OnOrderIDChanging(global::System.Int32 value);
+        partial void OnOrderIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String CustomerID
+        {
+            get
+            {
+                return _CustomerID;
+            }
+            set
+            {
+                OnCustomerIDChanging(value);
+                ReportPropertyChanging("CustomerID");
+                _CustomerID = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("CustomerID");
+                OnCustomerIDChanged();
+            }
+        }
+        private global::System.String _CustomerID;
+        partial void OnCustomerIDChanging(global::System.String value);
+        partial void OnCustomerIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int32> EmployeeID
+        {
+            get
+            {
+                return _EmployeeID;
+            }
+            set
+            {
+                OnEmployeeIDChanging(value);
+                ReportPropertyChanging("EmployeeID");
+                _EmployeeID = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("EmployeeID");
+                OnEmployeeIDChanged();
+            }
+        }
+        private Nullable<global::System.Int32> _EmployeeID;
+        partial void OnEmployeeIDChanging(Nullable<global::System.Int32> value);
+        partial void OnEmployeeIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> OrderDate
+        {
+            get
+            {
+                return _OrderDate;
+            }
+            set
+            {
+                OnOrderDateChanging(value);
+                ReportPropertyChanging("OrderDate");
+                _OrderDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("OrderDate");
+                OnOrderDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _OrderDate;
+        partial void OnOrderDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnOrderDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> RequiredDate
+        {
+            get
+            {
+                return _RequiredDate;
+            }
+            set
+            {
+                OnRequiredDateChanging(value);
+                ReportPropertyChanging("RequiredDate");
+                _RequiredDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("RequiredDate");
+                OnRequiredDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _RequiredDate;
+        partial void OnRequiredDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnRequiredDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> ShippedDate
+        {
+            get
+            {
+                return _ShippedDate;
+            }
+            set
+            {
+                OnShippedDateChanging(value);
+                ReportPropertyChanging("ShippedDate");
+                _ShippedDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ShippedDate");
+                OnShippedDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _ShippedDate;
+        partial void OnShippedDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnShippedDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int32> ShipVia
+        {
+            get
+            {
+                return _ShipVia;
+            }
+            set
+            {
+                OnShipViaChanging(value);
+                ReportPropertyChanging("ShipVia");
+                _ShipVia = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ShipVia");
+                OnShipViaChanged();
+            }
+        }
+        private Nullable<global::System.Int32> _ShipVia;
+        partial void OnShipViaChanging(Nullable<global::System.Int32> value);
+        partial void OnShipViaChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> Freight
+        {
+            get
+            {
+                return _Freight;
+            }
+            set
+            {
+                OnFreightChanging(value);
+                ReportPropertyChanging("Freight");
+                _Freight = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("Freight");
+                OnFreightChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _Freight;
+        partial void OnFreightChanging(Nullable<global::System.Decimal> value);
+        partial void OnFreightChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipName
+        {
+            get
+            {
+                return _ShipName;
+            }
+            set
+            {
+                OnShipNameChanging(value);
+                ReportPropertyChanging("ShipName");
+                _ShipName = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipName");
+                OnShipNameChanged();
+            }
+        }
+        private global::System.String _ShipName;
+        partial void OnShipNameChanging(global::System.String value);
+        partial void OnShipNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipAddress
+        {
+            get
+            {
+                return _ShipAddress;
+            }
+            set
+            {
+                OnShipAddressChanging(value);
+                ReportPropertyChanging("ShipAddress");
+                _ShipAddress = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipAddress");
+                OnShipAddressChanged();
+            }
+        }
+        private global::System.String _ShipAddress;
+        partial void OnShipAddressChanging(global::System.String value);
+        partial void OnShipAddressChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipCity
+        {
+            get
+            {
+                return _ShipCity;
+            }
+            set
+            {
+                OnShipCityChanging(value);
+                ReportPropertyChanging("ShipCity");
+                _ShipCity = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipCity");
+                OnShipCityChanged();
+            }
+        }
+        private global::System.String _ShipCity;
+        partial void OnShipCityChanging(global::System.String value);
+        partial void OnShipCityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipRegion
+        {
+            get
+            {
+                return _ShipRegion;
+            }
+            set
+            {
+                OnShipRegionChanging(value);
+                ReportPropertyChanging("ShipRegion");
+                _ShipRegion = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipRegion");
+                OnShipRegionChanged();
+            }
+        }
+        private global::System.String _ShipRegion;
+        partial void OnShipRegionChanging(global::System.String value);
+        partial void OnShipRegionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipPostalCode
+        {
+            get
+            {
+                return _ShipPostalCode;
+            }
+            set
+            {
+                OnShipPostalCodeChanging(value);
+                ReportPropertyChanging("ShipPostalCode");
+                _ShipPostalCode = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipPostalCode");
+                OnShipPostalCodeChanged();
+            }
+        }
+        private global::System.String _ShipPostalCode;
+        partial void OnShipPostalCodeChanging(global::System.String value);
+        partial void OnShipPostalCodeChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ShipCountry
+        {
+            get
+            {
+                return _ShipCountry;
+            }
+            set
+            {
+                OnShipCountryChanging(value);
+                ReportPropertyChanging("ShipCountry");
+                _ShipCountry = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ShipCountry");
+                OnShipCountryChanged();
+            }
+        }
+        private global::System.String _ShipCountry;
+        partial void OnShipCountryChanging(global::System.String value);
+        partial void OnShipCountryChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CompanyName
+        {
+            get
+            {
+                return _CompanyName;
+            }
+            set
+            {
+                if (_CompanyName != value)
+                {
+                    OnCompanyNameChanging(value);
+                    ReportPropertyChanging("CompanyName");
+                    _CompanyName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CompanyName");
+                    OnCompanyNameChanged();
+                }
+            }
+        }
+        private global::System.String _CompanyName;
+        partial void OnCompanyNameChanging(global::System.String value);
+        partial void OnCompanyNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Address
+        {
+            get
+            {
+                return _Address;
+            }
+            set
+            {
+                OnAddressChanging(value);
+                ReportPropertyChanging("Address");
+                _Address = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Address");
+                OnAddressChanged();
+            }
+        }
+        private global::System.String _Address;
+        partial void OnAddressChanging(global::System.String value);
+        partial void OnAddressChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String City
+        {
+            get
+            {
+                return _City;
+            }
+            set
+            {
+                OnCityChanging(value);
+                ReportPropertyChanging("City");
+                _City = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("City");
+                OnCityChanged();
+            }
+        }
+        private global::System.String _City;
+        partial void OnCityChanging(global::System.String value);
+        partial void OnCityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Region
+        {
+            get
+            {
+                return _Region;
+            }
+            set
+            {
+                OnRegionChanging(value);
+                ReportPropertyChanging("Region");
+                _Region = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Region");
+                OnRegionChanged();
+            }
+        }
+        private global::System.String _Region;
+        partial void OnRegionChanging(global::System.String value);
+        partial void OnRegionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String PostalCode
+        {
+            get
+            {
+                return _PostalCode;
+            }
+            set
+            {
+                OnPostalCodeChanging(value);
+                ReportPropertyChanging("PostalCode");
+                _PostalCode = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("PostalCode");
+                OnPostalCodeChanged();
+            }
+        }
+        private global::System.String _PostalCode;
+        partial void OnPostalCodeChanging(global::System.String value);
+        partial void OnPostalCodeChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Country
+        {
+            get
+            {
+                return _Country;
+            }
+            set
+            {
+                OnCountryChanging(value);
+                ReportPropertyChanging("Country");
+                _Country = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Country");
+                OnCountryChanged();
+            }
+        }
+        private global::System.String _Country;
+        partial void OnCountryChanging(global::System.String value);
+        partial void OnCountryChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Product")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Product : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Product object.
+        /// </summary>
+        /// <param name="productID">Initial value of the ProductID property.</param>
+        /// <param name="productName">Initial value of the ProductName property.</param>
+        /// <param name="discontinued">Initial value of the Discontinued property.</param>
+        public static Product CreateProduct(global::System.Int32 productID, global::System.String productName, global::System.Boolean discontinued)
+        {
+            Product product = new Product();
+            product.ProductID = productID;
+            product.ProductName = productName;
+            product.Discontinued = discontinued;
+            return product;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 ProductID
+        {
+            get
+            {
+                return _ProductID;
+            }
+            set
+            {
+                if (_ProductID != value)
+                {
+                    OnProductIDChanging(value);
+                    ReportPropertyChanging("ProductID");
+                    _ProductID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("ProductID");
+                    OnProductIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _ProductID;
+        partial void OnProductIDChanging(global::System.Int32 value);
+        partial void OnProductIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String ProductName
+        {
+            get
+            {
+                return _ProductName;
+            }
+            set
+            {
+                OnProductNameChanging(value);
+                ReportPropertyChanging("ProductName");
+                _ProductName = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("ProductName");
+                OnProductNameChanged();
+            }
+        }
+        private global::System.String _ProductName;
+        partial void OnProductNameChanging(global::System.String value);
+        partial void OnProductNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int32> SupplierID
+        {
+            get
+            {
+                return _SupplierID;
+            }
+            set
+            {
+                OnSupplierIDChanging(value);
+                ReportPropertyChanging("SupplierID");
+                _SupplierID = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("SupplierID");
+                OnSupplierIDChanged();
+            }
+        }
+        private Nullable<global::System.Int32> _SupplierID;
+        partial void OnSupplierIDChanging(Nullable<global::System.Int32> value);
+        partial void OnSupplierIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int32> CategoryID
+        {
+            get
+            {
+                return _CategoryID;
+            }
+            set
+            {
+                OnCategoryIDChanging(value);
+                ReportPropertyChanging("CategoryID");
+                _CategoryID = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("CategoryID");
+                OnCategoryIDChanged();
+            }
+        }
+        private Nullable<global::System.Int32> _CategoryID;
+        partial void OnCategoryIDChanging(Nullable<global::System.Int32> value);
+        partial void OnCategoryIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String QuantityPerUnit
+        {
+            get
+            {
+                return _QuantityPerUnit;
+            }
+            set
+            {
+                OnQuantityPerUnitChanging(value);
+                ReportPropertyChanging("QuantityPerUnit");
+                _QuantityPerUnit = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("QuantityPerUnit");
+                OnQuantityPerUnitChanged();
+            }
+        }
+        private global::System.String _QuantityPerUnit;
+        partial void OnQuantityPerUnitChanging(global::System.String value);
+        partial void OnQuantityPerUnitChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> UnitPrice
+        {
+            get
+            {
+                return _UnitPrice;
+            }
+            set
+            {
+                OnUnitPriceChanging(value);
+                ReportPropertyChanging("UnitPrice");
+                _UnitPrice = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("UnitPrice");
+                OnUnitPriceChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _UnitPrice;
+        partial void OnUnitPriceChanging(Nullable<global::System.Decimal> value);
+        partial void OnUnitPriceChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int16> UnitsInStock
+        {
+            get
+            {
+                return _UnitsInStock;
+            }
+            set
+            {
+                OnUnitsInStockChanging(value);
+                ReportPropertyChanging("UnitsInStock");
+                _UnitsInStock = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("UnitsInStock");
+                OnUnitsInStockChanged();
+            }
+        }
+        private Nullable<global::System.Int16> _UnitsInStock;
+        partial void OnUnitsInStockChanging(Nullable<global::System.Int16> value);
+        partial void OnUnitsInStockChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int16> UnitsOnOrder
+        {
+            get
+            {
+                return _UnitsOnOrder;
+            }
+            set
+            {
+                OnUnitsOnOrderChanging(value);
+                ReportPropertyChanging("UnitsOnOrder");
+                _UnitsOnOrder = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("UnitsOnOrder");
+                OnUnitsOnOrderChanged();
+            }
+        }
+        private Nullable<global::System.Int16> _UnitsOnOrder;
+        partial void OnUnitsOnOrderChanging(Nullable<global::System.Int16> value);
+        partial void OnUnitsOnOrderChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int16> ReorderLevel
+        {
+            get
+            {
+                return _ReorderLevel;
+            }
+            set
+            {
+                OnReorderLevelChanging(value);
+                ReportPropertyChanging("ReorderLevel");
+                _ReorderLevel = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ReorderLevel");
+                OnReorderLevelChanged();
+            }
+        }
+        private Nullable<global::System.Int16> _ReorderLevel;
+        partial void OnReorderLevelChanging(Nullable<global::System.Int16> value);
+        partial void OnReorderLevelChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Boolean Discontinued
+        {
+            get
+            {
+                return _Discontinued;
+            }
+            set
+            {
+                OnDiscontinuedChanging(value);
+                ReportPropertyChanging("Discontinued");
+                _Discontinued = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("Discontinued");
+                OnDiscontinuedChanged();
+            }
+        }
+        private global::System.Boolean _Discontinued;
+        partial void OnDiscontinuedChanging(global::System.Boolean value);
+        partial void OnDiscontinuedChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Products_Categories", "Categories")]
+        public Category Category
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Category>("Northwind.FK_Products_Categories", "Categories").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Category>("Northwind.FK_Products_Categories", "Categories").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Category> CategoryReference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Category>("Northwind.FK_Products_Categories", "Categories");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Category>("Northwind.FK_Products_Categories", "Categories", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Order_Details_Products", "Order_Details")]
+        public EntityCollection<Order_Detail> Order_Details
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Order_Detail>("Northwind.FK_Order_Details_Products", "Order_Details");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Order_Detail>("Northwind.FK_Order_Details_Products", "Order_Details", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Products_Suppliers", "Suppliers")]
+        public Supplier Supplier
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Supplier>("Northwind.FK_Products_Suppliers", "Suppliers").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Supplier>("Northwind.FK_Products_Suppliers", "Suppliers").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Supplier> SupplierReference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Supplier>("Northwind.FK_Products_Suppliers", "Suppliers");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Supplier>("Northwind.FK_Products_Suppliers", "Suppliers", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Product_Sales_for_1997")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Product_Sales_for_1997 : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Product_Sales_for_1997 object.
+        /// </summary>
+        /// <param name="categoryName">Initial value of the CategoryName property.</param>
+        /// <param name="productName">Initial value of the ProductName property.</param>
+        public static Product_Sales_for_1997 CreateProduct_Sales_for_1997(global::System.String categoryName, global::System.String productName)
+        {
+            Product_Sales_for_1997 product_Sales_for_1997 = new Product_Sales_for_1997();
+            product_Sales_for_1997.CategoryName = categoryName;
+            product_Sales_for_1997.ProductName = productName;
+            return product_Sales_for_1997;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CategoryName
+        {
+            get
+            {
+                return _CategoryName;
+            }
+            set
+            {
+                if (_CategoryName != value)
+                {
+                    OnCategoryNameChanging(value);
+                    ReportPropertyChanging("CategoryName");
+                    _CategoryName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CategoryName");
+                    OnCategoryNameChanged();
+                }
+            }
+        }
+        private global::System.String _CategoryName;
+        partial void OnCategoryNameChanging(global::System.String value);
+        partial void OnCategoryNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String ProductName
+        {
+            get
+            {
+                return _ProductName;
+            }
+            set
+            {
+                if (_ProductName != value)
+                {
+                    OnProductNameChanging(value);
+                    ReportPropertyChanging("ProductName");
+                    _ProductName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("ProductName");
+                    OnProductNameChanged();
+                }
+            }
+        }
+        private global::System.String _ProductName;
+        partial void OnProductNameChanging(global::System.String value);
+        partial void OnProductNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> ProductSales
+        {
+            get
+            {
+                return _ProductSales;
+            }
+            set
+            {
+                OnProductSalesChanging(value);
+                ReportPropertyChanging("ProductSales");
+                _ProductSales = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ProductSales");
+                OnProductSalesChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _ProductSales;
+        partial void OnProductSalesChanging(Nullable<global::System.Decimal> value);
+        partial void OnProductSalesChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Products_Above_Average_Price")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Products_Above_Average_Price : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Products_Above_Average_Price object.
+        /// </summary>
+        /// <param name="productName">Initial value of the ProductName property.</param>
+        public static Products_Above_Average_Price CreateProducts_Above_Average_Price(global::System.String productName)
+        {
+            Products_Above_Average_Price products_Above_Average_Price = new Products_Above_Average_Price();
+            products_Above_Average_Price.ProductName = productName;
+            return products_Above_Average_Price;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String ProductName
+        {
+            get
+            {
+                return _ProductName;
+            }
+            set
+            {
+                if (_ProductName != value)
+                {
+                    OnProductNameChanging(value);
+                    ReportPropertyChanging("ProductName");
+                    _ProductName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("ProductName");
+                    OnProductNameChanged();
+                }
+            }
+        }
+        private global::System.String _ProductName;
+        partial void OnProductNameChanging(global::System.String value);
+        partial void OnProductNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> UnitPrice
+        {
+            get
+            {
+                return _UnitPrice;
+            }
+            set
+            {
+                OnUnitPriceChanging(value);
+                ReportPropertyChanging("UnitPrice");
+                _UnitPrice = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("UnitPrice");
+                OnUnitPriceChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _UnitPrice;
+        partial void OnUnitPriceChanging(Nullable<global::System.Decimal> value);
+        partial void OnUnitPriceChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Products_by_Category")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Products_by_Category : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Products_by_Category object.
+        /// </summary>
+        /// <param name="categoryName">Initial value of the CategoryName property.</param>
+        /// <param name="productName">Initial value of the ProductName property.</param>
+        /// <param name="discontinued">Initial value of the Discontinued property.</param>
+        public static Products_by_Category CreateProducts_by_Category(global::System.String categoryName, global::System.String productName, global::System.Boolean discontinued)
+        {
+            Products_by_Category products_by_Category = new Products_by_Category();
+            products_by_Category.CategoryName = categoryName;
+            products_by_Category.ProductName = productName;
+            products_by_Category.Discontinued = discontinued;
+            return products_by_Category;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CategoryName
+        {
+            get
+            {
+                return _CategoryName;
+            }
+            set
+            {
+                if (_CategoryName != value)
+                {
+                    OnCategoryNameChanging(value);
+                    ReportPropertyChanging("CategoryName");
+                    _CategoryName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CategoryName");
+                    OnCategoryNameChanged();
+                }
+            }
+        }
+        private global::System.String _CategoryName;
+        partial void OnCategoryNameChanging(global::System.String value);
+        partial void OnCategoryNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String ProductName
+        {
+            get
+            {
+                return _ProductName;
+            }
+            set
+            {
+                if (_ProductName != value)
+                {
+                    OnProductNameChanging(value);
+                    ReportPropertyChanging("ProductName");
+                    _ProductName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("ProductName");
+                    OnProductNameChanged();
+                }
+            }
+        }
+        private global::System.String _ProductName;
+        partial void OnProductNameChanging(global::System.String value);
+        partial void OnProductNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String QuantityPerUnit
+        {
+            get
+            {
+                return _QuantityPerUnit;
+            }
+            set
+            {
+                OnQuantityPerUnitChanging(value);
+                ReportPropertyChanging("QuantityPerUnit");
+                _QuantityPerUnit = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("QuantityPerUnit");
+                OnQuantityPerUnitChanged();
+            }
+        }
+        private global::System.String _QuantityPerUnit;
+        partial void OnQuantityPerUnitChanging(global::System.String value);
+        partial void OnQuantityPerUnitChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Int16> UnitsInStock
+        {
+            get
+            {
+                return _UnitsInStock;
+            }
+            set
+            {
+                OnUnitsInStockChanging(value);
+                ReportPropertyChanging("UnitsInStock");
+                _UnitsInStock = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("UnitsInStock");
+                OnUnitsInStockChanged();
+            }
+        }
+        private Nullable<global::System.Int16> _UnitsInStock;
+        partial void OnUnitsInStockChanging(Nullable<global::System.Int16> value);
+        partial void OnUnitsInStockChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Boolean Discontinued
+        {
+            get
+            {
+                return _Discontinued;
+            }
+            set
+            {
+                if (_Discontinued != value)
+                {
+                    OnDiscontinuedChanging(value);
+                    ReportPropertyChanging("Discontinued");
+                    _Discontinued = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("Discontinued");
+                    OnDiscontinuedChanged();
+                }
+            }
+        }
+        private global::System.Boolean _Discontinued;
+        partial void OnDiscontinuedChanging(global::System.Boolean value);
+        partial void OnDiscontinuedChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Region")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Region : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Region object.
+        /// </summary>
+        /// <param name="regionID">Initial value of the RegionID property.</param>
+        /// <param name="regionDescription">Initial value of the RegionDescription property.</param>
+        public static Region CreateRegion(global::System.Int32 regionID, global::System.String regionDescription)
+        {
+            Region region = new Region();
+            region.RegionID = regionID;
+            region.RegionDescription = regionDescription;
+            return region;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 RegionID
+        {
+            get
+            {
+                return _RegionID;
+            }
+            set
+            {
+                if (_RegionID != value)
+                {
+                    OnRegionIDChanging(value);
+                    ReportPropertyChanging("RegionID");
+                    _RegionID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("RegionID");
+                    OnRegionIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _RegionID;
+        partial void OnRegionIDChanging(global::System.Int32 value);
+        partial void OnRegionIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String RegionDescription
+        {
+            get
+            {
+                return _RegionDescription;
+            }
+            set
+            {
+                OnRegionDescriptionChanging(value);
+                ReportPropertyChanging("RegionDescription");
+                _RegionDescription = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("RegionDescription");
+                OnRegionDescriptionChanged();
+            }
+        }
+        private global::System.String _RegionDescription;
+        partial void OnRegionDescriptionChanging(global::System.String value);
+        partial void OnRegionDescriptionChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Territories_Region", "Territories")]
+        public EntityCollection<Territory> Territories
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Territory>("Northwind.FK_Territories_Region", "Territories");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Territory>("Northwind.FK_Territories_Region", "Territories", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Sales_by_Category")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Sales_by_Category : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Sales_by_Category object.
+        /// </summary>
+        /// <param name="categoryID">Initial value of the CategoryID property.</param>
+        /// <param name="categoryName">Initial value of the CategoryName property.</param>
+        /// <param name="productName">Initial value of the ProductName property.</param>
+        public static Sales_by_Category CreateSales_by_Category(global::System.Int32 categoryID, global::System.String categoryName, global::System.String productName)
+        {
+            Sales_by_Category sales_by_Category = new Sales_by_Category();
+            sales_by_Category.CategoryID = categoryID;
+            sales_by_Category.CategoryName = categoryName;
+            sales_by_Category.ProductName = productName;
+            return sales_by_Category;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 CategoryID
+        {
+            get
+            {
+                return _CategoryID;
+            }
+            set
+            {
+                if (_CategoryID != value)
+                {
+                    OnCategoryIDChanging(value);
+                    ReportPropertyChanging("CategoryID");
+                    _CategoryID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("CategoryID");
+                    OnCategoryIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _CategoryID;
+        partial void OnCategoryIDChanging(global::System.Int32 value);
+        partial void OnCategoryIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CategoryName
+        {
+            get
+            {
+                return _CategoryName;
+            }
+            set
+            {
+                if (_CategoryName != value)
+                {
+                    OnCategoryNameChanging(value);
+                    ReportPropertyChanging("CategoryName");
+                    _CategoryName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CategoryName");
+                    OnCategoryNameChanged();
+                }
+            }
+        }
+        private global::System.String _CategoryName;
+        partial void OnCategoryNameChanging(global::System.String value);
+        partial void OnCategoryNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String ProductName
+        {
+            get
+            {
+                return _ProductName;
+            }
+            set
+            {
+                if (_ProductName != value)
+                {
+                    OnProductNameChanging(value);
+                    ReportPropertyChanging("ProductName");
+                    _ProductName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("ProductName");
+                    OnProductNameChanged();
+                }
+            }
+        }
+        private global::System.String _ProductName;
+        partial void OnProductNameChanging(global::System.String value);
+        partial void OnProductNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> ProductSales
+        {
+            get
+            {
+                return _ProductSales;
+            }
+            set
+            {
+                OnProductSalesChanging(value);
+                ReportPropertyChanging("ProductSales");
+                _ProductSales = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ProductSales");
+                OnProductSalesChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _ProductSales;
+        partial void OnProductSalesChanging(Nullable<global::System.Decimal> value);
+        partial void OnProductSalesChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Sales_Totals_by_Amount")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Sales_Totals_by_Amount : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Sales_Totals_by_Amount object.
+        /// </summary>
+        /// <param name="orderID">Initial value of the OrderID property.</param>
+        /// <param name="companyName">Initial value of the CompanyName property.</param>
+        public static Sales_Totals_by_Amount CreateSales_Totals_by_Amount(global::System.Int32 orderID, global::System.String companyName)
+        {
+            Sales_Totals_by_Amount sales_Totals_by_Amount = new Sales_Totals_by_Amount();
+            sales_Totals_by_Amount.OrderID = orderID;
+            sales_Totals_by_Amount.CompanyName = companyName;
+            return sales_Totals_by_Amount;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> SaleAmount
+        {
+            get
+            {
+                return _SaleAmount;
+            }
+            set
+            {
+                OnSaleAmountChanging(value);
+                ReportPropertyChanging("SaleAmount");
+                _SaleAmount = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("SaleAmount");
+                OnSaleAmountChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _SaleAmount;
+        partial void OnSaleAmountChanging(Nullable<global::System.Decimal> value);
+        partial void OnSaleAmountChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 OrderID
+        {
+            get
+            {
+                return _OrderID;
+            }
+            set
+            {
+                if (_OrderID != value)
+                {
+                    OnOrderIDChanging(value);
+                    ReportPropertyChanging("OrderID");
+                    _OrderID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("OrderID");
+                    OnOrderIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _OrderID;
+        partial void OnOrderIDChanging(global::System.Int32 value);
+        partial void OnOrderIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CompanyName
+        {
+            get
+            {
+                return _CompanyName;
+            }
+            set
+            {
+                if (_CompanyName != value)
+                {
+                    OnCompanyNameChanging(value);
+                    ReportPropertyChanging("CompanyName");
+                    _CompanyName = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("CompanyName");
+                    OnCompanyNameChanged();
+                }
+            }
+        }
+        private global::System.String _CompanyName;
+        partial void OnCompanyNameChanging(global::System.String value);
+        partial void OnCompanyNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> ShippedDate
+        {
+            get
+            {
+                return _ShippedDate;
+            }
+            set
+            {
+                OnShippedDateChanging(value);
+                ReportPropertyChanging("ShippedDate");
+                _ShippedDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ShippedDate");
+                OnShippedDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _ShippedDate;
+        partial void OnShippedDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnShippedDateChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Shipper")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Shipper : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Shipper object.
+        /// </summary>
+        /// <param name="shipperID">Initial value of the ShipperID property.</param>
+        /// <param name="companyName">Initial value of the CompanyName property.</param>
+        public static Shipper CreateShipper(global::System.Int32 shipperID, global::System.String companyName)
+        {
+            Shipper shipper = new Shipper();
+            shipper.ShipperID = shipperID;
+            shipper.CompanyName = companyName;
+            return shipper;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 ShipperID
+        {
+            get
+            {
+                return _ShipperID;
+            }
+            set
+            {
+                if (_ShipperID != value)
+                {
+                    OnShipperIDChanging(value);
+                    ReportPropertyChanging("ShipperID");
+                    _ShipperID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("ShipperID");
+                    OnShipperIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _ShipperID;
+        partial void OnShipperIDChanging(global::System.Int32 value);
+        partial void OnShipperIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CompanyName
+        {
+            get
+            {
+                return _CompanyName;
+            }
+            set
+            {
+                OnCompanyNameChanging(value);
+                ReportPropertyChanging("CompanyName");
+                _CompanyName = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("CompanyName");
+                OnCompanyNameChanged();
+            }
+        }
+        private global::System.String _CompanyName;
+        partial void OnCompanyNameChanging(global::System.String value);
+        partial void OnCompanyNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Phone
+        {
+            get
+            {
+                return _Phone;
+            }
+            set
+            {
+                OnPhoneChanging(value);
+                ReportPropertyChanging("Phone");
+                _Phone = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Phone");
+                OnPhoneChanged();
+            }
+        }
+        private global::System.String _Phone;
+        partial void OnPhoneChanging(global::System.String value);
+        partial void OnPhoneChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Orders_Shippers", "Orders")]
+        public EntityCollection<Order> Orders
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Order>("Northwind.FK_Orders_Shippers", "Orders");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Order>("Northwind.FK_Orders_Shippers", "Orders", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Summary_of_Sales_by_Quarter")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Summary_of_Sales_by_Quarter : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Summary_of_Sales_by_Quarter object.
+        /// </summary>
+        /// <param name="orderID">Initial value of the OrderID property.</param>
+        public static Summary_of_Sales_by_Quarter CreateSummary_of_Sales_by_Quarter(global::System.Int32 orderID)
+        {
+            Summary_of_Sales_by_Quarter summary_of_Sales_by_Quarter = new Summary_of_Sales_by_Quarter();
+            summary_of_Sales_by_Quarter.OrderID = orderID;
+            return summary_of_Sales_by_Quarter;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> ShippedDate
+        {
+            get
+            {
+                return _ShippedDate;
+            }
+            set
+            {
+                OnShippedDateChanging(value);
+                ReportPropertyChanging("ShippedDate");
+                _ShippedDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ShippedDate");
+                OnShippedDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _ShippedDate;
+        partial void OnShippedDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnShippedDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 OrderID
+        {
+            get
+            {
+                return _OrderID;
+            }
+            set
+            {
+                if (_OrderID != value)
+                {
+                    OnOrderIDChanging(value);
+                    ReportPropertyChanging("OrderID");
+                    _OrderID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("OrderID");
+                    OnOrderIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _OrderID;
+        partial void OnOrderIDChanging(global::System.Int32 value);
+        partial void OnOrderIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> Subtotal
+        {
+            get
+            {
+                return _Subtotal;
+            }
+            set
+            {
+                OnSubtotalChanging(value);
+                ReportPropertyChanging("Subtotal");
+                _Subtotal = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("Subtotal");
+                OnSubtotalChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _Subtotal;
+        partial void OnSubtotalChanging(Nullable<global::System.Decimal> value);
+        partial void OnSubtotalChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Summary_of_Sales_by_Year")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Summary_of_Sales_by_Year : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Summary_of_Sales_by_Year object.
+        /// </summary>
+        /// <param name="orderID">Initial value of the OrderID property.</param>
+        public static Summary_of_Sales_by_Year CreateSummary_of_Sales_by_Year(global::System.Int32 orderID)
+        {
+            Summary_of_Sales_by_Year summary_of_Sales_by_Year = new Summary_of_Sales_by_Year();
+            summary_of_Sales_by_Year.OrderID = orderID;
+            return summary_of_Sales_by_Year;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.DateTime> ShippedDate
+        {
+            get
+            {
+                return _ShippedDate;
+            }
+            set
+            {
+                OnShippedDateChanging(value);
+                ReportPropertyChanging("ShippedDate");
+                _ShippedDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("ShippedDate");
+                OnShippedDateChanged();
+            }
+        }
+        private Nullable<global::System.DateTime> _ShippedDate;
+        partial void OnShippedDateChanging(Nullable<global::System.DateTime> value);
+        partial void OnShippedDateChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 OrderID
+        {
+            get
+            {
+                return _OrderID;
+            }
+            set
+            {
+                if (_OrderID != value)
+                {
+                    OnOrderIDChanging(value);
+                    ReportPropertyChanging("OrderID");
+                    _OrderID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("OrderID");
+                    OnOrderIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _OrderID;
+        partial void OnOrderIDChanging(global::System.Int32 value);
+        partial void OnOrderIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public Nullable<global::System.Decimal> Subtotal
+        {
+            get
+            {
+                return _Subtotal;
+            }
+            set
+            {
+                OnSubtotalChanging(value);
+                ReportPropertyChanging("Subtotal");
+                _Subtotal = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("Subtotal");
+                OnSubtotalChanged();
+            }
+        }
+        private Nullable<global::System.Decimal> _Subtotal;
+        partial void OnSubtotalChanging(Nullable<global::System.Decimal> value);
+        partial void OnSubtotalChanged();
+
+        #endregion
+    
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Supplier")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Supplier : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Supplier object.
+        /// </summary>
+        /// <param name="supplierID">Initial value of the SupplierID property.</param>
+        /// <param name="companyName">Initial value of the CompanyName property.</param>
+        public static Supplier CreateSupplier(global::System.Int32 supplierID, global::System.String companyName)
+        {
+            Supplier supplier = new Supplier();
+            supplier.SupplierID = supplierID;
+            supplier.CompanyName = companyName;
+            return supplier;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 SupplierID
+        {
+            get
+            {
+                return _SupplierID;
+            }
+            set
+            {
+                if (_SupplierID != value)
+                {
+                    OnSupplierIDChanging(value);
+                    ReportPropertyChanging("SupplierID");
+                    _SupplierID = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("SupplierID");
+                    OnSupplierIDChanged();
+                }
+            }
+        }
+        private global::System.Int32 _SupplierID;
+        partial void OnSupplierIDChanging(global::System.Int32 value);
+        partial void OnSupplierIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String CompanyName
+        {
+            get
+            {
+                return _CompanyName;
+            }
+            set
+            {
+                OnCompanyNameChanging(value);
+                ReportPropertyChanging("CompanyName");
+                _CompanyName = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("CompanyName");
+                OnCompanyNameChanged();
+            }
+        }
+        private global::System.String _CompanyName;
+        partial void OnCompanyNameChanging(global::System.String value);
+        partial void OnCompanyNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ContactName
+        {
+            get
+            {
+                return _ContactName;
+            }
+            set
+            {
+                OnContactNameChanging(value);
+                ReportPropertyChanging("ContactName");
+                _ContactName = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ContactName");
+                OnContactNameChanged();
+            }
+        }
+        private global::System.String _ContactName;
+        partial void OnContactNameChanging(global::System.String value);
+        partial void OnContactNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String ContactTitle
+        {
+            get
+            {
+                return _ContactTitle;
+            }
+            set
+            {
+                OnContactTitleChanging(value);
+                ReportPropertyChanging("ContactTitle");
+                _ContactTitle = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("ContactTitle");
+                OnContactTitleChanged();
+            }
+        }
+        private global::System.String _ContactTitle;
+        partial void OnContactTitleChanging(global::System.String value);
+        partial void OnContactTitleChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Address
+        {
+            get
+            {
+                return _Address;
+            }
+            set
+            {
+                OnAddressChanging(value);
+                ReportPropertyChanging("Address");
+                _Address = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Address");
+                OnAddressChanged();
+            }
+        }
+        private global::System.String _Address;
+        partial void OnAddressChanging(global::System.String value);
+        partial void OnAddressChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String City
+        {
+            get
+            {
+                return _City;
+            }
+            set
+            {
+                OnCityChanging(value);
+                ReportPropertyChanging("City");
+                _City = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("City");
+                OnCityChanged();
+            }
+        }
+        private global::System.String _City;
+        partial void OnCityChanging(global::System.String value);
+        partial void OnCityChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Region
+        {
+            get
+            {
+                return _Region;
+            }
+            set
+            {
+                OnRegionChanging(value);
+                ReportPropertyChanging("Region");
+                _Region = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Region");
+                OnRegionChanged();
+            }
+        }
+        private global::System.String _Region;
+        partial void OnRegionChanging(global::System.String value);
+        partial void OnRegionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String PostalCode
+        {
+            get
+            {
+                return _PostalCode;
+            }
+            set
+            {
+                OnPostalCodeChanging(value);
+                ReportPropertyChanging("PostalCode");
+                _PostalCode = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("PostalCode");
+                OnPostalCodeChanged();
+            }
+        }
+        private global::System.String _PostalCode;
+        partial void OnPostalCodeChanging(global::System.String value);
+        partial void OnPostalCodeChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Country
+        {
+            get
+            {
+                return _Country;
+            }
+            set
+            {
+                OnCountryChanging(value);
+                ReportPropertyChanging("Country");
+                _Country = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Country");
+                OnCountryChanged();
+            }
+        }
+        private global::System.String _Country;
+        partial void OnCountryChanging(global::System.String value);
+        partial void OnCountryChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Phone
+        {
+            get
+            {
+                return _Phone;
+            }
+            set
+            {
+                OnPhoneChanging(value);
+                ReportPropertyChanging("Phone");
+                _Phone = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Phone");
+                OnPhoneChanged();
+            }
+        }
+        private global::System.String _Phone;
+        partial void OnPhoneChanging(global::System.String value);
+        partial void OnPhoneChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String Fax
+        {
+            get
+            {
+                return _Fax;
+            }
+            set
+            {
+                OnFaxChanging(value);
+                ReportPropertyChanging("Fax");
+                _Fax = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("Fax");
+                OnFaxChanged();
+            }
+        }
+        private global::System.String _Fax;
+        partial void OnFaxChanging(global::System.String value);
+        partial void OnFaxChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
+        [DataMemberAttribute()]
+        public global::System.String HomePage
+        {
+            get
+            {
+                return _HomePage;
+            }
+            set
+            {
+                OnHomePageChanging(value);
+                ReportPropertyChanging("HomePage");
+                _HomePage = StructuralObject.SetValidValue(value, true);
+                ReportPropertyChanged("HomePage");
+                OnHomePageChanged();
+            }
+        }
+        private global::System.String _HomePage;
+        partial void OnHomePageChanging(global::System.String value);
+        partial void OnHomePageChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Products_Suppliers", "Products")]
+        public EntityCollection<Product> Products
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Product>("Northwind.FK_Products_Suppliers", "Products");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Product>("Northwind.FK_Products_Suppliers", "Products", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="Northwind", Name="Territory")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Territory : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Territory object.
+        /// </summary>
+        /// <param name="territoryID">Initial value of the TerritoryID property.</param>
+        /// <param name="territoryDescription">Initial value of the TerritoryDescription property.</param>
+        /// <param name="regionID">Initial value of the RegionID property.</param>
+        public static Territory CreateTerritory(global::System.String territoryID, global::System.String territoryDescription, global::System.Int32 regionID)
+        {
+            Territory territory = new Territory();
+            territory.TerritoryID = territoryID;
+            territory.TerritoryDescription = territoryDescription;
+            territory.RegionID = regionID;
+            return territory;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String TerritoryID
+        {
+            get
+            {
+                return _TerritoryID;
+            }
+            set
+            {
+                if (_TerritoryID != value)
+                {
+                    OnTerritoryIDChanging(value);
+                    ReportPropertyChanging("TerritoryID");
+                    _TerritoryID = StructuralObject.SetValidValue(value, false);
+                    ReportPropertyChanged("TerritoryID");
+                    OnTerritoryIDChanged();
+                }
+            }
+        }
+        private global::System.String _TerritoryID;
+        partial void OnTerritoryIDChanging(global::System.String value);
+        partial void OnTerritoryIDChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String TerritoryDescription
+        {
+            get
+            {
+                return _TerritoryDescription;
+            }
+            set
+            {
+                OnTerritoryDescriptionChanging(value);
+                ReportPropertyChanging("TerritoryDescription");
+                _TerritoryDescription = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("TerritoryDescription");
+                OnTerritoryDescriptionChanged();
+            }
+        }
+        private global::System.String _TerritoryDescription;
+        partial void OnTerritoryDescriptionChanging(global::System.String value);
+        partial void OnTerritoryDescriptionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Int32 RegionID
+        {
+            get
+            {
+                return _RegionID;
+            }
+            set
+            {
+                OnRegionIDChanging(value);
+                ReportPropertyChanging("RegionID");
+                _RegionID = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("RegionID");
+                OnRegionIDChanged();
+            }
+        }
+        private global::System.Int32 _RegionID;
+        partial void OnRegionIDChanging(global::System.Int32 value);
+        partial void OnRegionIDChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "FK_Territories_Region", "Region")]
+        public Region Region
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Region>("Northwind.FK_Territories_Region", "Region").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Region>("Northwind.FK_Territories_Region", "Region").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Region> RegionReference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Region>("Northwind.FK_Territories_Region", "Region");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Region>("Northwind.FK_Territories_Region", "Region", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("Northwind", "EmployeeTerritories", "Employees")]
+        public EntityCollection<Employee> Employees
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Employee>("Northwind.EmployeeTerritories", "Employees");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Employee>("Northwind.EmployeeTerritories", "Employees", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+
+    #endregion
+    
+}
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Northwind.edmx b/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Northwind.edmx
new file mode 100644
index 0000000..1fe980b
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Northwind.edmx
@@ -0,0 +1,1738 @@
+<?xml version="1.0" encoding="utf-8"?>
+<edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
+  <!-- EF Runtime content -->
+  <edmx:Runtime>
+    <!-- SSDL content -->
+    <edmx:StorageModels>
+      <Schema Namespace="Northwind.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
+        <EntityContainer Name="NorthwindStoreContainer">
+          <EntitySet Name="Categories" EntityType="Northwind.Store.Categories" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="CustomerCustomerDemo" EntityType="Northwind.Store.CustomerCustomerDemo" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="CustomerDemographics" EntityType="Northwind.Store.CustomerDemographics" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="Customers" EntityType="Northwind.Store.Customers" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="Employees" EntityType="Northwind.Store.Employees" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="EmployeeTerritories" EntityType="Northwind.Store.EmployeeTerritories" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="Order Details" EntityType="Northwind.Store.Order Details" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="Orders" EntityType="Northwind.Store.Orders" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="Products" EntityType="Northwind.Store.Products" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="Region" EntityType="Northwind.Store.Region" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="Shippers" EntityType="Northwind.Store.Shippers" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="Suppliers" EntityType="Northwind.Store.Suppliers" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="Territories" EntityType="Northwind.Store.Territories" store:Type="Tables" Schema="dbo" />
+          <EntitySet Name="Alphabetical list of products" EntityType="Northwind.Store.Alphabetical list of products" store:Type="Views" store:Schema="dbo" store:Name="Alphabetical list of products">
+            <DefiningQuery>SELECT 
+      [Alphabetical list of products].[ProductID] AS [ProductID], 
+      [Alphabetical list of products].[ProductName] AS [ProductName], 
+      [Alphabetical list of products].[SupplierID] AS [SupplierID], 
+      [Alphabetical list of products].[CategoryID] AS [CategoryID], 
+      [Alphabetical list of products].[QuantityPerUnit] AS [QuantityPerUnit], 
+      [Alphabetical list of products].[UnitPrice] AS [UnitPrice], 
+      [Alphabetical list of products].[UnitsInStock] AS [UnitsInStock], 
+      [Alphabetical list of products].[UnitsOnOrder] AS [UnitsOnOrder], 
+      [Alphabetical list of products].[ReorderLevel] AS [ReorderLevel], 
+      [Alphabetical list of products].[Discontinued] AS [Discontinued], 
+      [Alphabetical list of products].[CategoryName] AS [CategoryName]
+      FROM [dbo].[Alphabetical list of products] AS [Alphabetical list of products]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Category Sales for 1997" EntityType="Northwind.Store.Category Sales for 1997" store:Type="Views" store:Schema="dbo" store:Name="Category Sales for 1997">
+            <DefiningQuery>SELECT 
+      [Category Sales for 1997].[CategoryName] AS [CategoryName], 
+      [Category Sales for 1997].[CategorySales] AS [CategorySales]
+      FROM [dbo].[Category Sales for 1997] AS [Category Sales for 1997]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Current Product List" EntityType="Northwind.Store.Current Product List" store:Type="Views" store:Schema="dbo" store:Name="Current Product List">
+            <DefiningQuery>SELECT 
+      [Current Product List].[ProductID] AS [ProductID], 
+      [Current Product List].[ProductName] AS [ProductName]
+      FROM [dbo].[Current Product List] AS [Current Product List]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Customer and Suppliers by City" EntityType="Northwind.Store.Customer and Suppliers by City" store:Type="Views" store:Schema="dbo" store:Name="Customer and Suppliers by City">
+            <DefiningQuery>SELECT 
+      [Customer and Suppliers by City].[City] AS [City], 
+      [Customer and Suppliers by City].[CompanyName] AS [CompanyName], 
+      [Customer and Suppliers by City].[ContactName] AS [ContactName], 
+      [Customer and Suppliers by City].[Relationship] AS [Relationship]
+      FROM [dbo].[Customer and Suppliers by City] AS [Customer and Suppliers by City]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Invoices" EntityType="Northwind.Store.Invoices" store:Type="Views" store:Schema="dbo" store:Name="Invoices">
+            <DefiningQuery>SELECT 
+      [Invoices].[ShipName] AS [ShipName], 
+      [Invoices].[ShipAddress] AS [ShipAddress], 
+      [Invoices].[ShipCity] AS [ShipCity], 
+      [Invoices].[ShipRegion] AS [ShipRegion], 
+      [Invoices].[ShipPostalCode] AS [ShipPostalCode], 
+      [Invoices].[ShipCountry] AS [ShipCountry], 
+      [Invoices].[CustomerID] AS [CustomerID], 
+      [Invoices].[CustomerName] AS [CustomerName], 
+      [Invoices].[Address] AS [Address], 
+      [Invoices].[City] AS [City], 
+      [Invoices].[Region] AS [Region], 
+      [Invoices].[PostalCode] AS [PostalCode], 
+      [Invoices].[Country] AS [Country], 
+      [Invoices].[Salesperson] AS [Salesperson], 
+      [Invoices].[OrderID] AS [OrderID], 
+      [Invoices].[OrderDate] AS [OrderDate], 
+      [Invoices].[RequiredDate] AS [RequiredDate], 
+      [Invoices].[ShippedDate] AS [ShippedDate], 
+      [Invoices].[ShipperName] AS [ShipperName], 
+      [Invoices].[ProductID] AS [ProductID], 
+      [Invoices].[ProductName] AS [ProductName], 
+      [Invoices].[UnitPrice] AS [UnitPrice], 
+      [Invoices].[Quantity] AS [Quantity], 
+      [Invoices].[Discount] AS [Discount], 
+      [Invoices].[ExtendedPrice] AS [ExtendedPrice], 
+      [Invoices].[Freight] AS [Freight]
+      FROM [dbo].[Invoices] AS [Invoices]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Order Details Extended" EntityType="Northwind.Store.Order Details Extended" store:Type="Views" store:Schema="dbo" store:Name="Order Details Extended">
+            <DefiningQuery>SELECT 
+      [Order Details Extended].[OrderID] AS [OrderID], 
+      [Order Details Extended].[ProductID] AS [ProductID], 
+      [Order Details Extended].[ProductName] AS [ProductName], 
+      [Order Details Extended].[UnitPrice] AS [UnitPrice], 
+      [Order Details Extended].[Quantity] AS [Quantity], 
+      [Order Details Extended].[Discount] AS [Discount], 
+      [Order Details Extended].[ExtendedPrice] AS [ExtendedPrice]
+      FROM [dbo].[Order Details Extended] AS [Order Details Extended]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Order Subtotals" EntityType="Northwind.Store.Order Subtotals" store:Type="Views" store:Schema="dbo" store:Name="Order Subtotals">
+            <DefiningQuery>SELECT 
+      [Order Subtotals].[OrderID] AS [OrderID], 
+      [Order Subtotals].[Subtotal] AS [Subtotal]
+      FROM [dbo].[Order Subtotals] AS [Order Subtotals]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Orders Qry" EntityType="Northwind.Store.Orders Qry" store:Type="Views" store:Schema="dbo" store:Name="Orders Qry">
+            <DefiningQuery>SELECT 
+      [Orders Qry].[OrderID] AS [OrderID], 
+      [Orders Qry].[CustomerID] AS [CustomerID], 
+      [Orders Qry].[EmployeeID] AS [EmployeeID], 
+      [Orders Qry].[OrderDate] AS [OrderDate], 
+      [Orders Qry].[RequiredDate] AS [RequiredDate], 
+      [Orders Qry].[ShippedDate] AS [ShippedDate], 
+      [Orders Qry].[ShipVia] AS [ShipVia], 
+      [Orders Qry].[Freight] AS [Freight], 
+      [Orders Qry].[ShipName] AS [ShipName], 
+      [Orders Qry].[ShipAddress] AS [ShipAddress], 
+      [Orders Qry].[ShipCity] AS [ShipCity], 
+      [Orders Qry].[ShipRegion] AS [ShipRegion], 
+      [Orders Qry].[ShipPostalCode] AS [ShipPostalCode], 
+      [Orders Qry].[ShipCountry] AS [ShipCountry], 
+      [Orders Qry].[CompanyName] AS [CompanyName], 
+      [Orders Qry].[Address] AS [Address], 
+      [Orders Qry].[City] AS [City], 
+      [Orders Qry].[Region] AS [Region], 
+      [Orders Qry].[PostalCode] AS [PostalCode], 
+      [Orders Qry].[Country] AS [Country]
+      FROM [dbo].[Orders Qry] AS [Orders Qry]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Product Sales for 1997" EntityType="Northwind.Store.Product Sales for 1997" store:Type="Views" store:Schema="dbo" store:Name="Product Sales for 1997">
+            <DefiningQuery>SELECT 
+      [Product Sales for 1997].[CategoryName] AS [CategoryName], 
+      [Product Sales for 1997].[ProductName] AS [ProductName], 
+      [Product Sales for 1997].[ProductSales] AS [ProductSales]
+      FROM [dbo].[Product Sales for 1997] AS [Product Sales for 1997]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Products Above Average Price" EntityType="Northwind.Store.Products Above Average Price" store:Type="Views" store:Schema="dbo" store:Name="Products Above Average Price">
+            <DefiningQuery>SELECT 
+      [Products Above Average Price].[ProductName] AS [ProductName], 
+      [Products Above Average Price].[UnitPrice] AS [UnitPrice]
+      FROM [dbo].[Products Above Average Price] AS [Products Above Average Price]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Products by Category" EntityType="Northwind.Store.Products by Category" store:Type="Views" store:Schema="dbo" store:Name="Products by Category">
+            <DefiningQuery>SELECT 
+      [Products by Category].[CategoryName] AS [CategoryName], 
+      [Products by Category].[ProductName] AS [ProductName], 
+      [Products by Category].[QuantityPerUnit] AS [QuantityPerUnit], 
+      [Products by Category].[UnitsInStock] AS [UnitsInStock], 
+      [Products by Category].[Discontinued] AS [Discontinued]
+      FROM [dbo].[Products by Category] AS [Products by Category]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Sales by Category" EntityType="Northwind.Store.Sales by Category" store:Type="Views" store:Schema="dbo" store:Name="Sales by Category">
+            <DefiningQuery>SELECT 
+      [Sales by Category].[CategoryID] AS [CategoryID], 
+      [Sales by Category].[CategoryName] AS [CategoryName], 
+      [Sales by Category].[ProductName] AS [ProductName], 
+      [Sales by Category].[ProductSales] AS [ProductSales]
+      FROM [dbo].[Sales by Category] AS [Sales by Category]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Sales Totals by Amount" EntityType="Northwind.Store.Sales Totals by Amount" store:Type="Views" store:Schema="dbo" store:Name="Sales Totals by Amount">
+            <DefiningQuery>SELECT 
+      [Sales Totals by Amount].[SaleAmount] AS [SaleAmount], 
+      [Sales Totals by Amount].[OrderID] AS [OrderID], 
+      [Sales Totals by Amount].[CompanyName] AS [CompanyName], 
+      [Sales Totals by Amount].[ShippedDate] AS [ShippedDate]
+      FROM [dbo].[Sales Totals by Amount] AS [Sales Totals by Amount]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Summary of Sales by Quarter" EntityType="Northwind.Store.Summary of Sales by Quarter" store:Type="Views" store:Schema="dbo" store:Name="Summary of Sales by Quarter">
+            <DefiningQuery>SELECT 
+      [Summary of Sales by Quarter].[ShippedDate] AS [ShippedDate], 
+      [Summary of Sales by Quarter].[OrderID] AS [OrderID], 
+      [Summary of Sales by Quarter].[Subtotal] AS [Subtotal]
+      FROM [dbo].[Summary of Sales by Quarter] AS [Summary of Sales by Quarter]</DefiningQuery>
+          </EntitySet>
+          <EntitySet Name="Summary of Sales by Year" EntityType="Northwind.Store.Summary of Sales by Year" store:Type="Views" store:Schema="dbo" store:Name="Summary of Sales by Year">
+            <DefiningQuery>SELECT 
+      [Summary of Sales by Year].[ShippedDate] AS [ShippedDate], 
+      [Summary of Sales by Year].[OrderID] AS [OrderID], 
+      [Summary of Sales by Year].[Subtotal] AS [Subtotal]
+      FROM [dbo].[Summary of Sales by Year] AS [Summary of Sales by Year]</DefiningQuery>
+          </EntitySet>
+          <AssociationSet Name="FK_CustomerCustomerDemo" Association="Northwind.Store.FK_CustomerCustomerDemo">
+            <End Role="CustomerDemographics" EntitySet="CustomerDemographics" />
+            <End Role="CustomerCustomerDemo" EntitySet="CustomerCustomerDemo" />
+          </AssociationSet>
+          <AssociationSet Name="FK_CustomerCustomerDemo_Customers" Association="Northwind.Store.FK_CustomerCustomerDemo_Customers">
+            <End Role="Customers" EntitySet="Customers" />
+            <End Role="CustomerCustomerDemo" EntitySet="CustomerCustomerDemo" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Employees_Employees" Association="Northwind.Store.FK_Employees_Employees">
+            <End Role="Employees" EntitySet="Employees" />
+            <End Role="Employees1" EntitySet="Employees" />
+          </AssociationSet>
+          <AssociationSet Name="FK_EmployeeTerritories_Employees" Association="Northwind.Store.FK_EmployeeTerritories_Employees">
+            <End Role="Employees" EntitySet="Employees" />
+            <End Role="EmployeeTerritories" EntitySet="EmployeeTerritories" />
+          </AssociationSet>
+          <AssociationSet Name="FK_EmployeeTerritories_Territories" Association="Northwind.Store.FK_EmployeeTerritories_Territories">
+            <End Role="Territories" EntitySet="Territories" />
+            <End Role="EmployeeTerritories" EntitySet="EmployeeTerritories" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Order_Details_Orders" Association="Northwind.Store.FK_Order_Details_Orders">
+            <End Role="Orders" EntitySet="Orders" />
+            <End Role="Order Details" EntitySet="Order Details" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Order_Details_Products" Association="Northwind.Store.FK_Order_Details_Products">
+            <End Role="Products" EntitySet="Products" />
+            <End Role="Order Details" EntitySet="Order Details" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Orders_Customers" Association="Northwind.Store.FK_Orders_Customers">
+            <End Role="Customers" EntitySet="Customers" />
+            <End Role="Orders" EntitySet="Orders" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Orders_Employees" Association="Northwind.Store.FK_Orders_Employees">
+            <End Role="Employees" EntitySet="Employees" />
+            <End Role="Orders" EntitySet="Orders" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Orders_Shippers" Association="Northwind.Store.FK_Orders_Shippers">
+            <End Role="Shippers" EntitySet="Shippers" />
+            <End Role="Orders" EntitySet="Orders" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Products_Categories" Association="Northwind.Store.FK_Products_Categories">
+            <End Role="Categories" EntitySet="Categories" />
+            <End Role="Products" EntitySet="Products" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Products_Suppliers" Association="Northwind.Store.FK_Products_Suppliers">
+            <End Role="Suppliers" EntitySet="Suppliers" />
+            <End Role="Products" EntitySet="Products" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Territories_Region" Association="Northwind.Store.FK_Territories_Region">
+            <End Role="Region" EntitySet="Region" />
+            <End Role="Territories" EntitySet="Territories" />
+          </AssociationSet>
+        </EntityContainer>
+        <EntityType Name="Categories">
+          <Key>
+            <PropertyRef Name="CategoryID" />
+          </Key>
+          <Property Name="CategoryID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
+          <Property Name="CategoryName" Type="nvarchar" Nullable="false" MaxLength="15" />
+          <Property Name="Description" Type="ntext" />
+          <Property Name="Picture" Type="image" />
+        </EntityType>
+        <EntityType Name="CustomerCustomerDemo">
+          <Key>
+            <PropertyRef Name="CustomerID" />
+            <PropertyRef Name="CustomerTypeID" />
+          </Key>
+          <Property Name="CustomerID" Type="nchar" Nullable="false" MaxLength="5" />
+          <Property Name="CustomerTypeID" Type="nchar" Nullable="false" MaxLength="10" />
+        </EntityType>
+        <EntityType Name="CustomerDemographics">
+          <Key>
+            <PropertyRef Name="CustomerTypeID" />
+          </Key>
+          <Property Name="CustomerTypeID" Type="nchar" Nullable="false" MaxLength="10" />
+          <Property Name="CustomerDesc" Type="ntext" />
+        </EntityType>
+        <EntityType Name="Customers">
+          <Key>
+            <PropertyRef Name="CustomerID" />
+          </Key>
+          <Property Name="CustomerID" Type="nchar" Nullable="false" MaxLength="5" />
+          <Property Name="CompanyName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="ContactName" Type="nvarchar" MaxLength="30" />
+          <Property Name="ContactTitle" Type="nvarchar" MaxLength="30" />
+          <Property Name="Address" Type="nvarchar" MaxLength="60" />
+          <Property Name="City" Type="nvarchar" MaxLength="15" />
+          <Property Name="Region" Type="nvarchar" MaxLength="15" />
+          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
+          <Property Name="Country" Type="nvarchar" MaxLength="15" />
+          <Property Name="Phone" Type="nvarchar" MaxLength="24" />
+          <Property Name="Fax" Type="nvarchar" MaxLength="24" />
+        </EntityType>
+        <EntityType Name="Employees">
+          <Key>
+            <PropertyRef Name="EmployeeID" />
+          </Key>
+          <Property Name="EmployeeID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
+          <Property Name="LastName" Type="nvarchar" Nullable="false" MaxLength="20" />
+          <Property Name="FirstName" Type="nvarchar" Nullable="false" MaxLength="10" />
+          <Property Name="Title" Type="nvarchar" MaxLength="30" />
+          <Property Name="TitleOfCourtesy" Type="nvarchar" MaxLength="25" />
+          <Property Name="BirthDate" Type="datetime" />
+          <Property Name="HireDate" Type="datetime" />
+          <Property Name="Address" Type="nvarchar" MaxLength="60" />
+          <Property Name="City" Type="nvarchar" MaxLength="15" />
+          <Property Name="Region" Type="nvarchar" MaxLength="15" />
+          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
+          <Property Name="Country" Type="nvarchar" MaxLength="15" />
+          <Property Name="HomePhone" Type="nvarchar" MaxLength="24" />
+          <Property Name="Extension" Type="nvarchar" MaxLength="4" />
+          <Property Name="Photo" Type="image" />
+          <Property Name="Notes" Type="ntext" />
+          <Property Name="ReportsTo" Type="int" />
+          <Property Name="PhotoPath" Type="nvarchar" MaxLength="255" />
+        </EntityType>
+        <EntityType Name="EmployeeTerritories">
+          <Key>
+            <PropertyRef Name="EmployeeID" />
+            <PropertyRef Name="TerritoryID" />
+          </Key>
+          <Property Name="EmployeeID" Type="int" Nullable="false" />
+          <Property Name="TerritoryID" Type="nvarchar" Nullable="false" MaxLength="20" />
+        </EntityType>
+        <EntityType Name="Order Details">
+          <Key>
+            <PropertyRef Name="OrderID" />
+            <PropertyRef Name="ProductID" />
+          </Key>
+          <Property Name="OrderID" Type="int" Nullable="false" />
+          <Property Name="ProductID" Type="int" Nullable="false" />
+          <Property Name="UnitPrice" Type="money" Nullable="false" />
+          <Property Name="Quantity" Type="smallint" Nullable="false" />
+          <Property Name="Discount" Type="real" Nullable="false" />
+        </EntityType>
+        <EntityType Name="Orders">
+          <Key>
+            <PropertyRef Name="OrderID" />
+          </Key>
+          <Property Name="OrderID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
+          <Property Name="CustomerID" Type="nchar" MaxLength="5" />
+          <Property Name="EmployeeID" Type="int" />
+          <Property Name="OrderDate" Type="datetime" />
+          <Property Name="RequiredDate" Type="datetime" />
+          <Property Name="ShippedDate" Type="datetime" />
+          <Property Name="ShipVia" Type="int" />
+          <Property Name="Freight" Type="money" />
+          <Property Name="ShipName" Type="nvarchar" MaxLength="40" />
+          <Property Name="ShipAddress" Type="nvarchar" MaxLength="60" />
+          <Property Name="ShipCity" Type="nvarchar" MaxLength="15" />
+          <Property Name="ShipRegion" Type="nvarchar" MaxLength="15" />
+          <Property Name="ShipPostalCode" Type="nvarchar" MaxLength="10" />
+          <Property Name="ShipCountry" Type="nvarchar" MaxLength="15" />
+        </EntityType>
+        <EntityType Name="Products">
+          <Key>
+            <PropertyRef Name="ProductID" />
+          </Key>
+          <Property Name="ProductID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
+          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="SupplierID" Type="int" />
+          <Property Name="CategoryID" Type="int" />
+          <Property Name="QuantityPerUnit" Type="nvarchar" MaxLength="20" />
+          <Property Name="UnitPrice" Type="money" />
+          <Property Name="UnitsInStock" Type="smallint" />
+          <Property Name="UnitsOnOrder" Type="smallint" />
+          <Property Name="ReorderLevel" Type="smallint" />
+          <Property Name="Discontinued" Type="bit" Nullable="false" />
+        </EntityType>
+        <EntityType Name="Region">
+          <Key>
+            <PropertyRef Name="RegionID" />
+          </Key>
+          <Property Name="RegionID" Type="int" Nullable="false" />
+          <Property Name="RegionDescription" Type="nchar" Nullable="false" MaxLength="50" />
+        </EntityType>
+        <EntityType Name="Shippers">
+          <Key>
+            <PropertyRef Name="ShipperID" />
+          </Key>
+          <Property Name="ShipperID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
+          <Property Name="CompanyName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="Phone" Type="nvarchar" MaxLength="24" />
+        </EntityType>
+        <EntityType Name="Suppliers">
+          <Key>
+            <PropertyRef Name="SupplierID" />
+          </Key>
+          <Property Name="SupplierID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
+          <Property Name="CompanyName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="ContactName" Type="nvarchar" MaxLength="30" />
+          <Property Name="ContactTitle" Type="nvarchar" MaxLength="30" />
+          <Property Name="Address" Type="nvarchar" MaxLength="60" />
+          <Property Name="City" Type="nvarchar" MaxLength="15" />
+          <Property Name="Region" Type="nvarchar" MaxLength="15" />
+          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
+          <Property Name="Country" Type="nvarchar" MaxLength="15" />
+          <Property Name="Phone" Type="nvarchar" MaxLength="24" />
+          <Property Name="Fax" Type="nvarchar" MaxLength="24" />
+          <Property Name="HomePage" Type="ntext" />
+        </EntityType>
+        <EntityType Name="Territories">
+          <Key>
+            <PropertyRef Name="TerritoryID" />
+          </Key>
+          <Property Name="TerritoryID" Type="nvarchar" Nullable="false" MaxLength="20" />
+          <Property Name="TerritoryDescription" Type="nchar" Nullable="false" MaxLength="50" />
+          <Property Name="RegionID" Type="int" Nullable="false" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Alphabetical list of products' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Alphabetical list of products">
+          <Key>
+            <PropertyRef Name="ProductID" />
+            <PropertyRef Name="ProductName" />
+            <PropertyRef Name="Discontinued" />
+            <PropertyRef Name="CategoryName" />
+          </Key>
+          <Property Name="ProductID" Type="int" Nullable="false" />
+          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="SupplierID" Type="int" />
+          <Property Name="CategoryID" Type="int" />
+          <Property Name="QuantityPerUnit" Type="nvarchar" MaxLength="20" />
+          <Property Name="UnitPrice" Type="money" />
+          <Property Name="UnitsInStock" Type="smallint" />
+          <Property Name="UnitsOnOrder" Type="smallint" />
+          <Property Name="ReorderLevel" Type="smallint" />
+          <Property Name="Discontinued" Type="bit" Nullable="false" />
+          <Property Name="CategoryName" Type="nvarchar" Nullable="false" MaxLength="15" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Category Sales for 1997' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Category Sales for 1997">
+          <Key>
+            <PropertyRef Name="CategoryName" />
+          </Key>
+          <Property Name="CategoryName" Type="nvarchar" Nullable="false" MaxLength="15" />
+          <Property Name="CategorySales" Type="money" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Current Product List' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Current Product List">
+          <Key>
+            <PropertyRef Name="ProductID" />
+            <PropertyRef Name="ProductName" />
+          </Key>
+          <Property Name="ProductID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
+          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Customer and Suppliers by City' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Customer and Suppliers by City">
+          <Key>
+            <PropertyRef Name="CompanyName" />
+            <PropertyRef Name="Relationship" />
+          </Key>
+          <Property Name="City" Type="nvarchar" MaxLength="15" />
+          <Property Name="CompanyName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="ContactName" Type="nvarchar" MaxLength="30" />
+          <Property Name="Relationship" Type="varchar" Nullable="false" MaxLength="9" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Invoices' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Invoices">
+          <Key>
+            <PropertyRef Name="CustomerName" />
+            <PropertyRef Name="Salesperson" />
+            <PropertyRef Name="OrderID" />
+            <PropertyRef Name="ShipperName" />
+            <PropertyRef Name="ProductID" />
+            <PropertyRef Name="ProductName" />
+            <PropertyRef Name="UnitPrice" />
+            <PropertyRef Name="Quantity" />
+            <PropertyRef Name="Discount" />
+          </Key>
+          <Property Name="ShipName" Type="nvarchar" MaxLength="40" />
+          <Property Name="ShipAddress" Type="nvarchar" MaxLength="60" />
+          <Property Name="ShipCity" Type="nvarchar" MaxLength="15" />
+          <Property Name="ShipRegion" Type="nvarchar" MaxLength="15" />
+          <Property Name="ShipPostalCode" Type="nvarchar" MaxLength="10" />
+          <Property Name="ShipCountry" Type="nvarchar" MaxLength="15" />
+          <Property Name="CustomerID" Type="nchar" MaxLength="5" />
+          <Property Name="CustomerName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="Address" Type="nvarchar" MaxLength="60" />
+          <Property Name="City" Type="nvarchar" MaxLength="15" />
+          <Property Name="Region" Type="nvarchar" MaxLength="15" />
+          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
+          <Property Name="Country" Type="nvarchar" MaxLength="15" />
+          <Property Name="Salesperson" Type="nvarchar" Nullable="false" MaxLength="31" />
+          <Property Name="OrderID" Type="int" Nullable="false" />
+          <Property Name="OrderDate" Type="datetime" />
+          <Property Name="RequiredDate" Type="datetime" />
+          <Property Name="ShippedDate" Type="datetime" />
+          <Property Name="ShipperName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="ProductID" Type="int" Nullable="false" />
+          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="UnitPrice" Type="money" Nullable="false" />
+          <Property Name="Quantity" Type="smallint" Nullable="false" />
+          <Property Name="Discount" Type="real" Nullable="false" />
+          <Property Name="ExtendedPrice" Type="money" />
+          <Property Name="Freight" Type="money" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Order Details Extended' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Order Details Extended">
+          <Key>
+            <PropertyRef Name="OrderID" />
+            <PropertyRef Name="ProductID" />
+            <PropertyRef Name="ProductName" />
+            <PropertyRef Name="UnitPrice" />
+            <PropertyRef Name="Quantity" />
+            <PropertyRef Name="Discount" />
+          </Key>
+          <Property Name="OrderID" Type="int" Nullable="false" />
+          <Property Name="ProductID" Type="int" Nullable="false" />
+          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="UnitPrice" Type="money" Nullable="false" />
+          <Property Name="Quantity" Type="smallint" Nullable="false" />
+          <Property Name="Discount" Type="real" Nullable="false" />
+          <Property Name="ExtendedPrice" Type="money" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Order Subtotals' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Order Subtotals">
+          <Key>
+            <PropertyRef Name="OrderID" />
+          </Key>
+          <Property Name="OrderID" Type="int" Nullable="false" />
+          <Property Name="Subtotal" Type="money" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Orders Qry' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Orders Qry">
+          <Key>
+            <PropertyRef Name="OrderID" />
+            <PropertyRef Name="CompanyName" />
+          </Key>
+          <Property Name="OrderID" Type="int" Nullable="false" />
+          <Property Name="CustomerID" Type="nchar" MaxLength="5" />
+          <Property Name="EmployeeID" Type="int" />
+          <Property Name="OrderDate" Type="datetime" />
+          <Property Name="RequiredDate" Type="datetime" />
+          <Property Name="ShippedDate" Type="datetime" />
+          <Property Name="ShipVia" Type="int" />
+          <Property Name="Freight" Type="money" />
+          <Property Name="ShipName" Type="nvarchar" MaxLength="40" />
+          <Property Name="ShipAddress" Type="nvarchar" MaxLength="60" />
+          <Property Name="ShipCity" Type="nvarchar" MaxLength="15" />
+          <Property Name="ShipRegion" Type="nvarchar" MaxLength="15" />
+          <Property Name="ShipPostalCode" Type="nvarchar" MaxLength="10" />
+          <Property Name="ShipCountry" Type="nvarchar" MaxLength="15" />
+          <Property Name="CompanyName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="Address" Type="nvarchar" MaxLength="60" />
+          <Property Name="City" Type="nvarchar" MaxLength="15" />
+          <Property Name="Region" Type="nvarchar" MaxLength="15" />
+          <Property Name="PostalCode" Type="nvarchar" MaxLength="10" />
+          <Property Name="Country" Type="nvarchar" MaxLength="15" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Product Sales for 1997' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Product Sales for 1997">
+          <Key>
+            <PropertyRef Name="CategoryName" />
+            <PropertyRef Name="ProductName" />
+          </Key>
+          <Property Name="CategoryName" Type="nvarchar" Nullable="false" MaxLength="15" />
+          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="ProductSales" Type="money" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Products Above Average Price' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Products Above Average Price">
+          <Key>
+            <PropertyRef Name="ProductName" />
+          </Key>
+          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="UnitPrice" Type="money" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Products by Category' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Products by Category">
+          <Key>
+            <PropertyRef Name="CategoryName" />
+            <PropertyRef Name="ProductName" />
+            <PropertyRef Name="Discontinued" />
+          </Key>
+          <Property Name="CategoryName" Type="nvarchar" Nullable="false" MaxLength="15" />
+          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="QuantityPerUnit" Type="nvarchar" MaxLength="20" />
+          <Property Name="UnitsInStock" Type="smallint" />
+          <Property Name="Discontinued" Type="bit" Nullable="false" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Sales by Category' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Sales by Category">
+          <Key>
+            <PropertyRef Name="CategoryID" />
+            <PropertyRef Name="CategoryName" />
+            <PropertyRef Name="ProductName" />
+          </Key>
+          <Property Name="CategoryID" Type="int" Nullable="false" />
+          <Property Name="CategoryName" Type="nvarchar" Nullable="false" MaxLength="15" />
+          <Property Name="ProductName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="ProductSales" Type="money" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Sales Totals by Amount' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Sales Totals by Amount">
+          <Key>
+            <PropertyRef Name="OrderID" />
+            <PropertyRef Name="CompanyName" />
+          </Key>
+          <Property Name="SaleAmount" Type="money" />
+          <Property Name="OrderID" Type="int" Nullable="false" />
+          <Property Name="CompanyName" Type="nvarchar" Nullable="false" MaxLength="40" />
+          <Property Name="ShippedDate" Type="datetime" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Summary of Sales by Quarter' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Summary of Sales by Quarter">
+          <Key>
+            <PropertyRef Name="OrderID" />
+          </Key>
+          <Property Name="ShippedDate" Type="datetime" />
+          <Property Name="OrderID" Type="int" Nullable="false" />
+          <Property Name="Subtotal" Type="money" />
+        </EntityType>
+        <!--Errors Found During Generation:
+      warning 6002: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Summary of Sales by Year' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
+      -->
+        <EntityType Name="Summary of Sales by Year">
+          <Key>
+            <PropertyRef Name="OrderID" />
+          </Key>
+          <Property Name="ShippedDate" Type="datetime" />
+          <Property Name="OrderID" Type="int" Nullable="false" />
+          <Property Name="Subtotal" Type="money" />
+        </EntityType>
+        <Association Name="FK_CustomerCustomerDemo">
+          <End Role="CustomerDemographics" Type="Northwind.Store.CustomerDemographics" Multiplicity="1" />
+          <End Role="CustomerCustomerDemo" Type="Northwind.Store.CustomerCustomerDemo" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="CustomerDemographics">
+              <PropertyRef Name="CustomerTypeID" />
+            </Principal>
+            <Dependent Role="CustomerCustomerDemo">
+              <PropertyRef Name="CustomerTypeID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_CustomerCustomerDemo_Customers">
+          <End Role="Customers" Type="Northwind.Store.Customers" Multiplicity="1" />
+          <End Role="CustomerCustomerDemo" Type="Northwind.Store.CustomerCustomerDemo" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Customers">
+              <PropertyRef Name="CustomerID" />
+            </Principal>
+            <Dependent Role="CustomerCustomerDemo">
+              <PropertyRef Name="CustomerID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Employees_Employees">
+          <End Role="Employees" Type="Northwind.Store.Employees" Multiplicity="0..1" />
+          <End Role="Employees1" Type="Northwind.Store.Employees" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Employees">
+              <PropertyRef Name="EmployeeID" />
+            </Principal>
+            <Dependent Role="Employees1">
+              <PropertyRef Name="ReportsTo" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_EmployeeTerritories_Employees">
+          <End Role="Employees" Type="Northwind.Store.Employees" Multiplicity="1" />
+          <End Role="EmployeeTerritories" Type="Northwind.Store.EmployeeTerritories" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Employees">
+              <PropertyRef Name="EmployeeID" />
+            </Principal>
+            <Dependent Role="EmployeeTerritories">
+              <PropertyRef Name="EmployeeID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_EmployeeTerritories_Territories">
+          <End Role="Territories" Type="Northwind.Store.Territories" Multiplicity="1" />
+          <End Role="EmployeeTerritories" Type="Northwind.Store.EmployeeTerritories" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Territories">
+              <PropertyRef Name="TerritoryID" />
+            </Principal>
+            <Dependent Role="EmployeeTerritories">
+              <PropertyRef Name="TerritoryID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Order_Details_Orders">
+          <End Role="Orders" Type="Northwind.Store.Orders" Multiplicity="1" />
+          <End Role="Order Details" Type="Northwind.Store.Order Details" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Orders">
+              <PropertyRef Name="OrderID" />
+            </Principal>
+            <Dependent Role="Order Details">
+              <PropertyRef Name="OrderID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Order_Details_Products">
+          <End Role="Products" Type="Northwind.Store.Products" Multiplicity="1" />
+          <End Role="Order Details" Type="Northwind.Store.Order Details" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Products">
+              <PropertyRef Name="ProductID" />
+            </Principal>
+            <Dependent Role="Order Details">
+              <PropertyRef Name="ProductID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Orders_Customers">
+          <End Role="Customers" Type="Northwind.Store.Customers" Multiplicity="0..1" />
+          <End Role="Orders" Type="Northwind.Store.Orders" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Customers">
+              <PropertyRef Name="CustomerID" />
+            </Principal>
+            <Dependent Role="Orders">
+              <PropertyRef Name="CustomerID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Orders_Employees">
+          <End Role="Employees" Type="Northwind.Store.Employees" Multiplicity="0..1" />
+          <End Role="Orders" Type="Northwind.Store.Orders" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Employees">
+              <PropertyRef Name="EmployeeID" />
+            </Principal>
+            <Dependent Role="Orders">
+              <PropertyRef Name="EmployeeID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Orders_Shippers">
+          <End Role="Shippers" Type="Northwind.Store.Shippers" Multiplicity="0..1" />
+          <End Role="Orders" Type="Northwind.Store.Orders" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Shippers">
+              <PropertyRef Name="ShipperID" />
+            </Principal>
+            <Dependent Role="Orders">
+              <PropertyRef Name="ShipVia" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Products_Categories">
+          <End Role="Categories" Type="Northwind.Store.Categories" Multiplicity="0..1" />
+          <End Role="Products" Type="Northwind.Store.Products" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Categories">
+              <PropertyRef Name="CategoryID" />
+            </Principal>
+            <Dependent Role="Products">
+              <PropertyRef Name="CategoryID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Products_Suppliers">
+          <End Role="Suppliers" Type="Northwind.Store.Suppliers" Multiplicity="0..1" />
+          <End Role="Products" Type="Northwind.Store.Products" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Suppliers">
+              <PropertyRef Name="SupplierID" />
+            </Principal>
+            <Dependent Role="Products">
+              <PropertyRef Name="SupplierID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Territories_Region">
+          <End Role="Region" Type="Northwind.Store.Region" Multiplicity="1" />
+          <End Role="Territories" Type="Northwind.Store.Territories" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Region">
+              <PropertyRef Name="RegionID" />
+            </Principal>
+            <Dependent Role="Territories">
+              <PropertyRef Name="RegionID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Function Name="CustOrderHist" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
+          <Parameter Name="CustomerID" Type="nchar" Mode="In" />
+        </Function>
+        <Function Name="CustOrdersDetail" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
+          <Parameter Name="OrderID" Type="int" Mode="In" />
+        </Function>
+        <Function Name="CustOrdersOrders" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
+          <Parameter Name="CustomerID" Type="nchar" Mode="In" />
+        </Function>
+        <Function Name="Employee_Sales_by_Country" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" StoreFunctionName="Employee Sales by Country" Schema="dbo">
+          <Parameter Name="Beginning_Date" Type="datetime" Mode="In" />
+          <Parameter Name="Ending_Date" Type="datetime" Mode="In" />
+        </Function>
+        <Function Name="Sales_by_Year" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" StoreFunctionName="Sales by Year" Schema="dbo">
+          <Parameter Name="Beginning_Date" Type="datetime" Mode="In" />
+          <Parameter Name="Ending_Date" Type="datetime" Mode="In" />
+        </Function>
+        <Function Name="SalesByCategory" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
+          <Parameter Name="CategoryName" Type="nvarchar" Mode="In" />
+          <Parameter Name="OrdYear" Type="nvarchar" Mode="In" />
+        </Function>
+        <Function Name="Ten_Most_Expensive_Products" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" StoreFunctionName="Ten Most Expensive Products" Schema="dbo" />
+        <!--Errors Found During Generation:
+      warning 6013: The table/view 'C:\TOMAS\PROJECTS\FSHARP\POWERPACK\WORKYARD\LINQ\FSHARP.POWERPACK.UNITTESTS\NORTHWND.MDF.dbo.Quarterly Orders' does not have a primary key defined and no valid primary key could be inferred. This table/view has been excluded. To use the entity, you will need to review your schema, add the correct keys, and uncomment it.
+      
+      <EntityType Name="Quarterly Orders">
+        <Property Name="CustomerID" Type="nchar" MaxLength="5" />
+        <Property Name="CompanyName" Type="nvarchar" MaxLength="40" />
+        <Property Name="City" Type="nvarchar" MaxLength="15" />
+        <Property Name="Country" Type="nvarchar" MaxLength="15" />
+      </EntityType>-->
+      </Schema>
+    </edmx:StorageModels>
+    <!-- CSDL content -->
+    <edmx:ConceptualModels>
+      <Schema Namespace="Northwind" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
+        <EntityContainer Name="Entities" annotation:LazyLoadingEnabled="true">
+          <EntitySet Name="Categories" EntityType="Northwind.Category" />
+          <EntitySet Name="CustomerDemographics" EntityType="Northwind.CustomerDemographic" />
+          <EntitySet Name="Customers" EntityType="Northwind.Customer" />
+          <EntitySet Name="Employees" EntityType="Northwind.Employee" />
+          <EntitySet Name="Order_Details" EntityType="Northwind.Order_Detail" />
+          <EntitySet Name="Orders" EntityType="Northwind.Order" />
+          <EntitySet Name="Products" EntityType="Northwind.Product" />
+          <EntitySet Name="Regions" EntityType="Northwind.Region" />
+          <EntitySet Name="Shippers" EntityType="Northwind.Shipper" />
+          <EntitySet Name="Suppliers" EntityType="Northwind.Supplier" />
+          <EntitySet Name="Territories" EntityType="Northwind.Territory" />
+          <EntitySet Name="Alphabetical_list_of_products" EntityType="Northwind.Alphabetical_list_of_product" />
+          <EntitySet Name="Category_Sales_for_1997" EntityType="Northwind.Category_Sales_for_1997" />
+          <EntitySet Name="Current_Product_Lists" EntityType="Northwind.Current_Product_List" />
+          <EntitySet Name="Customer_and_Suppliers_by_Cities" EntityType="Northwind.Customer_and_Suppliers_by_City" />
+          <EntitySet Name="Invoices" EntityType="Northwind.Invoice" />
+          <EntitySet Name="Order_Details_Extendeds" EntityType="Northwind.Order_Details_Extended" />
+          <EntitySet Name="Order_Subtotals" EntityType="Northwind.Order_Subtotal" />
+          <EntitySet Name="Orders_Qries" EntityType="Northwind.Orders_Qry" />
+          <EntitySet Name="Product_Sales_for_1997" EntityType="Northwind.Product_Sales_for_1997" />
+          <EntitySet Name="Products_Above_Average_Prices" EntityType="Northwind.Products_Above_Average_Price" />
+          <EntitySet Name="Products_by_Categories" EntityType="Northwind.Products_by_Category" />
+          <EntitySet Name="Sales_by_Categories" EntityType="Northwind.Sales_by_Category" />
+          <EntitySet Name="Sales_Totals_by_Amounts" EntityType="Northwind.Sales_Totals_by_Amount" />
+          <EntitySet Name="Summary_of_Sales_by_Quarters" EntityType="Northwind.Summary_of_Sales_by_Quarter" />
+          <EntitySet Name="Summary_of_Sales_by_Years" EntityType="Northwind.Summary_of_Sales_by_Year" />
+          <AssociationSet Name="FK_Products_Categories" Association="Northwind.FK_Products_Categories">
+            <End Role="Categories" EntitySet="Categories" />
+            <End Role="Products" EntitySet="Products" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Orders_Customers" Association="Northwind.FK_Orders_Customers">
+            <End Role="Customers" EntitySet="Customers" />
+            <End Role="Orders" EntitySet="Orders" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Employees_Employees" Association="Northwind.FK_Employees_Employees">
+            <End Role="Employees" EntitySet="Employees" />
+            <End Role="Employees1" EntitySet="Employees" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Orders_Employees" Association="Northwind.FK_Orders_Employees">
+            <End Role="Employees" EntitySet="Employees" />
+            <End Role="Orders" EntitySet="Orders" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Order_Details_Orders" Association="Northwind.FK_Order_Details_Orders">
+            <End Role="Orders" EntitySet="Orders" />
+            <End Role="Order_Details" EntitySet="Order_Details" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Order_Details_Products" Association="Northwind.FK_Order_Details_Products">
+            <End Role="Products" EntitySet="Products" />
+            <End Role="Order_Details" EntitySet="Order_Details" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Orders_Shippers" Association="Northwind.FK_Orders_Shippers">
+            <End Role="Shippers" EntitySet="Shippers" />
+            <End Role="Orders" EntitySet="Orders" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Products_Suppliers" Association="Northwind.FK_Products_Suppliers">
+            <End Role="Suppliers" EntitySet="Suppliers" />
+            <End Role="Products" EntitySet="Products" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Territories_Region" Association="Northwind.FK_Territories_Region">
+            <End Role="Region" EntitySet="Regions" />
+            <End Role="Territories" EntitySet="Territories" />
+          </AssociationSet>
+          <AssociationSet Name="CustomerCustomerDemo" Association="Northwind.CustomerCustomerDemo">
+            <End Role="CustomerDemographics" EntitySet="CustomerDemographics" />
+            <End Role="Customers" EntitySet="Customers" />
+          </AssociationSet>
+          <AssociationSet Name="EmployeeTerritories" Association="Northwind.EmployeeTerritories">
+            <End Role="Employees" EntitySet="Employees" />
+            <End Role="Territories" EntitySet="Territories" />
+          </AssociationSet>
+        </EntityContainer>
+        <EntityType Name="Category">
+          <Key>
+            <PropertyRef Name="CategoryID" />
+          </Key>
+          <Property Name="CategoryID" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
+          <Property Name="CategoryName" Type="String" Nullable="false" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="Description" Type="String" MaxLength="Max" Unicode="true" FixedLength="false" />
+          <Property Name="Picture" Type="Binary" MaxLength="Max" FixedLength="false" />
+          <NavigationProperty Name="Products" Relationship="Northwind.FK_Products_Categories" FromRole="Categories" ToRole="Products" />
+        </EntityType>
+        <EntityType Name="CustomerDemographic">
+          <Key>
+            <PropertyRef Name="CustomerTypeID" />
+          </Key>
+          <Property Name="CustomerTypeID" Type="String" Nullable="false" MaxLength="10" Unicode="true" FixedLength="true" />
+          <Property Name="CustomerDesc" Type="String" MaxLength="Max" Unicode="true" FixedLength="false" />
+          <NavigationProperty Name="Customers" Relationship="Northwind.CustomerCustomerDemo" FromRole="CustomerDemographics" ToRole="Customers" />
+        </EntityType>
+        <EntityType Name="Customer">
+          <Key>
+            <PropertyRef Name="CustomerID" />
+          </Key>
+          <Property Name="CustomerID" Type="String" Nullable="false" MaxLength="5" Unicode="true" FixedLength="true" />
+          <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="ContactName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
+          <Property Name="ContactTitle" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
+          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
+          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
+          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="Phone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
+          <Property Name="Fax" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
+          <NavigationProperty Name="Orders" Relationship="Northwind.FK_Orders_Customers" FromRole="Customers" ToRole="Orders" />
+          <NavigationProperty Name="CustomerDemographics" Relationship="Northwind.CustomerCustomerDemo" FromRole="Customers" ToRole="CustomerDemographics" />
+        </EntityType>
+        <EntityType Name="Employee">
+          <Key>
+            <PropertyRef Name="EmployeeID" />
+          </Key>
+          <Property Name="EmployeeID" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
+          <Property Name="LastName" Type="String" Nullable="false" MaxLength="20" Unicode="true" FixedLength="false" />
+          <Property Name="FirstName" Type="String" Nullable="false" MaxLength="10" Unicode="true" FixedLength="false" />
+          <Property Name="Title" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
+          <Property Name="TitleOfCourtesy" Type="String" MaxLength="25" Unicode="true" FixedLength="false" />
+          <Property Name="BirthDate" Type="DateTime" />
+          <Property Name="HireDate" Type="DateTime" />
+          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
+          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
+          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="HomePhone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
+          <Property Name="Extension" Type="String" MaxLength="4" Unicode="true" FixedLength="false" />
+          <Property Name="Photo" Type="Binary" MaxLength="Max" FixedLength="false" />
+          <Property Name="Notes" Type="String" MaxLength="Max" Unicode="true" FixedLength="false" />
+          <Property Name="ReportsTo" Type="Int32" />
+          <Property Name="PhotoPath" Type="String" MaxLength="255" Unicode="true" FixedLength="false" />
+          <NavigationProperty Name="Employees1" Relationship="Northwind.FK_Employees_Employees" FromRole="Employees" ToRole="Employees1" />
+          <NavigationProperty Name="Employee1" Relationship="Northwind.FK_Employees_Employees" FromRole="Employees1" ToRole="Employees" />
+          <NavigationProperty Name="Orders" Relationship="Northwind.FK_Orders_Employees" FromRole="Employees" ToRole="Orders" />
+          <NavigationProperty Name="Territories" Relationship="Northwind.EmployeeTerritories" FromRole="Employees" ToRole="Territories" />
+        </EntityType>
+        <EntityType Name="Order_Detail">
+          <Key>
+            <PropertyRef Name="OrderID" />
+            <PropertyRef Name="ProductID" />
+          </Key>
+          <Property Name="OrderID" Type="Int32" Nullable="false" />
+          <Property Name="ProductID" Type="Int32" Nullable="false" />
+          <Property Name="UnitPrice" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
+          <Property Name="Quantity" Type="Int16" Nullable="false" />
+          <Property Name="Discount" Type="Single" Nullable="false" />
+          <NavigationProperty Name="Order" Relationship="Northwind.FK_Order_Details_Orders" FromRole="Order_Details" ToRole="Orders" />
+          <NavigationProperty Name="Product" Relationship="Northwind.FK_Order_Details_Products" FromRole="Order_Details" ToRole="Products" />
+        </EntityType>
+        <EntityType Name="Order">
+          <Key>
+            <PropertyRef Name="OrderID" />
+          </Key>
+          <Property Name="OrderID" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
+          <Property Name="CustomerID" Type="String" MaxLength="5" Unicode="true" FixedLength="true" />
+          <Property Name="EmployeeID" Type="Int32" />
+          <Property Name="OrderDate" Type="DateTime" />
+          <Property Name="RequiredDate" Type="DateTime" />
+          <Property Name="ShippedDate" Type="DateTime" />
+          <Property Name="ShipVia" Type="Int32" />
+          <Property Name="Freight" Type="Decimal" Precision="19" Scale="4" />
+          <Property Name="ShipName" Type="String" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="ShipAddress" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
+          <Property Name="ShipCity" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="ShipRegion" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="ShipPostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
+          <Property Name="ShipCountry" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <NavigationProperty Name="Customer" Relationship="Northwind.FK_Orders_Customers" FromRole="Orders" ToRole="Customers" />
+          <NavigationProperty Name="Employee" Relationship="Northwind.FK_Orders_Employees" FromRole="Orders" ToRole="Employees" />
+          <NavigationProperty Name="Order_Details" Relationship="Northwind.FK_Order_Details_Orders" FromRole="Orders" ToRole="Order_Details" />
+          <NavigationProperty Name="Shipper" Relationship="Northwind.FK_Orders_Shippers" FromRole="Orders" ToRole="Shippers" />
+        </EntityType>
+        <EntityType Name="Product">
+          <Key>
+            <PropertyRef Name="ProductID" />
+          </Key>
+          <Property Name="ProductID" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
+          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="SupplierID" Type="Int32" />
+          <Property Name="CategoryID" Type="Int32" />
+          <Property Name="QuantityPerUnit" Type="String" MaxLength="20" Unicode="true" FixedLength="false" />
+          <Property Name="UnitPrice" Type="Decimal" Precision="19" Scale="4" />
+          <Property Name="UnitsInStock" Type="Int16" />
+          <Property Name="UnitsOnOrder" Type="Int16" />
+          <Property Name="ReorderLevel" Type="Int16" />
+          <Property Name="Discontinued" Type="Boolean" Nullable="false" />
+          <NavigationProperty Name="Category" Relationship="Northwind.FK_Products_Categories" FromRole="Products" ToRole="Categories" />
+          <NavigationProperty Name="Order_Details" Relationship="Northwind.FK_Order_Details_Products" FromRole="Products" ToRole="Order_Details" />
+          <NavigationProperty Name="Supplier" Relationship="Northwind.FK_Products_Suppliers" FromRole="Products" ToRole="Suppliers" />
+        </EntityType>
+        <EntityType Name="Region">
+          <Key>
+            <PropertyRef Name="RegionID" />
+          </Key>
+          <Property Name="RegionID" Type="Int32" Nullable="false" />
+          <Property Name="RegionDescription" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="true" />
+          <NavigationProperty Name="Territories" Relationship="Northwind.FK_Territories_Region" FromRole="Region" ToRole="Territories" />
+        </EntityType>
+        <EntityType Name="Shipper">
+          <Key>
+            <PropertyRef Name="ShipperID" />
+          </Key>
+          <Property Name="ShipperID" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
+          <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="Phone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
+          <NavigationProperty Name="Orders" Relationship="Northwind.FK_Orders_Shippers" FromRole="Shippers" ToRole="Orders" />
+        </EntityType>
+        <EntityType Name="Supplier">
+          <Key>
+            <PropertyRef Name="SupplierID" />
+          </Key>
+          <Property Name="SupplierID" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
+          <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="ContactName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
+          <Property Name="ContactTitle" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
+          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
+          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
+          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="Phone" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
+          <Property Name="Fax" Type="String" MaxLength="24" Unicode="true" FixedLength="false" />
+          <Property Name="HomePage" Type="String" MaxLength="Max" Unicode="true" FixedLength="false" />
+          <NavigationProperty Name="Products" Relationship="Northwind.FK_Products_Suppliers" FromRole="Suppliers" ToRole="Products" />
+        </EntityType>
+        <EntityType Name="Territory">
+          <Key>
+            <PropertyRef Name="TerritoryID" />
+          </Key>
+          <Property Name="TerritoryID" Type="String" Nullable="false" MaxLength="20" Unicode="true" FixedLength="false" />
+          <Property Name="TerritoryDescription" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="true" />
+          <Property Name="RegionID" Type="Int32" Nullable="false" />
+          <NavigationProperty Name="Region" Relationship="Northwind.FK_Territories_Region" FromRole="Territories" ToRole="Region" />
+          <NavigationProperty Name="Employees" Relationship="Northwind.EmployeeTerritories" FromRole="Territories" ToRole="Employees" />
+        </EntityType>
+        <EntityType Name="Alphabetical_list_of_product">
+          <Key>
+            <PropertyRef Name="ProductID" />
+            <PropertyRef Name="ProductName" />
+            <PropertyRef Name="Discontinued" />
+            <PropertyRef Name="CategoryName" />
+          </Key>
+          <Property Name="ProductID" Type="Int32" Nullable="false" />
+          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="SupplierID" Type="Int32" />
+          <Property Name="CategoryID" Type="Int32" />
+          <Property Name="QuantityPerUnit" Type="String" MaxLength="20" Unicode="true" FixedLength="false" />
+          <Property Name="UnitPrice" Type="Decimal" Precision="19" Scale="4" />
+          <Property Name="UnitsInStock" Type="Int16" />
+          <Property Name="UnitsOnOrder" Type="Int16" />
+          <Property Name="ReorderLevel" Type="Int16" />
+          <Property Name="Discontinued" Type="Boolean" Nullable="false" />
+          <Property Name="CategoryName" Type="String" Nullable="false" MaxLength="15" Unicode="true" FixedLength="false" />
+        </EntityType>
+        <EntityType Name="Category_Sales_for_1997">
+          <Key>
+            <PropertyRef Name="CategoryName" />
+          </Key>
+          <Property Name="CategoryName" Type="String" Nullable="false" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="CategorySales" Type="Decimal" Precision="19" Scale="4" />
+        </EntityType>
+        <EntityType Name="Current_Product_List">
+          <Key>
+            <PropertyRef Name="ProductID" />
+            <PropertyRef Name="ProductName" />
+          </Key>
+          <Property Name="ProductID" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
+          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+        </EntityType>
+        <EntityType Name="Customer_and_Suppliers_by_City">
+          <Key>
+            <PropertyRef Name="CompanyName" />
+            <PropertyRef Name="Relationship" />
+          </Key>
+          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="ContactName" Type="String" MaxLength="30" Unicode="true" FixedLength="false" />
+          <Property Name="Relationship" Type="String" Nullable="false" MaxLength="9" Unicode="false" FixedLength="false" />
+        </EntityType>
+        <EntityType Name="Invoice">
+          <Key>
+            <PropertyRef Name="CustomerName" />
+            <PropertyRef Name="Salesperson" />
+            <PropertyRef Name="OrderID" />
+            <PropertyRef Name="ShipperName" />
+            <PropertyRef Name="ProductID" />
+            <PropertyRef Name="ProductName" />
+            <PropertyRef Name="UnitPrice" />
+            <PropertyRef Name="Quantity" />
+            <PropertyRef Name="Discount" />
+          </Key>
+          <Property Name="ShipName" Type="String" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="ShipAddress" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
+          <Property Name="ShipCity" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="ShipRegion" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="ShipPostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
+          <Property Name="ShipCountry" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="CustomerID" Type="String" MaxLength="5" Unicode="true" FixedLength="true" />
+          <Property Name="CustomerName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
+          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
+          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="Salesperson" Type="String" Nullable="false" MaxLength="31" Unicode="true" FixedLength="false" />
+          <Property Name="OrderID" Type="Int32" Nullable="false" />
+          <Property Name="OrderDate" Type="DateTime" />
+          <Property Name="RequiredDate" Type="DateTime" />
+          <Property Name="ShippedDate" Type="DateTime" />
+          <Property Name="ShipperName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="ProductID" Type="Int32" Nullable="false" />
+          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="UnitPrice" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
+          <Property Name="Quantity" Type="Int16" Nullable="false" />
+          <Property Name="Discount" Type="Single" Nullable="false" />
+          <Property Name="ExtendedPrice" Type="Decimal" Precision="19" Scale="4" />
+          <Property Name="Freight" Type="Decimal" Precision="19" Scale="4" />
+        </EntityType>
+        <EntityType Name="Order_Details_Extended">
+          <Key>
+            <PropertyRef Name="OrderID" />
+            <PropertyRef Name="ProductID" />
+            <PropertyRef Name="ProductName" />
+            <PropertyRef Name="UnitPrice" />
+            <PropertyRef Name="Quantity" />
+            <PropertyRef Name="Discount" />
+          </Key>
+          <Property Name="OrderID" Type="Int32" Nullable="false" />
+          <Property Name="ProductID" Type="Int32" Nullable="false" />
+          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="UnitPrice" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
+          <Property Name="Quantity" Type="Int16" Nullable="false" />
+          <Property Name="Discount" Type="Single" Nullable="false" />
+          <Property Name="ExtendedPrice" Type="Decimal" Precision="19" Scale="4" />
+        </EntityType>
+        <EntityType Name="Order_Subtotal">
+          <Key>
+            <PropertyRef Name="OrderID" />
+          </Key>
+          <Property Name="OrderID" Type="Int32" Nullable="false" />
+          <Property Name="Subtotal" Type="Decimal" Precision="19" Scale="4" />
+        </EntityType>
+        <EntityType Name="Orders_Qry">
+          <Key>
+            <PropertyRef Name="OrderID" />
+            <PropertyRef Name="CompanyName" />
+          </Key>
+          <Property Name="OrderID" Type="Int32" Nullable="false" />
+          <Property Name="CustomerID" Type="String" MaxLength="5" Unicode="true" FixedLength="true" />
+          <Property Name="EmployeeID" Type="Int32" />
+          <Property Name="OrderDate" Type="DateTime" />
+          <Property Name="RequiredDate" Type="DateTime" />
+          <Property Name="ShippedDate" Type="DateTime" />
+          <Property Name="ShipVia" Type="Int32" />
+          <Property Name="Freight" Type="Decimal" Precision="19" Scale="4" />
+          <Property Name="ShipName" Type="String" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="ShipAddress" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
+          <Property Name="ShipCity" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="ShipRegion" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="ShipPostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
+          <Property Name="ShipCountry" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="Address" Type="String" MaxLength="60" Unicode="true" FixedLength="false" />
+          <Property Name="City" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="Region" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="PostalCode" Type="String" MaxLength="10" Unicode="true" FixedLength="false" />
+          <Property Name="Country" Type="String" MaxLength="15" Unicode="true" FixedLength="false" />
+        </EntityType>
+        <EntityType Name="Product_Sales_for_1997">
+          <Key>
+            <PropertyRef Name="CategoryName" />
+            <PropertyRef Name="ProductName" />
+          </Key>
+          <Property Name="CategoryName" Type="String" Nullable="false" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="ProductSales" Type="Decimal" Precision="19" Scale="4" />
+        </EntityType>
+        <EntityType Name="Products_Above_Average_Price">
+          <Key>
+            <PropertyRef Name="ProductName" />
+          </Key>
+          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="UnitPrice" Type="Decimal" Precision="19" Scale="4" />
+        </EntityType>
+        <EntityType Name="Products_by_Category">
+          <Key>
+            <PropertyRef Name="CategoryName" />
+            <PropertyRef Name="ProductName" />
+            <PropertyRef Name="Discontinued" />
+          </Key>
+          <Property Name="CategoryName" Type="String" Nullable="false" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="QuantityPerUnit" Type="String" MaxLength="20" Unicode="true" FixedLength="false" />
+          <Property Name="UnitsInStock" Type="Int16" />
+          <Property Name="Discontinued" Type="Boolean" Nullable="false" />
+        </EntityType>
+        <EntityType Name="Sales_by_Category">
+          <Key>
+            <PropertyRef Name="CategoryID" />
+            <PropertyRef Name="CategoryName" />
+            <PropertyRef Name="ProductName" />
+          </Key>
+          <Property Name="CategoryID" Type="Int32" Nullable="false" />
+          <Property Name="CategoryName" Type="String" Nullable="false" MaxLength="15" Unicode="true" FixedLength="false" />
+          <Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="ProductSales" Type="Decimal" Precision="19" Scale="4" />
+        </EntityType>
+        <EntityType Name="Sales_Totals_by_Amount">
+          <Key>
+            <PropertyRef Name="OrderID" />
+            <PropertyRef Name="CompanyName" />
+          </Key>
+          <Property Name="SaleAmount" Type="Decimal" Precision="19" Scale="4" />
+          <Property Name="OrderID" Type="Int32" Nullable="false" />
+          <Property Name="CompanyName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" />
+          <Property Name="ShippedDate" Type="DateTime" />
+        </EntityType>
+        <EntityType Name="Summary_of_Sales_by_Quarter">
+          <Key>
+            <PropertyRef Name="OrderID" />
+          </Key>
+          <Property Name="ShippedDate" Type="DateTime" />
+          <Property Name="OrderID" Type="Int32" Nullable="false" />
+          <Property Name="Subtotal" Type="Decimal" Precision="19" Scale="4" />
+        </EntityType>
+        <EntityType Name="Summary_of_Sales_by_Year">
+          <Key>
+            <PropertyRef Name="OrderID" />
+          </Key>
+          <Property Name="ShippedDate" Type="DateTime" />
+          <Property Name="OrderID" Type="Int32" Nullable="false" />
+          <Property Name="Subtotal" Type="Decimal" Precision="19" Scale="4" />
+        </EntityType>
+        <Association Name="FK_Products_Categories">
+          <End Role="Categories" Type="Northwind.Category" Multiplicity="0..1" />
+          <End Role="Products" Type="Northwind.Product" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Categories">
+              <PropertyRef Name="CategoryID" />
+            </Principal>
+            <Dependent Role="Products">
+              <PropertyRef Name="CategoryID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Orders_Customers">
+          <End Role="Customers" Type="Northwind.Customer" Multiplicity="0..1" />
+          <End Role="Orders" Type="Northwind.Order" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Customers">
+              <PropertyRef Name="CustomerID" />
+            </Principal>
+            <Dependent Role="Orders">
+              <PropertyRef Name="CustomerID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Employees_Employees">
+          <End Role="Employees" Type="Northwind.Employee" Multiplicity="0..1" />
+          <End Role="Employees1" Type="Northwind.Employee" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Employees">
+              <PropertyRef Name="EmployeeID" />
+            </Principal>
+            <Dependent Role="Employees1">
+              <PropertyRef Name="ReportsTo" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Orders_Employees">
+          <End Role="Employees" Type="Northwind.Employee" Multiplicity="0..1" />
+          <End Role="Orders" Type="Northwind.Order" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Employees">
+              <PropertyRef Name="EmployeeID" />
+            </Principal>
+            <Dependent Role="Orders">
+              <PropertyRef Name="EmployeeID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Order_Details_Orders">
+          <End Role="Orders" Type="Northwind.Order" Multiplicity="1" />
+          <End Role="Order_Details" Type="Northwind.Order_Detail" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Orders">
+              <PropertyRef Name="OrderID" />
+            </Principal>
+            <Dependent Role="Order_Details">
+              <PropertyRef Name="OrderID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Order_Details_Products">
+          <End Role="Products" Type="Northwind.Product" Multiplicity="1" />
+          <End Role="Order_Details" Type="Northwind.Order_Detail" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Products">
+              <PropertyRef Name="ProductID" />
+            </Principal>
+            <Dependent Role="Order_Details">
+              <PropertyRef Name="ProductID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Orders_Shippers">
+          <End Role="Shippers" Type="Northwind.Shipper" Multiplicity="0..1" />
+          <End Role="Orders" Type="Northwind.Order" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Shippers">
+              <PropertyRef Name="ShipperID" />
+            </Principal>
+            <Dependent Role="Orders">
+              <PropertyRef Name="ShipVia" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Products_Suppliers">
+          <End Role="Suppliers" Type="Northwind.Supplier" Multiplicity="0..1" />
+          <End Role="Products" Type="Northwind.Product" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Suppliers">
+              <PropertyRef Name="SupplierID" />
+            </Principal>
+            <Dependent Role="Products">
+              <PropertyRef Name="SupplierID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Territories_Region">
+          <End Role="Region" Type="Northwind.Region" Multiplicity="1" />
+          <End Role="Territories" Type="Northwind.Territory" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Region">
+              <PropertyRef Name="RegionID" />
+            </Principal>
+            <Dependent Role="Territories">
+              <PropertyRef Name="RegionID" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="CustomerCustomerDemo">
+          <End Role="CustomerDemographics" Type="Northwind.CustomerDemographic" Multiplicity="*" />
+          <End Role="Customers" Type="Northwind.Customer" Multiplicity="*" />
+        </Association>
+        <Association Name="EmployeeTerritories">
+          <End Role="Employees" Type="Northwind.Employee" Multiplicity="*" />
+          <End Role="Territories" Type="Northwind.Territory" Multiplicity="*" />
+        </Association>
+      </Schema>
+    </edmx:ConceptualModels>
+    <!-- C-S mapping content -->
+    <edmx:Mappings>
+      <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
+        <EntityContainerMapping StorageEntityContainer="NorthwindStoreContainer" CdmEntityContainer="Entities">
+          <EntitySetMapping Name="Categories"><EntityTypeMapping TypeName="Northwind.Category"><MappingFragment StoreEntitySet="Categories">
+            <ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
+            <ScalarProperty Name="CategoryName" ColumnName="CategoryName" />
+            <ScalarProperty Name="Description" ColumnName="Description" />
+            <ScalarProperty Name="Picture" ColumnName="Picture" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="CustomerDemographics"><EntityTypeMapping TypeName="Northwind.CustomerDemographic"><MappingFragment StoreEntitySet="CustomerDemographics">
+            <ScalarProperty Name="CustomerTypeID" ColumnName="CustomerTypeID" />
+            <ScalarProperty Name="CustomerDesc" ColumnName="CustomerDesc" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Customers"><EntityTypeMapping TypeName="Northwind.Customer"><MappingFragment StoreEntitySet="Customers">
+            <ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
+            <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
+            <ScalarProperty Name="ContactName" ColumnName="ContactName" />
+            <ScalarProperty Name="ContactTitle" ColumnName="ContactTitle" />
+            <ScalarProperty Name="Address" ColumnName="Address" />
+            <ScalarProperty Name="City" ColumnName="City" />
+            <ScalarProperty Name="Region" ColumnName="Region" />
+            <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
+            <ScalarProperty Name="Country" ColumnName="Country" />
+            <ScalarProperty Name="Phone" ColumnName="Phone" />
+            <ScalarProperty Name="Fax" ColumnName="Fax" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Employees"><EntityTypeMapping TypeName="Northwind.Employee"><MappingFragment StoreEntitySet="Employees">
+            <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
+            <ScalarProperty Name="LastName" ColumnName="LastName" />
+            <ScalarProperty Name="FirstName" ColumnName="FirstName" />
+            <ScalarProperty Name="Title" ColumnName="Title" />
+            <ScalarProperty Name="TitleOfCourtesy" ColumnName="TitleOfCourtesy" />
+            <ScalarProperty Name="BirthDate" ColumnName="BirthDate" />
+            <ScalarProperty Name="HireDate" ColumnName="HireDate" />
+            <ScalarProperty Name="Address" ColumnName="Address" />
+            <ScalarProperty Name="City" ColumnName="City" />
+            <ScalarProperty Name="Region" ColumnName="Region" />
+            <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
+            <ScalarProperty Name="Country" ColumnName="Country" />
+            <ScalarProperty Name="HomePhone" ColumnName="HomePhone" />
+            <ScalarProperty Name="Extension" ColumnName="Extension" />
+            <ScalarProperty Name="Photo" ColumnName="Photo" />
+            <ScalarProperty Name="Notes" ColumnName="Notes" />
+            <ScalarProperty Name="ReportsTo" ColumnName="ReportsTo" />
+            <ScalarProperty Name="PhotoPath" ColumnName="PhotoPath" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Order_Details"><EntityTypeMapping TypeName="Northwind.Order_Detail"><MappingFragment StoreEntitySet="Order Details">
+            <ScalarProperty Name="OrderID" ColumnName="OrderID" />
+            <ScalarProperty Name="ProductID" ColumnName="ProductID" />
+            <ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
+            <ScalarProperty Name="Quantity" ColumnName="Quantity" />
+            <ScalarProperty Name="Discount" ColumnName="Discount" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Orders"><EntityTypeMapping TypeName="Northwind.Order"><MappingFragment StoreEntitySet="Orders">
+            <ScalarProperty Name="OrderID" ColumnName="OrderID" />
+            <ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
+            <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
+            <ScalarProperty Name="OrderDate" ColumnName="OrderDate" />
+            <ScalarProperty Name="RequiredDate" ColumnName="RequiredDate" />
+            <ScalarProperty Name="ShippedDate" ColumnName="ShippedDate" />
+            <ScalarProperty Name="ShipVia" ColumnName="ShipVia" />
+            <ScalarProperty Name="Freight" ColumnName="Freight" />
+            <ScalarProperty Name="ShipName" ColumnName="ShipName" />
+            <ScalarProperty Name="ShipAddress" ColumnName="ShipAddress" />
+            <ScalarProperty Name="ShipCity" ColumnName="ShipCity" />
+            <ScalarProperty Name="ShipRegion" ColumnName="ShipRegion" />
+            <ScalarProperty Name="ShipPostalCode" ColumnName="ShipPostalCode" />
+            <ScalarProperty Name="ShipCountry" ColumnName="ShipCountry" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Products"><EntityTypeMapping TypeName="Northwind.Product"><MappingFragment StoreEntitySet="Products">
+            <ScalarProperty Name="ProductID" ColumnName="ProductID" />
+            <ScalarProperty Name="ProductName" ColumnName="ProductName" />
+            <ScalarProperty Name="SupplierID" ColumnName="SupplierID" />
+            <ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
+            <ScalarProperty Name="QuantityPerUnit" ColumnName="QuantityPerUnit" />
+            <ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
+            <ScalarProperty Name="UnitsInStock" ColumnName="UnitsInStock" />
+            <ScalarProperty Name="UnitsOnOrder" ColumnName="UnitsOnOrder" />
+            <ScalarProperty Name="ReorderLevel" ColumnName="ReorderLevel" />
+            <ScalarProperty Name="Discontinued" ColumnName="Discontinued" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Regions"><EntityTypeMapping TypeName="Northwind.Region"><MappingFragment StoreEntitySet="Region">
+            <ScalarProperty Name="RegionID" ColumnName="RegionID" />
+            <ScalarProperty Name="RegionDescription" ColumnName="RegionDescription" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Shippers"><EntityTypeMapping TypeName="Northwind.Shipper"><MappingFragment StoreEntitySet="Shippers">
+            <ScalarProperty Name="ShipperID" ColumnName="ShipperID" />
+            <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
+            <ScalarProperty Name="Phone" ColumnName="Phone" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Suppliers"><EntityTypeMapping TypeName="Northwind.Supplier"><MappingFragment StoreEntitySet="Suppliers">
+            <ScalarProperty Name="SupplierID" ColumnName="SupplierID" />
+            <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
+            <ScalarProperty Name="ContactName" ColumnName="ContactName" />
+            <ScalarProperty Name="ContactTitle" ColumnName="ContactTitle" />
+            <ScalarProperty Name="Address" ColumnName="Address" />
+            <ScalarProperty Name="City" ColumnName="City" />
+            <ScalarProperty Name="Region" ColumnName="Region" />
+            <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
+            <ScalarProperty Name="Country" ColumnName="Country" />
+            <ScalarProperty Name="Phone" ColumnName="Phone" />
+            <ScalarProperty Name="Fax" ColumnName="Fax" />
+            <ScalarProperty Name="HomePage" ColumnName="HomePage" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Territories"><EntityTypeMapping TypeName="Northwind.Territory"><MappingFragment StoreEntitySet="Territories">
+            <ScalarProperty Name="TerritoryID" ColumnName="TerritoryID" />
+            <ScalarProperty Name="TerritoryDescription" ColumnName="TerritoryDescription" />
+            <ScalarProperty Name="RegionID" ColumnName="RegionID" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Alphabetical_list_of_products"><EntityTypeMapping TypeName="Northwind.Alphabetical_list_of_product"><MappingFragment StoreEntitySet="Alphabetical list of products">
+            <ScalarProperty Name="ProductID" ColumnName="ProductID" />
+            <ScalarProperty Name="ProductName" ColumnName="ProductName" />
+            <ScalarProperty Name="SupplierID" ColumnName="SupplierID" />
+            <ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
+            <ScalarProperty Name="QuantityPerUnit" ColumnName="QuantityPerUnit" />
+            <ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
+            <ScalarProperty Name="UnitsInStock" ColumnName="UnitsInStock" />
+            <ScalarProperty Name="UnitsOnOrder" ColumnName="UnitsOnOrder" />
+            <ScalarProperty Name="ReorderLevel" ColumnName="ReorderLevel" />
+            <ScalarProperty Name="Discontinued" ColumnName="Discontinued" />
+            <ScalarProperty Name="CategoryName" ColumnName="CategoryName" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Category_Sales_for_1997"><EntityTypeMapping TypeName="Northwind.Category_Sales_for_1997"><MappingFragment StoreEntitySet="Category Sales for 1997">
+            <ScalarProperty Name="CategoryName" ColumnName="CategoryName" />
+            <ScalarProperty Name="CategorySales" ColumnName="CategorySales" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Current_Product_Lists"><EntityTypeMapping TypeName="Northwind.Current_Product_List"><MappingFragment StoreEntitySet="Current Product List">
+            <ScalarProperty Name="ProductID" ColumnName="ProductID" />
+            <ScalarProperty Name="ProductName" ColumnName="ProductName" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Customer_and_Suppliers_by_Cities"><EntityTypeMapping TypeName="Northwind.Customer_and_Suppliers_by_City"><MappingFragment StoreEntitySet="Customer and Suppliers by City">
+            <ScalarProperty Name="City" ColumnName="City" />
+            <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
+            <ScalarProperty Name="ContactName" ColumnName="ContactName" />
+            <ScalarProperty Name="Relationship" ColumnName="Relationship" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Invoices"><EntityTypeMapping TypeName="Northwind.Invoice"><MappingFragment StoreEntitySet="Invoices">
+            <ScalarProperty Name="ShipName" ColumnName="ShipName" />
+            <ScalarProperty Name="ShipAddress" ColumnName="ShipAddress" />
+            <ScalarProperty Name="ShipCity" ColumnName="ShipCity" />
+            <ScalarProperty Name="ShipRegion" ColumnName="ShipRegion" />
+            <ScalarProperty Name="ShipPostalCode" ColumnName="ShipPostalCode" />
+            <ScalarProperty Name="ShipCountry" ColumnName="ShipCountry" />
+            <ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
+            <ScalarProperty Name="CustomerName" ColumnName="CustomerName" />
+            <ScalarProperty Name="Address" ColumnName="Address" />
+            <ScalarProperty Name="City" ColumnName="City" />
+            <ScalarProperty Name="Region" ColumnName="Region" />
+            <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
+            <ScalarProperty Name="Country" ColumnName="Country" />
+            <ScalarProperty Name="Salesperson" ColumnName="Salesperson" />
+            <ScalarProperty Name="OrderID" ColumnName="OrderID" />
+            <ScalarProperty Name="OrderDate" ColumnName="OrderDate" />
+            <ScalarProperty Name="RequiredDate" ColumnName="RequiredDate" />
+            <ScalarProperty Name="ShippedDate" ColumnName="ShippedDate" />
+            <ScalarProperty Name="ShipperName" ColumnName="ShipperName" />
+            <ScalarProperty Name="ProductID" ColumnName="ProductID" />
+            <ScalarProperty Name="ProductName" ColumnName="ProductName" />
+            <ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
+            <ScalarProperty Name="Quantity" ColumnName="Quantity" />
+            <ScalarProperty Name="Discount" ColumnName="Discount" />
+            <ScalarProperty Name="ExtendedPrice" ColumnName="ExtendedPrice" />
+            <ScalarProperty Name="Freight" ColumnName="Freight" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Order_Details_Extendeds"><EntityTypeMapping TypeName="Northwind.Order_Details_Extended"><MappingFragment StoreEntitySet="Order Details Extended">
+            <ScalarProperty Name="OrderID" ColumnName="OrderID" />
+            <ScalarProperty Name="ProductID" ColumnName="ProductID" />
+            <ScalarProperty Name="ProductName" ColumnName="ProductName" />
+            <ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
+            <ScalarProperty Name="Quantity" ColumnName="Quantity" />
+            <ScalarProperty Name="Discount" ColumnName="Discount" />
+            <ScalarProperty Name="ExtendedPrice" ColumnName="ExtendedPrice" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Order_Subtotals"><EntityTypeMapping TypeName="Northwind.Order_Subtotal"><MappingFragment StoreEntitySet="Order Subtotals">
+            <ScalarProperty Name="OrderID" ColumnName="OrderID" />
+            <ScalarProperty Name="Subtotal" ColumnName="Subtotal" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Orders_Qries"><EntityTypeMapping TypeName="Northwind.Orders_Qry"><MappingFragment StoreEntitySet="Orders Qry">
+            <ScalarProperty Name="OrderID" ColumnName="OrderID" />
+            <ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
+            <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
+            <ScalarProperty Name="OrderDate" ColumnName="OrderDate" />
+            <ScalarProperty Name="RequiredDate" ColumnName="RequiredDate" />
+            <ScalarProperty Name="ShippedDate" ColumnName="ShippedDate" />
+            <ScalarProperty Name="ShipVia" ColumnName="ShipVia" />
+            <ScalarProperty Name="Freight" ColumnName="Freight" />
+            <ScalarProperty Name="ShipName" ColumnName="ShipName" />
+            <ScalarProperty Name="ShipAddress" ColumnName="ShipAddress" />
+            <ScalarProperty Name="ShipCity" ColumnName="ShipCity" />
+            <ScalarProperty Name="ShipRegion" ColumnName="ShipRegion" />
+            <ScalarProperty Name="ShipPostalCode" ColumnName="ShipPostalCode" />
+            <ScalarProperty Name="ShipCountry" ColumnName="ShipCountry" />
+            <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
+            <ScalarProperty Name="Address" ColumnName="Address" />
+            <ScalarProperty Name="City" ColumnName="City" />
+            <ScalarProperty Name="Region" ColumnName="Region" />
+            <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
+            <ScalarProperty Name="Country" ColumnName="Country" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Product_Sales_for_1997"><EntityTypeMapping TypeName="Northwind.Product_Sales_for_1997"><MappingFragment StoreEntitySet="Product Sales for 1997">
+            <ScalarProperty Name="CategoryName" ColumnName="CategoryName" />
+            <ScalarProperty Name="ProductName" ColumnName="ProductName" />
+            <ScalarProperty Name="ProductSales" ColumnName="ProductSales" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Products_Above_Average_Prices"><EntityTypeMapping TypeName="Northwind.Products_Above_Average_Price"><MappingFragment StoreEntitySet="Products Above Average Price">
+            <ScalarProperty Name="ProductName" ColumnName="ProductName" />
+            <ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Products_by_Categories"><EntityTypeMapping TypeName="Northwind.Products_by_Category"><MappingFragment StoreEntitySet="Products by Category">
+            <ScalarProperty Name="CategoryName" ColumnName="CategoryName" />
+            <ScalarProperty Name="ProductName" ColumnName="ProductName" />
+            <ScalarProperty Name="QuantityPerUnit" ColumnName="QuantityPerUnit" />
+            <ScalarProperty Name="UnitsInStock" ColumnName="UnitsInStock" />
+            <ScalarProperty Name="Discontinued" ColumnName="Discontinued" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Sales_by_Categories"><EntityTypeMapping TypeName="Northwind.Sales_by_Category"><MappingFragment StoreEntitySet="Sales by Category">
+            <ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
+            <ScalarProperty Name="CategoryName" ColumnName="CategoryName" />
+            <ScalarProperty Name="ProductName" ColumnName="ProductName" />
+            <ScalarProperty Name="ProductSales" ColumnName="ProductSales" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Sales_Totals_by_Amounts"><EntityTypeMapping TypeName="Northwind.Sales_Totals_by_Amount"><MappingFragment StoreEntitySet="Sales Totals by Amount">
+            <ScalarProperty Name="SaleAmount" ColumnName="SaleAmount" />
+            <ScalarProperty Name="OrderID" ColumnName="OrderID" />
+            <ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
+            <ScalarProperty Name="ShippedDate" ColumnName="ShippedDate" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Summary_of_Sales_by_Quarters"><EntityTypeMapping TypeName="Northwind.Summary_of_Sales_by_Quarter"><MappingFragment StoreEntitySet="Summary of Sales by Quarter">
+            <ScalarProperty Name="ShippedDate" ColumnName="ShippedDate" />
+            <ScalarProperty Name="OrderID" ColumnName="OrderID" />
+            <ScalarProperty Name="Subtotal" ColumnName="Subtotal" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <EntitySetMapping Name="Summary_of_Sales_by_Years"><EntityTypeMapping TypeName="Northwind.Summary_of_Sales_by_Year"><MappingFragment StoreEntitySet="Summary of Sales by Year">
+            <ScalarProperty Name="ShippedDate" ColumnName="ShippedDate" />
+            <ScalarProperty Name="OrderID" ColumnName="OrderID" />
+            <ScalarProperty Name="Subtotal" ColumnName="Subtotal" />
+          </MappingFragment></EntityTypeMapping></EntitySetMapping>
+          <AssociationSetMapping Name="CustomerCustomerDemo" TypeName="Northwind.CustomerCustomerDemo" StoreEntitySet="CustomerCustomerDemo">
+            <EndProperty Name="CustomerDemographics">
+              <ScalarProperty Name="CustomerTypeID" ColumnName="CustomerTypeID" />
+            </EndProperty>
+            <EndProperty Name="Customers">
+              <ScalarProperty Name="CustomerID" ColumnName="CustomerID" />
+            </EndProperty>
+          </AssociationSetMapping>
+          <AssociationSetMapping Name="EmployeeTerritories" TypeName="Northwind.EmployeeTerritories" StoreEntitySet="EmployeeTerritories">
+            <EndProperty Name="Employees">
+              <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" />
+            </EndProperty>
+            <EndProperty Name="Territories">
+              <ScalarProperty Name="TerritoryID" ColumnName="TerritoryID" />
+            </EndProperty>
+          </AssociationSetMapping>
+        </EntityContainerMapping>
+      </Mapping>
+    </edmx:Mappings>
+  </edmx:Runtime>
+  <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
+  <Designer xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
+    <Connection>
+      <DesignerInfoPropertySet>
+        <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
+      </DesignerInfoPropertySet>
+    </Connection>
+    <Options>
+      <DesignerInfoPropertySet>
+        <DesignerProperty Name="ValidateOnBuild" Value="true" />
+        <DesignerProperty Name="EnablePluralization" Value="False" />
+        <DesignerProperty Name="IncludeForeignKeysInModel" Value="True" />
+      </DesignerInfoPropertySet>
+    </Options>
+    <!-- Diagram content (shape and connector positions) -->
+    <Diagrams>
+      <Diagram Name="Northwind">
+        <EntityTypeShape EntityType="Northwind.Category" Width="1.5" PointX="3" PointY="19.5" Height="1.9802864583333317" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.CustomerDemographic" Width="1.5" PointX="0.75" PointY="2.5" Height="1.5956835937499996" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Customer" Width="1.5" PointX="3" PointY="1.5" Height="3.5186979166666656" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Employee" Width="1.5" PointX="3" PointY="9.25" Height="5.2494108072916674" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Order_Detail" Width="1.5" PointX="7.5" PointY="2.125" Height="2.3648893229166656" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Order" Width="1.5" PointX="5.25" PointY="1" Height="4.4802050781250031" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Product" Width="1.5" PointX="5.25" PointY="20.875" Height="3.5186979166666674" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Region" Width="1.5" PointX="5.75" PointY="7.125" Height="1.5956835937499996" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Shipper" Width="1.5" PointX="3" PointY="15.25" Height="1.7879850260416674" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Supplier" Width="1.5" PointX="3" PointY="22.25" Height="3.5186979166666674" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Territory" Width="1.5" PointX="8" PointY="9.875" Height="1.9802864583333353" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Alphabetical_list_of_product" Width="1.5" PointX="7.75" PointY="5.75" Height="3.1340950520833317" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Category_Sales_for_1997" Width="1.5" PointX="0.75" PointY="6.75" Height="1.4033821614583388" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Current_Product_List" Width="1.5" PointX="2.75" PointY="6.75" Height="1.4033821614583388" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Customer_and_Suppliers_by_City" Width="1.5" PointX="9.75" PointY="0.75" Height="1.7879850260416674" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Invoice" Width="1.5" PointX="10.75" PointY="3.75" Height="6.0186165364583388" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Order_Details_Extended" Width="1.5" PointX="10.75" PointY="10.75" Height="2.3648893229166674" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Order_Subtotal" Width="1.5" PointX="11.75" PointY="0.75" Height="1.4033821614583388" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Orders_Qry" Width="1.5" PointX="12.75" PointY="3.75" Height="4.8648079427083388" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Product_Sales_for_1997" Width="1.5" PointX="5.75" PointY="12.75" Height="1.5956835937500031" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Products_Above_Average_Price" Width="1.5" PointX="7.75" PointY="12.75" Height="1.4033821614583388" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Products_by_Category" Width="1.5" PointX="12.75" PointY="9.75" Height="1.9802864583333282" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Sales_by_Category" Width="1.5" PointX="12.75" PointY="12.75" Height="1.7879850260416674" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Sales_Totals_by_Amount" Width="1.5" PointX="13.75" PointY="0.75" Height="1.7879850260416674" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Summary_of_Sales_by_Quarter" Width="1.5" PointX="14.75" PointY="3.75" Height="1.5956835937500102" IsExpanded="true" />
+        <EntityTypeShape EntityType="Northwind.Summary_of_Sales_by_Year" Width="1.5" PointX="14.75" PointY="6.75" Height="1.5956835937500102" IsExpanded="true" />
+        <AssociationConnector Association="Northwind.FK_Products_Categories" ManuallyRouted="false">
+          <ConnectorPoint PointX="4.5" PointY="21.177643229166666" />
+          <ConnectorPoint PointX="5.25" PointY="21.177643229166666" />
+        </AssociationConnector>
+        <AssociationConnector Association="Northwind.FK_Orders_Customers" ManuallyRouted="false">
+          <ConnectorPoint PointX="4.5" PointY="3.2593489583333328" />
+          <ConnectorPoint PointX="5.25" PointY="3.2593489583333328" />
+        </AssociationConnector>
+        <AssociationConnector Association="Northwind.FK_Employees_Employees" ManuallyRouted="false">
+          <ConnectorPoint PointX="3.5319230769230767" PointY="14.499410807291667" />
+          <ConnectorPoint PointX="3.5319230769230767" PointY="14.749410807291667" />
+          <ConnectorPoint PointX="3.9784615384615383" PointY="14.749410807291667" />
+          <ConnectorPoint PointX="3.9784615384615383" PointY="14.499410807291667" />
+        </AssociationConnector>
+        <AssociationConnector Association="Northwind.FK_Orders_Employees" ManuallyRouted="false">
+          <ConnectorPoint PointX="4.5" PointY="10.96875" />
+          <ConnectorPoint PointX="5.2447891666666671" PointY="10.96875" />
+          <ConnectorPoint PointX="5.4114558333333331" PointY="10.96875" />
+          <ConnectorPoint PointX="5.46875" PointY="10.96875" />
+          <ConnectorPoint PointX="5.46875" PointY="5.4802050781250031" />
+        </AssociationConnector>
+        <AssociationConnector Association="Northwind.FK_Order_Details_Orders" ManuallyRouted="false">
+          <ConnectorPoint PointX="6.75" PointY="3.3074446614583328" />
+          <ConnectorPoint PointX="7.5" PointY="3.3074446614583328" />
+        </AssociationConnector>
+        <AssociationConnector Association="Northwind.FK_Order_Details_Products" ManuallyRouted="false">
+          <ConnectorPoint PointX="6.75" PointY="22.634348958333334" />
+          <ConnectorPoint PointX="7.59375" PointY="22.634348958333334" />
+          <ConnectorPoint PointX="7.59375" PointY="4.4898893229166656" />
+        </AssociationConnector>
+        <AssociationConnector Association="Northwind.FK_Orders_Shippers" ManuallyRouted="false">
+          <ConnectorPoint PointX="4.5" PointY="16.143992513020834" />
+          <ConnectorPoint PointX="5.3281225" PointY="16.143992513020834" />
+          <ConnectorPoint PointX="5.3281225" PointY="5.4802050781250031" />
+        </AssociationConnector>
+        <AssociationConnector Association="Northwind.FK_Products_Suppliers" ManuallyRouted="false">
+          <ConnectorPoint PointX="4.5" PointY="23.321848958333334" />
+          <ConnectorPoint PointX="5.25" PointY="23.321848958333334" />
+        </AssociationConnector>
+        <AssociationConnector Association="Northwind.FK_Territories_Region" ManuallyRouted="false">
+          <ConnectorPoint PointX="6.5" PointY="8.72068359375" />
+          <ConnectorPoint PointX="6.5" PointY="10.865143229166668" />
+          <ConnectorPoint PointX="7.510416666666667" PointY="10.865143229166668" />
+          <ConnectorPoint PointX="7.677083333333333" PointY="10.865143229166668" />
+          <ConnectorPoint PointX="8" PointY="10.865143229166668" />
+        </AssociationConnector>
+        <AssociationConnector Association="Northwind.CustomerCustomerDemo" ManuallyRouted="false">
+          <ConnectorPoint PointX="2.25" PointY="3.297841796875" />
+          <ConnectorPoint PointX="3" PointY="3.297841796875" />
+        </AssociationConnector>
+        <AssociationConnector Association="Northwind.EmployeeTerritories" ManuallyRouted="false">
+          <ConnectorPoint PointX="4.5" PointY="10.307571614583335" />
+          <ConnectorPoint PointX="5.2447891666666671" PointY="10.307571614583333" />
+          <ConnectorPoint PointX="5.5520833333333321" PointY="10.307571614583335" />
+          <ConnectorPoint PointX="6.416666666666667" PointY="10.307571614583335" />
+          <ConnectorPoint PointX="6.583333333333333" PointY="10.307571614583335" />
+          <ConnectorPoint PointX="7.510416666666667" PointY="10.307571614583335" />
+          <ConnectorPoint PointX="7.677083333333333" PointY="10.307571614583335" />
+          <ConnectorPoint PointX="8" PointY="10.307571614583335" />
+        </AssociationConnector>
+      </Diagram>
+    </Diagrams>
+  </Designer>
+</edmx:Edmx>
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Properties/AssemblyInfo.cs b/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4dcbb83
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/Entities.Northwind/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Entities.Northwind")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Entities.Northwind")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
+[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("a8864b44-233b-4e3d-9f6e-f8be8407a79e")]
+
+// 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/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/LinqToSql.Northwind.csproj b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/LinqToSql.Northwind.csproj
new file mode 100644
index 0000000..86e31be
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/LinqToSql.Northwind.csproj
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{641552DA-03CE-4441-8298-253AFB40C74E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>LinqToSql.Northwind</RootNamespace>
+    <AssemblyName>LinqToSql.Northwind</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data.Linq" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Northwind.designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Northwind.dbml</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+      <DependentUpon>Settings.settings</DependentUpon>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="Northwind.dbml">
+      <Generator>MSLinqToSQLGenerator</Generator>
+      <LastGenOutput>Northwind.designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </None>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Northwind.dbml.layout">
+      <DependentUpon>Northwind.dbml</DependentUpon>
+    </None>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Northwind.dbml b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Northwind.dbml
new file mode 100644
index 0000000..0227968
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Northwind.dbml
@@ -0,0 +1,412 @@
+<?xml version="1.0" encoding="utf-8"?><Database Name="NORTHWND" Class="NorthwindDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
+  <Connection Mode="AppSettings" ConnectionString="Data Source=.\SQLEXPRESS;AttachDbFilename="C:\Tomas\Projects\Documents\Templates\Web\WebApplication (MVC 3)\WebApplication\App_Data\NORTHWND.MDF";Integrated Security=True;User Instance=True" SettingsObjectName="LinqToSql.Northwind.Properties.Settings" SettingsPropertyName="NORTHWNDConnectionString" Provider="System.Data.SqlClient" />
+  <Table Name="dbo.Categories" Member="Categories">
+    <Type Name="Category">
+      <Column Name="CategoryID" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+      <Column Name="CategoryName" Type="System.String" DbType="NVarChar(15) NOT NULL" CanBeNull="false" />
+      <Column Name="Description" Type="System.String" DbType="NText" CanBeNull="true" UpdateCheck="Never" />
+      <Column Name="Picture" Type="System.Data.Linq.Binary" DbType="Image" CanBeNull="true" UpdateCheck="Never" />
+      <Association Name="Category_Product" Member="Products" ThisKey="CategoryID" OtherKey="CategoryID" Type="Product" />
+    </Type>
+  </Table>
+  <Table Name="dbo.Territories" Member="Territories">
+    <Type Name="Territory">
+      <Column Name="TerritoryID" Type="System.String" DbType="NVarChar(20) NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="TerritoryDescription" Type="System.String" DbType="NChar(50) NOT NULL" CanBeNull="false" />
+      <Column Name="RegionID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Association Name="Territory_EmployeeTerritory" Member="EmployeeTerritories" ThisKey="TerritoryID" OtherKey="TerritoryID" Type="EmployeeTerritory" />
+      <Association Name="Region_Territory" Member="Region" ThisKey="RegionID" OtherKey="RegionID" Type="Region" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.CustomerCustomerDemo" Member="CustomerCustomerDemos">
+    <Type Name="CustomerCustomerDemo">
+      <Column Name="CustomerID" Type="System.String" DbType="NChar(5) NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="CustomerTypeID" Type="System.String" DbType="NChar(10) NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Association Name="CustomerDemographic_CustomerCustomerDemo" Member="CustomerDemographic" ThisKey="CustomerTypeID" OtherKey="CustomerTypeID" Type="CustomerDemographic" IsForeignKey="true" />
+      <Association Name="Customer_CustomerCustomerDemo" Member="Customer" ThisKey="CustomerID" OtherKey="CustomerID" Type="Customer" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.CustomerDemographics" Member="CustomerDemographics">
+    <Type Name="CustomerDemographic">
+      <Column Name="CustomerTypeID" Type="System.String" DbType="NChar(10) NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="CustomerDesc" Type="System.String" DbType="NText" CanBeNull="true" UpdateCheck="Never" />
+      <Association Name="CustomerDemographic_CustomerCustomerDemo" Member="CustomerCustomerDemos" ThisKey="CustomerTypeID" OtherKey="CustomerTypeID" Type="CustomerCustomerDemo" />
+    </Type>
+  </Table>
+  <Table Name="dbo.Customers" Member="Customers">
+    <Type Name="Customer">
+      <Column Name="CustomerID" Type="System.String" DbType="NChar(5) NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="CompanyName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="ContactName" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
+      <Column Name="ContactTitle" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
+      <Column Name="Address" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
+      <Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="Region" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="PostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
+      <Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="Phone" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
+      <Column Name="Fax" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
+      <Association Name="Customer_CustomerCustomerDemo" Member="CustomerCustomerDemos" ThisKey="CustomerID" OtherKey="CustomerID" Type="CustomerCustomerDemo" />
+      <Association Name="Customer_Order" Member="Orders" ThisKey="CustomerID" OtherKey="CustomerID" Type="Order" />
+    </Type>
+  </Table>
+  <Table Name="dbo.Employees" Member="Employees">
+    <Type Name="Employee">
+      <Column Name="EmployeeID" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+      <Column Name="LastName" Type="System.String" DbType="NVarChar(20) NOT NULL" CanBeNull="false" />
+      <Column Name="FirstName" Type="System.String" DbType="NVarChar(10) NOT NULL" CanBeNull="false" />
+      <Column Name="Title" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
+      <Column Name="TitleOfCourtesy" Type="System.String" DbType="NVarChar(25)" CanBeNull="true" />
+      <Column Name="BirthDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="HireDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="Address" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
+      <Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="Region" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="PostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
+      <Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="HomePhone" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
+      <Column Name="Extension" Type="System.String" DbType="NVarChar(4)" CanBeNull="true" />
+      <Column Name="Photo" Type="System.Data.Linq.Binary" DbType="Image" CanBeNull="true" UpdateCheck="Never" />
+      <Column Name="Notes" Type="System.String" DbType="NText" CanBeNull="true" UpdateCheck="Never" />
+      <Column Name="ReportsTo" Type="System.Int32" DbType="Int" CanBeNull="true" />
+      <Column Name="PhotoPath" Type="System.String" DbType="NVarChar(255)" CanBeNull="true" />
+      <Association Name="Employee_Employee" Member="Employees" ThisKey="EmployeeID" OtherKey="ReportsTo" Type="Employee" />
+      <Association Name="Employee_EmployeeTerritory" Member="EmployeeTerritories" ThisKey="EmployeeID" OtherKey="EmployeeID" Type="EmployeeTerritory" />
+      <Association Name="Employee_Order" Member="Orders" ThisKey="EmployeeID" OtherKey="EmployeeID" Type="Order" />
+      <Association Name="Employee_Employee" Member="Employee1" ThisKey="ReportsTo" OtherKey="EmployeeID" Type="Employee" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.EmployeeTerritories" Member="EmployeeTerritories">
+    <Type Name="EmployeeTerritory">
+      <Column Name="EmployeeID" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="TerritoryID" Type="System.String" DbType="NVarChar(20) NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Association Name="Employee_EmployeeTerritory" Member="Employee" ThisKey="EmployeeID" OtherKey="EmployeeID" Type="Employee" IsForeignKey="true" />
+      <Association Name="Territory_EmployeeTerritory" Member="Territory" ThisKey="TerritoryID" OtherKey="TerritoryID" Type="Territory" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Order Details]" Member="Order_Details">
+    <Type Name="Order_Detail">
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="ProductID" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="UnitPrice" Type="System.Decimal" DbType="Money NOT NULL" CanBeNull="false" />
+      <Column Name="Quantity" Type="System.Int16" DbType="SmallInt NOT NULL" CanBeNull="false" />
+      <Column Name="Discount" Type="System.Single" DbType="Real NOT NULL" CanBeNull="false" />
+      <Association Name="Order_Order_Detail" Member="Order" ThisKey="OrderID" OtherKey="OrderID" Type="Order" IsForeignKey="true" />
+      <Association Name="Product_Order_Detail" Member="Product" ThisKey="ProductID" OtherKey="ProductID" Type="Product" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.Orders" Member="Orders">
+    <Type Name="Order">
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+      <Column Name="CustomerID" Type="System.String" DbType="NChar(5)" CanBeNull="true" />
+      <Column Name="EmployeeID" Type="System.Int32" DbType="Int" CanBeNull="true" />
+      <Column Name="OrderDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="RequiredDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="ShipVia" Type="System.Int32" DbType="Int" CanBeNull="true" />
+      <Column Name="Freight" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+      <Column Name="ShipName" Type="System.String" DbType="NVarChar(40)" CanBeNull="true" />
+      <Column Name="ShipAddress" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
+      <Column Name="ShipCity" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="ShipRegion" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="ShipPostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
+      <Column Name="ShipCountry" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Association Name="Order_Order_Detail" Member="Order_Details" ThisKey="OrderID" OtherKey="OrderID" Type="Order_Detail" />
+      <Association Name="Customer_Order" Member="Customer" ThisKey="CustomerID" OtherKey="CustomerID" Type="Customer" IsForeignKey="true" />
+      <Association Name="Employee_Order" Member="Employee" ThisKey="EmployeeID" OtherKey="EmployeeID" Type="Employee" IsForeignKey="true" />
+      <Association Name="Shipper_Order" Member="Shipper" ThisKey="ShipVia" OtherKey="ShipperID" Type="Shipper" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.Products" Member="Products">
+    <Type Name="Product">
+      <Column Name="ProductID" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="SupplierID" Type="System.Int32" DbType="Int" CanBeNull="true" />
+      <Column Name="CategoryID" Type="System.Int32" DbType="Int" CanBeNull="true" />
+      <Column Name="QuantityPerUnit" Type="System.String" DbType="NVarChar(20)" CanBeNull="true" />
+      <Column Name="UnitPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+      <Column Name="UnitsInStock" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
+      <Column Name="UnitsOnOrder" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
+      <Column Name="ReorderLevel" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
+      <Column Name="Discontinued" Type="System.Boolean" DbType="Bit NOT NULL" CanBeNull="false" />
+      <Association Name="Product_Order_Detail" Member="Order_Details" ThisKey="ProductID" OtherKey="ProductID" Type="Order_Detail" />
+      <Association Name="Category_Product" Member="Category" ThisKey="CategoryID" OtherKey="CategoryID" Type="Category" IsForeignKey="true" />
+      <Association Name="Supplier_Product" Member="Supplier" ThisKey="SupplierID" OtherKey="SupplierID" Type="Supplier" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.Region" Member="Regions">
+    <Type Name="Region">
+      <Column Name="RegionID" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="RegionDescription" Type="System.String" DbType="NChar(50) NOT NULL" CanBeNull="false" />
+      <Association Name="Region_Territory" Member="Territories" ThisKey="RegionID" OtherKey="RegionID" Type="Territory" />
+    </Type>
+  </Table>
+  <Table Name="dbo.Shippers" Member="Shippers">
+    <Type Name="Shipper">
+      <Column Name="ShipperID" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+      <Column Name="CompanyName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="Phone" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
+      <Association Name="Shipper_Order" Member="Orders" ThisKey="ShipperID" OtherKey="ShipVia" Type="Order" />
+    </Type>
+  </Table>
+  <Table Name="dbo.Suppliers" Member="Suppliers">
+    <Type Name="Supplier">
+      <Column Name="SupplierID" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+      <Column Name="CompanyName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="ContactName" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
+      <Column Name="ContactTitle" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
+      <Column Name="Address" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
+      <Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="Region" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="PostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
+      <Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="Phone" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
+      <Column Name="Fax" Type="System.String" DbType="NVarChar(24)" CanBeNull="true" />
+      <Column Name="HomePage" Type="System.String" DbType="NText" CanBeNull="true" UpdateCheck="Never" />
+      <Association Name="Supplier_Product" Member="Products" ThisKey="SupplierID" OtherKey="SupplierID" Type="Product" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Alphabetical list of products]" Member="Alphabetical_list_of_products">
+    <Type Name="Alphabetical_list_of_product">
+      <Column Name="ProductID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="SupplierID" Type="System.Int32" DbType="Int" CanBeNull="true" />
+      <Column Name="CategoryID" Type="System.Int32" DbType="Int" CanBeNull="true" />
+      <Column Name="QuantityPerUnit" Type="System.String" DbType="NVarChar(20)" CanBeNull="true" />
+      <Column Name="UnitPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+      <Column Name="UnitsInStock" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
+      <Column Name="UnitsOnOrder" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
+      <Column Name="ReorderLevel" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
+      <Column Name="Discontinued" Type="System.Boolean" DbType="Bit NOT NULL" CanBeNull="false" />
+      <Column Name="CategoryName" Type="System.String" DbType="NVarChar(15) NOT NULL" CanBeNull="false" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Summary of Sales by Year]" Member="Summary_of_Sales_by_Years">
+    <Type Name="Summary_of_Sales_by_Year">
+      <Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="Subtotal" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Category Sales for 1997]" Member="Category_Sales_for_1997s">
+    <Type Name="Category_Sales_for_1997">
+      <Column Name="CategoryName" Type="System.String" DbType="NVarChar(15) NOT NULL" CanBeNull="false" />
+      <Column Name="CategorySales" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Current Product List]" Member="Current_Product_Lists">
+    <Type Name="Current_Product_List">
+      <Column Name="ProductID" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsDbGenerated="true" CanBeNull="false" />
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Customer and Suppliers by City]" Member="Customer_and_Suppliers_by_Cities">
+    <Type Name="Customer_and_Suppliers_by_City">
+      <Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="CompanyName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="ContactName" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
+      <Column Name="Relationship" Type="System.String" DbType="VarChar(9) NOT NULL" CanBeNull="false" />
+    </Type>
+  </Table>
+  <Table Name="dbo.Invoices" Member="Invoices">
+    <Type Name="Invoice">
+      <Column Name="ShipName" Type="System.String" DbType="NVarChar(40)" CanBeNull="true" />
+      <Column Name="ShipAddress" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
+      <Column Name="ShipCity" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="ShipRegion" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="ShipPostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
+      <Column Name="ShipCountry" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="CustomerID" Type="System.String" DbType="NChar(5)" CanBeNull="true" />
+      <Column Name="CustomerName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="Address" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
+      <Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="Region" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="PostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
+      <Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="Salesperson" Type="System.String" DbType="NVarChar(31) NOT NULL" CanBeNull="false" />
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="OrderDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="RequiredDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="ShipperName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="ProductID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="UnitPrice" Type="System.Decimal" DbType="Money NOT NULL" CanBeNull="false" />
+      <Column Name="Quantity" Type="System.Int16" DbType="SmallInt NOT NULL" CanBeNull="false" />
+      <Column Name="Discount" Type="System.Single" DbType="Real NOT NULL" CanBeNull="false" />
+      <Column Name="ExtendedPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+      <Column Name="Freight" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Order Details Extended]" Member="Order_Details_Extendeds">
+    <Type Name="Order_Details_Extended">
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="ProductID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="UnitPrice" Type="System.Decimal" DbType="Money NOT NULL" CanBeNull="false" />
+      <Column Name="Quantity" Type="System.Int16" DbType="SmallInt NOT NULL" CanBeNull="false" />
+      <Column Name="Discount" Type="System.Single" DbType="Real NOT NULL" CanBeNull="false" />
+      <Column Name="ExtendedPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Order Subtotals]" Member="Order_Subtotals">
+    <Type Name="Order_Subtotal">
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="Subtotal" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Orders Qry]" Member="Orders_Qries">
+    <Type Name="Orders_Qry">
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="CustomerID" Type="System.String" DbType="NChar(5)" CanBeNull="true" />
+      <Column Name="EmployeeID" Type="System.Int32" DbType="Int" CanBeNull="true" />
+      <Column Name="OrderDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="RequiredDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="ShipVia" Type="System.Int32" DbType="Int" CanBeNull="true" />
+      <Column Name="Freight" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+      <Column Name="ShipName" Type="System.String" DbType="NVarChar(40)" CanBeNull="true" />
+      <Column Name="ShipAddress" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
+      <Column Name="ShipCity" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="ShipRegion" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="ShipPostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
+      <Column Name="ShipCountry" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="CompanyName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="Address" Type="System.String" DbType="NVarChar(60)" CanBeNull="true" />
+      <Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="Region" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="PostalCode" Type="System.String" DbType="NVarChar(10)" CanBeNull="true" />
+      <Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Product Sales for 1997]" Member="Product_Sales_for_1997s">
+    <Type Name="Product_Sales_for_1997">
+      <Column Name="CategoryName" Type="System.String" DbType="NVarChar(15) NOT NULL" CanBeNull="false" />
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="ProductSales" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Products Above Average Price]" Member="Products_Above_Average_Prices">
+    <Type Name="Products_Above_Average_Price">
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="UnitPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Products by Category]" Member="Products_by_Categories">
+    <Type Name="Products_by_Category">
+      <Column Name="CategoryName" Type="System.String" DbType="NVarChar(15) NOT NULL" CanBeNull="false" />
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="QuantityPerUnit" Type="System.String" DbType="NVarChar(20)" CanBeNull="true" />
+      <Column Name="UnitsInStock" Type="System.Int16" DbType="SmallInt" CanBeNull="true" />
+      <Column Name="Discontinued" Type="System.Boolean" DbType="Bit NOT NULL" CanBeNull="false" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Quarterly Orders]" Member="Quarterly_Orders">
+    <Type Name="Quarterly_Order">
+      <Column Name="CustomerID" Type="System.String" DbType="NChar(5)" CanBeNull="true" />
+      <Column Name="CompanyName" Type="System.String" DbType="NVarChar(40)" CanBeNull="true" />
+      <Column Name="City" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Sales by Category]" Member="Sales_by_Categories">
+    <Type Name="Sales_by_Category">
+      <Column Name="CategoryID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="CategoryName" Type="System.String" DbType="NVarChar(15) NOT NULL" CanBeNull="false" />
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="ProductSales" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Sales Totals by Amount]" Member="Sales_Totals_by_Amounts">
+    <Type Name="Sales_Totals_by_Amount">
+      <Column Name="SaleAmount" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="CompanyName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Table Name="dbo.[Summary of Sales by Quarter]" Member="Summary_of_Sales_by_Quarters">
+    <Type Name="Summary_of_Sales_by_Quarter">
+      <Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="Subtotal" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </Type>
+  </Table>
+  <Function Name="dbo.CustOrderHist" Method="CustOrderHist">
+    <Parameter Name="CustomerID" Parameter="customerID" Type="System.String" DbType="NChar(5)" />
+    <ElementType Name="CustOrderHistResult">
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="Total" Type="System.Int32" DbType="Int" CanBeNull="true" />
+    </ElementType>
+  </Function>
+  <Function Name="dbo.[Ten Most Expensive Products]" Method="Ten_Most_Expensive_Products">
+    <ElementType Name="Ten_Most_Expensive_ProductsResult">
+      <Column Name="TenMostExpensiveProducts" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="UnitPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </ElementType>
+  </Function>
+  <Function Name="dbo.CustOrdersDetail" Method="CustOrdersDetail">
+    <Parameter Name="OrderID" Parameter="orderID" Type="System.Int32" DbType="Int" />
+    <ElementType Name="CustOrdersDetailResult">
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="UnitPrice" Type="System.Decimal" DbType="Money NOT NULL" CanBeNull="false" />
+      <Column Name="Quantity" Type="System.Int16" DbType="SmallInt NOT NULL" CanBeNull="false" />
+      <Column Name="Discount" Type="System.Int32" DbType="Int" CanBeNull="true" />
+      <Column Name="ExtendedPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </ElementType>
+  </Function>
+  <Function Name="dbo.CustOrdersOrders" Method="CustOrdersOrders">
+    <Parameter Name="CustomerID" Parameter="customerID" Type="System.String" DbType="NChar(5)" />
+    <ElementType Name="CustOrdersOrdersResult">
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="OrderDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="RequiredDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+    </ElementType>
+  </Function>
+  <Function Name="dbo.DeleteProduct" Method="DeleteProduct">
+    <Parameter Name="id" Type="System.Int32" DbType="Int" />
+    <Return Type="System.Int32" />
+  </Function>
+  <Function Name="dbo.[Employee Sales by Country]" Method="Employee_Sales_by_Country">
+    <Parameter Name="Beginning_Date" Parameter="beginning_Date" Type="System.DateTime" DbType="DateTime" />
+    <Parameter Name="Ending_Date" Parameter="ending_Date" Type="System.DateTime" DbType="DateTime" />
+    <ElementType Name="Employee_Sales_by_CountryResult">
+      <Column Name="Country" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
+      <Column Name="LastName" Type="System.String" DbType="NVarChar(20) NOT NULL" CanBeNull="false" />
+      <Column Name="FirstName" Type="System.String" DbType="NVarChar(10) NOT NULL" CanBeNull="false" />
+      <Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="SaleAmount" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+    </ElementType>
+  </Function>
+  <Function Name="dbo.ChangeProductPrice" Method="ChangeProductPrice">
+    <Parameter Name="prod" Type="System.Int32" DbType="Int" />
+    <Parameter Name="price" Type="System.Decimal" DbType="Money" />
+    <Return Type="System.Int32" />
+  </Function>
+  <Function Name="dbo.InsertProduct" Method="InsertProduct">
+    <Parameter Name="name" Type="System.String" DbType="NVarChar(40)" />
+    <Parameter Name="price" Type="System.Decimal" DbType="Money" />
+    <Parameter Name="id" Type="System.Int32" DbType="Int" Direction="InOut" />
+    <Return Type="System.Int32" />
+  </Function>
+  <Function Name="dbo.[Sales by Year]" Method="Sales_by_Year">
+    <Parameter Name="Beginning_Date" Parameter="beginning_Date" Type="System.DateTime" DbType="DateTime" />
+    <Parameter Name="Ending_Date" Parameter="ending_Date" Type="System.DateTime" DbType="DateTime" />
+    <ElementType Name="Sales_by_YearResult">
+      <Column Name="ShippedDate" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+      <Column Name="OrderID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+      <Column Name="Subtotal" Type="System.Decimal" DbType="Money" CanBeNull="true" />
+      <Column Name="Year" Type="System.String" DbType="NVarChar(30)" CanBeNull="true" />
+    </ElementType>
+  </Function>
+  <Function Name="dbo.SalesByCategory" Method="SalesByCategory">
+    <Parameter Name="CategoryName" Parameter="categoryName" Type="System.String" DbType="NVarChar(15)" />
+    <Parameter Name="OrdYear" Parameter="ordYear" Type="System.String" DbType="NVarChar(4)" />
+    <ElementType Name="SalesByCategoryResult">
+      <Column Name="ProductName" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
+      <Column Name="TotalPurchase" Type="System.Decimal" DbType="Decimal(38,2)" CanBeNull="true" />
+    </ElementType>
+  </Function>
+</Database>
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Northwind.dbml.layout b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Northwind.dbml.layout
new file mode 100644
index 0000000..726f6fd
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Northwind.dbml.layout
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ordesignerObjectsDiagram dslVersion="1.0.0.0" absoluteBounds="0, 0, 18, 20.375" name="Northwind">
+  <DataContextMoniker Name="/NorthwindDataContext" />
+  <nestedChildShapes>
+    <classShape Id="3b9375c8-34f2-4c3c-bcca-59016253cf92" absoluteBounds="3.75, 14.625, 2, 1.5785953776041684">
+      <DataClassMoniker Name="/NorthwindDataContext/Category" />
+      <nestedChildShapes>
+        <elementListCompartment Id="ece6fcc6-6b8b-4a43-97c7-a48c4c5a9a2e" absoluteBounds="3.765, 15.085, 1.9700000000000002, 1.0185953776041665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="2bb5887c-da73-4bb1-a2a3-b311af0e0de7" absoluteBounds="9.5, 7.375, 2, 1.3862939453124987">
+      <DataClassMoniker Name="/NorthwindDataContext/Territory" />
+      <nestedChildShapes>
+        <elementListCompartment Id="c3eb16e4-9ed6-4872-bdff-bc2144d73d8b" absoluteBounds="9.515, 7.835, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="b629582f-474b-4e11-ac3a-9be86c56d955" absoluteBounds="3.5, 3.75, 2, 1.1939925130208327">
+      <DataClassMoniker Name="/NorthwindDataContext/CustomerCustomerDemo" />
+      <nestedChildShapes>
+        <elementListCompartment Id="09c1323d-0e12-4740-b675-931ae7295e2c" absoluteBounds="3.515, 4.21, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="65690936-af5c-43e3-81b8-adb64e57338e" absoluteBounds="0.75, 0.75, 2, 1.1939925130208335">
+      <DataClassMoniker Name="/NorthwindDataContext/CustomerDemographic" />
+      <nestedChildShapes>
+        <elementListCompartment Id="d446ede6-c90e-4fc0-a217-8671ea27aaac" absoluteBounds="0.765, 1.21, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="bd563047-81b5-4cdf-95b7-2349e1a465e9" absoluteBounds="0.75, 2.875, 2, 2.9247054036458322">
+      <DataClassMoniker Name="/NorthwindDataContext/Customer" />
+      <nestedChildShapes>
+        <elementListCompartment Id="d94a20f2-55c2-4785-8033-e9f093841d66" absoluteBounds="0.765, 3.335, 1.9700000000000002, 2.364705403645833" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="06900d69-9c6d-47df-8c23-24a928ab0ed5" absoluteBounds="3.75, 8.625, 2, 4.2708154296874987">
+      <DataClassMoniker Name="/NorthwindDataContext/Employee" />
+      <nestedChildShapes>
+        <elementListCompartment Id="607be449-eb06-43b0-8da1-2aefb03a6562" absoluteBounds="3.765, 9.085, 1.9700000000000002, 3.7108154296875" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="7c0d5f5a-5cdd-42a5-b550-922619960781" absoluteBounds="12.25, 9.5, 2, 1.1939925130208344">
+      <DataClassMoniker Name="/NorthwindDataContext/EmployeeTerritory" />
+      <nestedChildShapes>
+        <elementListCompartment Id="bff78cfd-acd7-40aa-8ae4-88e9cce753f5" absoluteBounds="12.265, 9.96, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="86f73524-9d74-4902-b8aa-c515bccfe48f" absoluteBounds="9.25, 3.5, 2, 1.7708968098958322">
+      <DataClassMoniker Name="/NorthwindDataContext/Order_Detail" />
+      <nestedChildShapes>
+        <elementListCompartment Id="a730f366-3782-4134-a1c5-190e85ec9aac" absoluteBounds="9.265, 3.96, 1.9700000000000002, 1.2108968098958333" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="14aa6ac1-500f-4ad0-b450-27cfb4529b76" absoluteBounds="6.5, 2.625, 2, 3.5016097005208322">
+      <DataClassMoniker Name="/NorthwindDataContext/Order" />
+      <nestedChildShapes>
+        <elementListCompartment Id="17fc4fa6-d6d3-4d59-9932-4eba681322fb" absoluteBounds="6.515, 3.085, 1.9700000000000002, 2.941609700520833" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="f297b0da-24b7-41a0-8ddb-8ceaf10bb5a2" absoluteBounds="6.5, 16, 2, 2.7324039713541683">
+      <DataClassMoniker Name="/NorthwindDataContext/Product" />
+      <nestedChildShapes>
+        <elementListCompartment Id="df6e7957-30a8-436d-9511-90143d06799a" absoluteBounds="6.515, 16.46, 1.9700000000000002, 2.1724039713541665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="e72e4bde-87fb-4e99-8ce3-791a4bfaf28d" absoluteBounds="6.75, 7.5, 2, 1.1939925130208344">
+      <DataClassMoniker Name="/NorthwindDataContext/Region" />
+      <nestedChildShapes>
+        <elementListCompartment Id="09c418dd-7000-418c-a80d-38644c6c7c2c" absoluteBounds="6.765, 7.96, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="b0452772-b9fc-432c-804d-e335eed32d94" absoluteBounds="3.75, 6.5, 2, 1.3862939453125005">
+      <DataClassMoniker Name="/NorthwindDataContext/Shipper" />
+      <nestedChildShapes>
+        <elementListCompartment Id="386c4a13-988e-4e00-a6b6-5a96cd053359" absoluteBounds="3.765, 6.96, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="d4fca122-8825-4b4a-a2fa-2a1999c21c23" absoluteBounds="3.75, 17, 2, 3.1170068359375023">
+      <DataClassMoniker Name="/NorthwindDataContext/Supplier" />
+      <nestedChildShapes>
+        <elementListCompartment Id="24483cd3-8668-4140-a88f-c7f4163651a6" absoluteBounds="3.765, 17.46, 1.9700000000000002, 2.5570068359375" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <associationConnector edgePoints="[(2.75 : 1.34699625651042); (4.5 : 1.34699625651042); (4.5 : 3.75)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/CustomerDemographic/CustomerDemographic_CustomerCustomerDemo" />
+      <nodes>
+        <classShapeMoniker Id="65690936-af5c-43e3-81b8-adb64e57338e" />
+        <classShapeMoniker Id="b629582f-474b-4e11-ac3a-9be86c56d955" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(2.75 : 4.34699625651042); (3.5 : 4.34699625651042)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Customer/Customer_CustomerCustomerDemo" />
+      <nodes>
+        <classShapeMoniker Id="bd563047-81b5-4cdf-95b7-2349e1a465e9" />
+        <classShapeMoniker Id="b629582f-474b-4e11-ac3a-9be86c56d955" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(4.45923076923077 : 12.8958154296875); (4.45923076923077 : 13.1458154296875); (5.05461538461539 : 13.1458154296875); (5.05461538461539 : 12.8958154296875)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+      <AssociationMoniker Name="/NorthwindDataContext/Employee/Employee_Employee" />
+      <nodes>
+        <classShapeMoniker Id="06900d69-9c6d-47df-8c23-24a928ab0ed5" />
+        <classShapeMoniker Id="06900d69-9c6d-47df-8c23-24a928ab0ed5" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(5.75 : 9.59375); (9.26041666666667 : 9.59375 : JumpStart); (9.42708333333333 : 9.59375 : JumpEnd); (12.25 : 9.59375)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Employee/Employee_EmployeeTerritory" />
+      <nodes>
+        <classShapeMoniker Id="06900d69-9c6d-47df-8c23-24a928ab0ed5" />
+        <classShapeMoniker Id="7c0d5f5a-5cdd-42a5-b550-922619960781" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(11.5 : 8.61460611979166); (12.46875 : 8.61460611979166); (12.46875 : 9.5)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Territory/Territory_EmployeeTerritory" />
+      <nodes>
+        <classShapeMoniker Id="2bb5887c-da73-4bb1-a2a3-b311af0e0de7" />
+        <classShapeMoniker Id="7c0d5f5a-5cdd-42a5-b550-922619960781" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(8.5 : 4.38544840494792); (9.25 : 4.38544840494792)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Order/Order_Order_Detail" />
+      <nodes>
+        <classShapeMoniker Id="14aa6ac1-500f-4ad0-b450-27cfb4529b76" />
+        <classShapeMoniker Id="86f73524-9d74-4902-b8aa-c515bccfe48f" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(2.75 : 3.28125); (4.41666666666667 : 3.28125 : JumpStart); (4.58333333333333 : 3.28125 : JumpEnd); (6.5 : 3.28125)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Customer/Customer_Order" />
+      <nodes>
+        <classShapeMoniker Id="bd563047-81b5-4cdf-95b7-2349e1a465e9" />
+        <classShapeMoniker Id="14aa6ac1-500f-4ad0-b450-27cfb4529b76" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(5.75 : 9.14386875651042); (6.59375 : 9.14386875651042); (6.59375 : 6.12660970052083)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Employee/Employee_Order" />
+      <nodes>
+        <classShapeMoniker Id="06900d69-9c6d-47df-8c23-24a928ab0ed5" />
+        <classShapeMoniker Id="14aa6ac1-500f-4ad0-b450-27cfb4529b76" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(8.5 : 18.1770654296875); (9.34375 : 18.1770654296875); (9.34375 : 5.27089680989583)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Product/Product_Order_Detail" />
+      <nodes>
+        <classShapeMoniker Id="f297b0da-24b7-41a0-8ddb-8ceaf10bb5a2" />
+        <classShapeMoniker Id="86f73524-9d74-4902-b8aa-c515bccfe48f" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(5.75 : 15.3124995); (7.5 : 15.3124995); (7.5 : 16)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Category/Category_Product" />
+      <nodes>
+        <classShapeMoniker Id="3b9375c8-34f2-4c3c-bcca-59016253cf92" />
+        <classShapeMoniker Id="f297b0da-24b7-41a0-8ddb-8ceaf10bb5a2" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(8.75 : 8.09699625651042); (9.26041666666667 : 8.09699625651042 : JumpStart); (9.42708333333333 : 8.09699625651042 : JumpEnd); (9.5 : 8.09699625651042)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Region/Region_Territory" />
+      <nodes>
+        <classShapeMoniker Id="e72e4bde-87fb-4e99-8ce3-791a4bfaf28d" />
+        <classShapeMoniker Id="2bb5887c-da73-4bb1-a2a3-b311af0e0de7" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(5.75 : 6.96875); (6.5624975 : 6.96875); (6.5624975 : 6.12660970052083)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Shipper/Shipper_Order" />
+      <nodes>
+        <classShapeMoniker Id="b0452772-b9fc-432c-804d-e335eed32d94" />
+        <classShapeMoniker Id="14aa6ac1-500f-4ad0-b450-27cfb4529b76" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(5.75 : 17.8662019856771); (6.5 : 17.8662019856771)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/NorthwindDataContext/Supplier/Supplier_Product" />
+      <nodes>
+        <classShapeMoniker Id="d4fca122-8825-4b4a-a2fa-2a1999c21c23" />
+        <classShapeMoniker Id="f297b0da-24b7-41a0-8ddb-8ceaf10bb5a2" />
+      </nodes>
+    </associationConnector>
+    <classShape Id="6ad43328-33be-4d9b-9452-c918b3faffdf" absoluteBounds="0.75, 6.75, 2, 2.9247054036458318">
+      <DataClassMoniker Name="/NorthwindDataContext/Alphabetical_list_of_product" />
+      <nestedChildShapes>
+        <elementListCompartment Id="0d1d9afb-d596-4e7c-9514-47a7b8cff4ad" absoluteBounds="0.765, 7.21, 1.9700000000000002, 2.364705403645833" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="d8a16878-0d9c-41c9-b614-529678fa14ec" absoluteBounds="9.75, 0.75, 2, 1.3862939453125003">
+      <DataClassMoniker Name="/NorthwindDataContext/Summary_of_Sales_by_Year" />
+      <nestedChildShapes>
+        <elementListCompartment Id="c16af244-ab34-4224-be3a-9f0379ee7b6e" absoluteBounds="9.765, 1.21, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="c66b7392-a737-462c-a4e6-ce508a5fbc17" absoluteBounds="6.75, 9.75, 2, 1.1939925130208344">
+      <DataClassMoniker Name="/NorthwindDataContext/Category_Sales_for_1997" />
+      <nestedChildShapes>
+        <elementListCompartment Id="2415e6a0-d96d-4745-8738-bb89ca9ffadb" absoluteBounds="6.765, 10.21, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="a7ccfe0f-19c2-4844-9964-b2b5155b3ebd" absoluteBounds="0.75, 10.75, 2, 1.1939925130208344">
+      <DataClassMoniker Name="/NorthwindDataContext/Current_Product_List" />
+      <nestedChildShapes>
+        <elementListCompartment Id="44a8cfe9-09fe-401d-af54-d64c7b4367b4" absoluteBounds="0.765, 11.21, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="ab41029a-add9-4ae9-8531-3f57d4c2d775" absoluteBounds="6.75, 11.75, 2, 1.5785953776041666">
+      <DataClassMoniker Name="/NorthwindDataContext/Customer_and_Suppliers_by_City" />
+      <nestedChildShapes>
+        <elementListCompartment Id="a2f9e294-d64c-4ec7-84b7-f054d4bafa05" absoluteBounds="6.765, 12.21, 1.9700000000000002, 1.0185953776041665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="7d4f6f03-f5d0-455b-997c-dd6431ac21b1" absoluteBounds="9.75, 11.75, 2, 5.8092268880208309">
+      <DataClassMoniker Name="/NorthwindDataContext/Invoice" />
+      <nestedChildShapes>
+        <elementListCompartment Id="1c23abbe-a75f-4f9a-bc1e-f654673b4999" absoluteBounds="9.765, 12.21, 1.9700000000000002, 5.249226888020833" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="f61ca77f-73c2-4cea-b564-2340c0feb3b2" absoluteBounds="12.75, 0.75, 2, 2.1554996744791666">
+      <DataClassMoniker Name="/NorthwindDataContext/Order_Details_Extended" />
+      <nestedChildShapes>
+        <elementListCompartment Id="2830e3d8-0996-4ca1-8fab-b8e0c644fb40" absoluteBounds="12.765, 1.21, 1.9700000000000002, 1.5954996744791665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="0081e9c3-5f61-4da7-a1de-389d3896af75" absoluteBounds="0.75, 12.75, 2, 1.1939925130208344">
+      <DataClassMoniker Name="/NorthwindDataContext/Order_Subtotal" />
+      <nestedChildShapes>
+        <elementListCompartment Id="fb27d152-8a51-46c8-97d5-46aa4cf56969" absoluteBounds="0.765, 13.21, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="2a39e1ee-46e0-4a88-8ace-8bc9ab17ce1c" absoluteBounds="12.75, 3.75, 2, 4.6554182942708318">
+      <DataClassMoniker Name="/NorthwindDataContext/Orders_Qry" />
+      <nestedChildShapes>
+        <elementListCompartment Id="19078d0f-7dac-4d62-ae29-0088792dd50f" absoluteBounds="12.765, 4.21, 1.9700000000000002, 4.095418294270833" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="4010c61b-ec8b-4f68-94d1-390345e28421" absoluteBounds="12.75, 11.75, 2, 1.3862939453124987">
+      <DataClassMoniker Name="/NorthwindDataContext/Product_Sales_for_1997" />
+      <nestedChildShapes>
+        <elementListCompartment Id="5d4e4117-5041-4d87-b4e1-cc0752bfeeff" absoluteBounds="12.765, 12.21, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="ac400aa7-f253-4245-a974-786dd181276a" absoluteBounds="0.75, 14.75, 2, 1.1939925130208344">
+      <DataClassMoniker Name="/NorthwindDataContext/Products_Above_Average_Price" />
+      <nestedChildShapes>
+        <elementListCompartment Id="9ed91a2a-1e08-47b0-8b39-9d6dbc4092ac" absoluteBounds="0.765, 15.21, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="bd8ce512-5f0d-43d0-a86a-130cac30b77d" absoluteBounds="12.75, 14.75, 2, 1.7708968098958344">
+      <DataClassMoniker Name="/NorthwindDataContext/Products_by_Category" />
+      <nestedChildShapes>
+        <elementListCompartment Id="817ca83c-63aa-4dc9-92f4-230fccc4a929" absoluteBounds="12.765, 15.21, 1.9700000000000002, 1.2108968098958333" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="04e97ea4-5746-4c54-b763-57f74500a263" absoluteBounds="15.75, 0.75, 2, 1.5785953776041666">
+      <DataClassMoniker Name="/NorthwindDataContext/Quarterly_Order" />
+      <nestedChildShapes>
+        <elementListCompartment Id="d08b7626-107e-47f1-b521-679653d702be" absoluteBounds="15.765, 1.21, 1.9700000000000002, 1.0185953776041665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="e95cbca7-d82b-47ca-b9e1-f96b94a11e8a" absoluteBounds="15.75, 3.75, 2, 1.5785953776041666">
+      <DataClassMoniker Name="/NorthwindDataContext/Sales_by_Category" />
+      <nestedChildShapes>
+        <elementListCompartment Id="583d4513-9076-4515-8277-5e4f31e498c5" absoluteBounds="15.765, 4.21, 1.9700000000000002, 1.0185953776041665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="6fd0a097-055d-4814-9fcb-d7eca513b16c" absoluteBounds="15.75, 6.75, 2, 1.5785953776041666">
+      <DataClassMoniker Name="/NorthwindDataContext/Sales_Totals_by_Amount" />
+      <nestedChildShapes>
+        <elementListCompartment Id="eaaea9e0-0a53-4102-b31a-7303aec4f861" absoluteBounds="15.765, 7.21, 1.9700000000000002, 1.0185953776041665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="56ddaffc-8b62-442d-bbc5-3e1a1325fb11" absoluteBounds="15.75, 9.75, 2, 1.3862939453124987">
+      <DataClassMoniker Name="/NorthwindDataContext/Summary_of_Sales_by_Quarter" />
+      <nestedChildShapes>
+        <elementListCompartment Id="76c72d80-82b2-4bbc-8861-05cd028e2a66" absoluteBounds="15.765, 10.21, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+  </nestedChildShapes>
+</ordesignerObjectsDiagram>
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Northwind.designer.cs b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Northwind.designer.cs
new file mode 100644
index 0000000..86b5cc6
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Northwind.designer.cs
@@ -0,0 +1,6397 @@
+#pragma warning disable 1591
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.1
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace LinqToSql.Northwind
+{
+	using System.Data.Linq;
+	using System.Data.Linq.Mapping;
+	using System.Data;
+	using System.Collections.Generic;
+	using System.Reflection;
+	using System.Linq;
+	using System.Linq.Expressions;
+	using System.ComponentModel;
+	using System;
+	
+	
+	[global::System.Data.Linq.Mapping.DatabaseAttribute(Name="NORTHWND")]
+	public partial class NorthwindDataContext : System.Data.Linq.DataContext
+	{
+		
+		private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
+		
+    #region Extensibility Method Definitions
+    partial void OnCreated();
+    partial void InsertCategory(Category instance);
+    partial void UpdateCategory(Category instance);
+    partial void DeleteCategory(Category instance);
+    partial void InsertTerritory(Territory instance);
+    partial void UpdateTerritory(Territory instance);
+    partial void DeleteTerritory(Territory instance);
+    partial void InsertCustomerCustomerDemo(CustomerCustomerDemo instance);
+    partial void UpdateCustomerCustomerDemo(CustomerCustomerDemo instance);
+    partial void DeleteCustomerCustomerDemo(CustomerCustomerDemo instance);
+    partial void InsertCustomerDemographic(CustomerDemographic instance);
+    partial void UpdateCustomerDemographic(CustomerDemographic instance);
+    partial void DeleteCustomerDemographic(CustomerDemographic instance);
+    partial void InsertCustomer(Customer instance);
+    partial void UpdateCustomer(Customer instance);
+    partial void DeleteCustomer(Customer instance);
+    partial void InsertEmployee(Employee instance);
+    partial void UpdateEmployee(Employee instance);
+    partial void DeleteEmployee(Employee instance);
+    partial void InsertEmployeeTerritory(EmployeeTerritory instance);
+    partial void UpdateEmployeeTerritory(EmployeeTerritory instance);
+    partial void DeleteEmployeeTerritory(EmployeeTerritory instance);
+    partial void InsertOrder_Detail(Order_Detail instance);
+    partial void UpdateOrder_Detail(Order_Detail instance);
+    partial void DeleteOrder_Detail(Order_Detail instance);
+    partial void InsertOrder(Order instance);
+    partial void UpdateOrder(Order instance);
+    partial void DeleteOrder(Order instance);
+    partial void InsertProduct(Product instance);
+    partial void UpdateProduct(Product instance);
+    partial void DeleteProduct(Product instance);
+    partial void InsertRegion(Region instance);
+    partial void UpdateRegion(Region instance);
+    partial void DeleteRegion(Region instance);
+    partial void InsertShipper(Shipper instance);
+    partial void UpdateShipper(Shipper instance);
+    partial void DeleteShipper(Shipper instance);
+    partial void InsertSupplier(Supplier instance);
+    partial void UpdateSupplier(Supplier instance);
+    partial void DeleteSupplier(Supplier instance);
+    #endregion
+		
+		public NorthwindDataContext() : 
+				base(global::LinqToSql.Northwind.Properties.Settings.Default.NORTHWNDConnectionString, mappingSource)
+		{
+			OnCreated();
+		}
+		
+		public NorthwindDataContext(string connection) : 
+				base(connection, mappingSource)
+		{
+			OnCreated();
+		}
+		
+		public NorthwindDataContext(System.Data.IDbConnection connection) : 
+				base(connection, mappingSource)
+		{
+			OnCreated();
+		}
+		
+		public NorthwindDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) : 
+				base(connection, mappingSource)
+		{
+			OnCreated();
+		}
+		
+		public NorthwindDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) : 
+				base(connection, mappingSource)
+		{
+			OnCreated();
+		}
+		
+		public System.Data.Linq.Table<Category> Categories
+		{
+			get
+			{
+				return this.GetTable<Category>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Territory> Territories
+		{
+			get
+			{
+				return this.GetTable<Territory>();
+			}
+		}
+		
+		public System.Data.Linq.Table<CustomerCustomerDemo> CustomerCustomerDemos
+		{
+			get
+			{
+				return this.GetTable<CustomerCustomerDemo>();
+			}
+		}
+		
+		public System.Data.Linq.Table<CustomerDemographic> CustomerDemographics
+		{
+			get
+			{
+				return this.GetTable<CustomerDemographic>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Customer> Customers
+		{
+			get
+			{
+				return this.GetTable<Customer>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Employee> Employees
+		{
+			get
+			{
+				return this.GetTable<Employee>();
+			}
+		}
+		
+		public System.Data.Linq.Table<EmployeeTerritory> EmployeeTerritories
+		{
+			get
+			{
+				return this.GetTable<EmployeeTerritory>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Order_Detail> Order_Details
+		{
+			get
+			{
+				return this.GetTable<Order_Detail>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Order> Orders
+		{
+			get
+			{
+				return this.GetTable<Order>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Product> Products
+		{
+			get
+			{
+				return this.GetTable<Product>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Region> Regions
+		{
+			get
+			{
+				return this.GetTable<Region>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Shipper> Shippers
+		{
+			get
+			{
+				return this.GetTable<Shipper>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Supplier> Suppliers
+		{
+			get
+			{
+				return this.GetTable<Supplier>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Alphabetical_list_of_product> Alphabetical_list_of_products
+		{
+			get
+			{
+				return this.GetTable<Alphabetical_list_of_product>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Summary_of_Sales_by_Year> Summary_of_Sales_by_Years
+		{
+			get
+			{
+				return this.GetTable<Summary_of_Sales_by_Year>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Category_Sales_for_1997> Category_Sales_for_1997s
+		{
+			get
+			{
+				return this.GetTable<Category_Sales_for_1997>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Current_Product_List> Current_Product_Lists
+		{
+			get
+			{
+				return this.GetTable<Current_Product_List>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Customer_and_Suppliers_by_City> Customer_and_Suppliers_by_Cities
+		{
+			get
+			{
+				return this.GetTable<Customer_and_Suppliers_by_City>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Invoice> Invoices
+		{
+			get
+			{
+				return this.GetTable<Invoice>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Order_Details_Extended> Order_Details_Extendeds
+		{
+			get
+			{
+				return this.GetTable<Order_Details_Extended>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Order_Subtotal> Order_Subtotals
+		{
+			get
+			{
+				return this.GetTable<Order_Subtotal>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Orders_Qry> Orders_Qries
+		{
+			get
+			{
+				return this.GetTable<Orders_Qry>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Product_Sales_for_1997> Product_Sales_for_1997s
+		{
+			get
+			{
+				return this.GetTable<Product_Sales_for_1997>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Products_Above_Average_Price> Products_Above_Average_Prices
+		{
+			get
+			{
+				return this.GetTable<Products_Above_Average_Price>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Products_by_Category> Products_by_Categories
+		{
+			get
+			{
+				return this.GetTable<Products_by_Category>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Quarterly_Order> Quarterly_Orders
+		{
+			get
+			{
+				return this.GetTable<Quarterly_Order>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Sales_by_Category> Sales_by_Categories
+		{
+			get
+			{
+				return this.GetTable<Sales_by_Category>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Sales_Totals_by_Amount> Sales_Totals_by_Amounts
+		{
+			get
+			{
+				return this.GetTable<Sales_Totals_by_Amount>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Summary_of_Sales_by_Quarter> Summary_of_Sales_by_Quarters
+		{
+			get
+			{
+				return this.GetTable<Summary_of_Sales_by_Quarter>();
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.CustOrderHist")]
+		public ISingleResult<CustOrderHistResult> CustOrderHist([global::System.Data.Linq.Mapping.ParameterAttribute(Name="CustomerID", DbType="NChar(5)")] string customerID)
+		{
+			IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), customerID);
+			return ((ISingleResult<CustOrderHistResult>)(result.ReturnValue));
+		}
+		
+		[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.[Ten Most Expensive Products]")]
+		public ISingleResult<Ten_Most_Expensive_ProductsResult> Ten_Most_Expensive_Products()
+		{
+			IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
+			return ((ISingleResult<Ten_Most_Expensive_ProductsResult>)(result.ReturnValue));
+		}
+		
+		[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.CustOrdersDetail")]
+		public ISingleResult<CustOrdersDetailResult> CustOrdersDetail([global::System.Data.Linq.Mapping.ParameterAttribute(Name="OrderID", DbType="Int")] System.Nullable<int> orderID)
+		{
+			IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), orderID);
+			return ((ISingleResult<CustOrdersDetailResult>)(result.ReturnValue));
+		}
+		
+		[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.CustOrdersOrders")]
+		public ISingleResult<CustOrdersOrdersResult> CustOrdersOrders([global::System.Data.Linq.Mapping.ParameterAttribute(Name="CustomerID", DbType="NChar(5)")] string customerID)
+		{
+			IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), customerID);
+			return ((ISingleResult<CustOrdersOrdersResult>)(result.ReturnValue));
+		}
+		
+		[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.DeleteProduct")]
+		public int DeleteProduct([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> id)
+		{
+			IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), id);
+			return ((int)(result.ReturnValue));
+		}
+		
+		[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.[Employee Sales by Country]")]
+		public ISingleResult<Employee_Sales_by_CountryResult> Employee_Sales_by_Country([global::System.Data.Linq.Mapping.ParameterAttribute(Name="Beginning_Date", DbType="DateTime")] System.Nullable<System.DateTime> beginning_Date, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="Ending_Date", DbType="DateTime")] System.Nullable<System.DateTime> ending_Date)
+		{
+			IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), beginning_Date, ending_Date);
+			return ((ISingleResult<Employee_Sales_by_CountryResult>)(result.ReturnValue));
+		}
+		
+		[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.ChangeProductPrice")]
+		public int ChangeProductPrice([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> prod, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Money")] System.Nullable<decimal> price)
+		{
+			IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), prod, price);
+			return ((int)(result.ReturnValue));
+		}
+		
+		[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.InsertProduct")]
+		public int InsertProduct([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="NVarChar(40)")] string name, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Money")] System.Nullable<decimal> price, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] ref System.Nullable<int> id)
+		{
+			IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), name, price, id);
+			id = ((System.Nullable<int>)(result.GetParameterValue(2)));
+			return ((int)(result.ReturnValue));
+		}
+		
+		[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.[Sales by Year]")]
+		public ISingleResult<Sales_by_YearResult> Sales_by_Year([global::System.Data.Linq.Mapping.ParameterAttribute(Name="Beginning_Date", DbType="DateTime")] System.Nullable<System.DateTime> beginning_Date, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="Ending_Date", DbType="DateTime")] System.Nullable<System.DateTime> ending_Date)
+		{
+			IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), beginning_Date, ending_Date);
+			return ((ISingleResult<Sales_by_YearResult>)(result.ReturnValue));
+		}
+		
+		[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.SalesByCategory")]
+		public ISingleResult<SalesByCategoryResult> SalesByCategory([global::System.Data.Linq.Mapping.ParameterAttribute(Name="CategoryName", DbType="NVarChar(15)")] string categoryName, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="OrdYear", DbType="NVarChar(4)")] string ordYear)
+		{
+			IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), categoryName, ordYear);
+			return ((ISingleResult<SalesByCategoryResult>)(result.ReturnValue));
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Categories")]
+	public partial class Category : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private int _CategoryID;
+		
+		private string _CategoryName;
+		
+		private string _Description;
+		
+		private System.Data.Linq.Binary _Picture;
+		
+		private EntitySet<Product> _Products;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnCategoryIDChanging(int value);
+    partial void OnCategoryIDChanged();
+    partial void OnCategoryNameChanging(string value);
+    partial void OnCategoryNameChanged();
+    partial void OnDescriptionChanging(string value);
+    partial void OnDescriptionChanged();
+    partial void OnPictureChanging(System.Data.Linq.Binary value);
+    partial void OnPictureChanged();
+    #endregion
+		
+		public Category()
+		{
+			this._Products = new EntitySet<Product>(new Action<Product>(this.attach_Products), new Action<Product>(this.detach_Products));
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategoryID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+		public int CategoryID
+		{
+			get
+			{
+				return this._CategoryID;
+			}
+			set
+			{
+				if ((this._CategoryID != value))
+				{
+					this.OnCategoryIDChanging(value);
+					this.SendPropertyChanging();
+					this._CategoryID = value;
+					this.SendPropertyChanged("CategoryID");
+					this.OnCategoryIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategoryName", DbType="NVarChar(15) NOT NULL", CanBeNull=false)]
+		public string CategoryName
+		{
+			get
+			{
+				return this._CategoryName;
+			}
+			set
+			{
+				if ((this._CategoryName != value))
+				{
+					this.OnCategoryNameChanging(value);
+					this.SendPropertyChanging();
+					this._CategoryName = value;
+					this.SendPropertyChanged("CategoryName");
+					this.OnCategoryNameChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Description", DbType="NText", UpdateCheck=UpdateCheck.Never)]
+		public string Description
+		{
+			get
+			{
+				return this._Description;
+			}
+			set
+			{
+				if ((this._Description != value))
+				{
+					this.OnDescriptionChanging(value);
+					this.SendPropertyChanging();
+					this._Description = value;
+					this.SendPropertyChanged("Description");
+					this.OnDescriptionChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Picture", DbType="Image", UpdateCheck=UpdateCheck.Never)]
+		public System.Data.Linq.Binary Picture
+		{
+			get
+			{
+				return this._Picture;
+			}
+			set
+			{
+				if ((this._Picture != value))
+				{
+					this.OnPictureChanging(value);
+					this.SendPropertyChanging();
+					this._Picture = value;
+					this.SendPropertyChanged("Picture");
+					this.OnPictureChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Category_Product", Storage="_Products", ThisKey="CategoryID", OtherKey="CategoryID")]
+		public EntitySet<Product> Products
+		{
+			get
+			{
+				return this._Products;
+			}
+			set
+			{
+				this._Products.Assign(value);
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_Products(Product entity)
+		{
+			this.SendPropertyChanging();
+			entity.Category = this;
+		}
+		
+		private void detach_Products(Product entity)
+		{
+			this.SendPropertyChanging();
+			entity.Category = null;
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Territories")]
+	public partial class Territory : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private string _TerritoryID;
+		
+		private string _TerritoryDescription;
+		
+		private int _RegionID;
+		
+		private EntitySet<EmployeeTerritory> _EmployeeTerritories;
+		
+		private EntityRef<Region> _Region;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnTerritoryIDChanging(string value);
+    partial void OnTerritoryIDChanged();
+    partial void OnTerritoryDescriptionChanging(string value);
+    partial void OnTerritoryDescriptionChanged();
+    partial void OnRegionIDChanging(int value);
+    partial void OnRegionIDChanged();
+    #endregion
+		
+		public Territory()
+		{
+			this._EmployeeTerritories = new EntitySet<EmployeeTerritory>(new Action<EmployeeTerritory>(this.attach_EmployeeTerritories), new Action<EmployeeTerritory>(this.detach_EmployeeTerritories));
+			this._Region = default(EntityRef<Region>);
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_TerritoryID", DbType="NVarChar(20) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+		public string TerritoryID
+		{
+			get
+			{
+				return this._TerritoryID;
+			}
+			set
+			{
+				if ((this._TerritoryID != value))
+				{
+					this.OnTerritoryIDChanging(value);
+					this.SendPropertyChanging();
+					this._TerritoryID = value;
+					this.SendPropertyChanged("TerritoryID");
+					this.OnTerritoryIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_TerritoryDescription", DbType="NChar(50) NOT NULL", CanBeNull=false)]
+		public string TerritoryDescription
+		{
+			get
+			{
+				return this._TerritoryDescription;
+			}
+			set
+			{
+				if ((this._TerritoryDescription != value))
+				{
+					this.OnTerritoryDescriptionChanging(value);
+					this.SendPropertyChanging();
+					this._TerritoryDescription = value;
+					this.SendPropertyChanged("TerritoryDescription");
+					this.OnTerritoryDescriptionChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RegionID", DbType="Int NOT NULL")]
+		public int RegionID
+		{
+			get
+			{
+				return this._RegionID;
+			}
+			set
+			{
+				if ((this._RegionID != value))
+				{
+					if (this._Region.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnRegionIDChanging(value);
+					this.SendPropertyChanging();
+					this._RegionID = value;
+					this.SendPropertyChanged("RegionID");
+					this.OnRegionIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Territory_EmployeeTerritory", Storage="_EmployeeTerritories", ThisKey="TerritoryID", OtherKey="TerritoryID")]
+		public EntitySet<EmployeeTerritory> EmployeeTerritories
+		{
+			get
+			{
+				return this._EmployeeTerritories;
+			}
+			set
+			{
+				this._EmployeeTerritories.Assign(value);
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Region_Territory", Storage="_Region", ThisKey="RegionID", OtherKey="RegionID", IsForeignKey=true)]
+		public Region Region
+		{
+			get
+			{
+				return this._Region.Entity;
+			}
+			set
+			{
+				Region previousValue = this._Region.Entity;
+				if (((previousValue != value) 
+							|| (this._Region.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Region.Entity = null;
+						previousValue.Territories.Remove(this);
+					}
+					this._Region.Entity = value;
+					if ((value != null))
+					{
+						value.Territories.Add(this);
+						this._RegionID = value.RegionID;
+					}
+					else
+					{
+						this._RegionID = default(int);
+					}
+					this.SendPropertyChanged("Region");
+				}
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_EmployeeTerritories(EmployeeTerritory entity)
+		{
+			this.SendPropertyChanging();
+			entity.Territory = this;
+		}
+		
+		private void detach_EmployeeTerritories(EmployeeTerritory entity)
+		{
+			this.SendPropertyChanging();
+			entity.Territory = null;
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.CustomerCustomerDemo")]
+	public partial class CustomerCustomerDemo : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private string _CustomerID;
+		
+		private string _CustomerTypeID;
+		
+		private EntityRef<CustomerDemographic> _CustomerDemographic;
+		
+		private EntityRef<Customer> _Customer;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnCustomerIDChanging(string value);
+    partial void OnCustomerIDChanged();
+    partial void OnCustomerTypeIDChanging(string value);
+    partial void OnCustomerTypeIDChanged();
+    #endregion
+		
+		public CustomerCustomerDemo()
+		{
+			this._CustomerDemographic = default(EntityRef<CustomerDemographic>);
+			this._Customer = default(EntityRef<Customer>);
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CustomerID", DbType="NChar(5) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+		public string CustomerID
+		{
+			get
+			{
+				return this._CustomerID;
+			}
+			set
+			{
+				if ((this._CustomerID != value))
+				{
+					if (this._Customer.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnCustomerIDChanging(value);
+					this.SendPropertyChanging();
+					this._CustomerID = value;
+					this.SendPropertyChanged("CustomerID");
+					this.OnCustomerIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CustomerTypeID", DbType="NChar(10) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+		public string CustomerTypeID
+		{
+			get
+			{
+				return this._CustomerTypeID;
+			}
+			set
+			{
+				if ((this._CustomerTypeID != value))
+				{
+					if (this._CustomerDemographic.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnCustomerTypeIDChanging(value);
+					this.SendPropertyChanging();
+					this._CustomerTypeID = value;
+					this.SendPropertyChanged("CustomerTypeID");
+					this.OnCustomerTypeIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="CustomerDemographic_CustomerCustomerDemo", Storage="_CustomerDemographic", ThisKey="CustomerTypeID", OtherKey="CustomerTypeID", IsForeignKey=true)]
+		public CustomerDemographic CustomerDemographic
+		{
+			get
+			{
+				return this._CustomerDemographic.Entity;
+			}
+			set
+			{
+				CustomerDemographic previousValue = this._CustomerDemographic.Entity;
+				if (((previousValue != value) 
+							|| (this._CustomerDemographic.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._CustomerDemographic.Entity = null;
+						previousValue.CustomerCustomerDemos.Remove(this);
+					}
+					this._CustomerDemographic.Entity = value;
+					if ((value != null))
+					{
+						value.CustomerCustomerDemos.Add(this);
+						this._CustomerTypeID = value.CustomerTypeID;
+					}
+					else
+					{
+						this._CustomerTypeID = default(string);
+					}
+					this.SendPropertyChanged("CustomerDemographic");
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Customer_CustomerCustomerDemo", Storage="_Customer", ThisKey="CustomerID", OtherKey="CustomerID", IsForeignKey=true)]
+		public Customer Customer
+		{
+			get
+			{
+				return this._Customer.Entity;
+			}
+			set
+			{
+				Customer previousValue = this._Customer.Entity;
+				if (((previousValue != value) 
+							|| (this._Customer.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Customer.Entity = null;
+						previousValue.CustomerCustomerDemos.Remove(this);
+					}
+					this._Customer.Entity = value;
+					if ((value != null))
+					{
+						value.CustomerCustomerDemos.Add(this);
+						this._CustomerID = value.CustomerID;
+					}
+					else
+					{
+						this._CustomerID = default(string);
+					}
+					this.SendPropertyChanged("Customer");
+				}
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.CustomerDemographics")]
+	public partial class CustomerDemographic : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private string _CustomerTypeID;
+		
+		private string _CustomerDesc;
+		
+		private EntitySet<CustomerCustomerDemo> _CustomerCustomerDemos;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnCustomerTypeIDChanging(string value);
+    partial void OnCustomerTypeIDChanged();
+    partial void OnCustomerDescChanging(string value);
+    partial void OnCustomerDescChanged();
+    #endregion
+		
+		public CustomerDemographic()
+		{
+			this._CustomerCustomerDemos = new EntitySet<CustomerCustomerDemo>(new Action<CustomerCustomerDemo>(this.attach_CustomerCustomerDemos), new Action<CustomerCustomerDemo>(this.detach_CustomerCustomerDemos));
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CustomerTypeID", DbType="NChar(10) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+		public string CustomerTypeID
+		{
+			get
+			{
+				return this._CustomerTypeID;
+			}
+			set
+			{
+				if ((this._CustomerTypeID != value))
+				{
+					this.OnCustomerTypeIDChanging(value);
+					this.SendPropertyChanging();
+					this._CustomerTypeID = value;
+					this.SendPropertyChanged("CustomerTypeID");
+					this.OnCustomerTypeIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CustomerDesc", DbType="NText", UpdateCheck=UpdateCheck.Never)]
+		public string CustomerDesc
+		{
+			get
+			{
+				return this._CustomerDesc;
+			}
+			set
+			{
+				if ((this._CustomerDesc != value))
+				{
+					this.OnCustomerDescChanging(value);
+					this.SendPropertyChanging();
+					this._CustomerDesc = value;
+					this.SendPropertyChanged("CustomerDesc");
+					this.OnCustomerDescChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="CustomerDemographic_CustomerCustomerDemo", Storage="_CustomerCustomerDemos", ThisKey="CustomerTypeID", OtherKey="CustomerTypeID")]
+		public EntitySet<CustomerCustomerDemo> CustomerCustomerDemos
+		{
+			get
+			{
+				return this._CustomerCustomerDemos;
+			}
+			set
+			{
+				this._CustomerCustomerDemos.Assign(value);
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_CustomerCustomerDemos(CustomerCustomerDemo entity)
+		{
+			this.SendPropertyChanging();
+			entity.CustomerDemographic = this;
+		}
+		
+		private void detach_CustomerCustomerDemos(CustomerCustomerDemo entity)
+		{
+			this.SendPropertyChanging();
+			entity.CustomerDemographic = null;
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Customers")]
+	public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private string _CustomerID;
+		
+		private string _CompanyName;
+		
+		private string _ContactName;
+		
+		private string _ContactTitle;
+		
+		private string _Address;
+		
+		private string _City;
+		
+		private string _Region;
+		
+		private string _PostalCode;
+		
+		private string _Country;
+		
+		private string _Phone;
+		
+		private string _Fax;
+		
+		private EntitySet<CustomerCustomerDemo> _CustomerCustomerDemos;
+		
+		private EntitySet<Order> _Orders;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnCustomerIDChanging(string value);
+    partial void OnCustomerIDChanged();
+    partial void OnCompanyNameChanging(string value);
+    partial void OnCompanyNameChanged();
+    partial void OnContactNameChanging(string value);
+    partial void OnContactNameChanged();
+    partial void OnContactTitleChanging(string value);
+    partial void OnContactTitleChanged();
+    partial void OnAddressChanging(string value);
+    partial void OnAddressChanged();
+    partial void OnCityChanging(string value);
+    partial void OnCityChanged();
+    partial void OnRegionChanging(string value);
+    partial void OnRegionChanged();
+    partial void OnPostalCodeChanging(string value);
+    partial void OnPostalCodeChanged();
+    partial void OnCountryChanging(string value);
+    partial void OnCountryChanged();
+    partial void OnPhoneChanging(string value);
+    partial void OnPhoneChanged();
+    partial void OnFaxChanging(string value);
+    partial void OnFaxChanged();
+    #endregion
+		
+		public Customer()
+		{
+			this._CustomerCustomerDemos = new EntitySet<CustomerCustomerDemo>(new Action<CustomerCustomerDemo>(this.attach_CustomerCustomerDemos), new Action<CustomerCustomerDemo>(this.detach_CustomerCustomerDemos));
+			this._Orders = new EntitySet<Order>(new Action<Order>(this.attach_Orders), new Action<Order>(this.detach_Orders));
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CustomerID", DbType="NChar(5) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+		public string CustomerID
+		{
+			get
+			{
+				return this._CustomerID;
+			}
+			set
+			{
+				if ((this._CustomerID != value))
+				{
+					this.OnCustomerIDChanging(value);
+					this.SendPropertyChanging();
+					this._CustomerID = value;
+					this.SendPropertyChanged("CustomerID");
+					this.OnCustomerIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string CompanyName
+		{
+			get
+			{
+				return this._CompanyName;
+			}
+			set
+			{
+				if ((this._CompanyName != value))
+				{
+					this.OnCompanyNameChanging(value);
+					this.SendPropertyChanging();
+					this._CompanyName = value;
+					this.SendPropertyChanged("CompanyName");
+					this.OnCompanyNameChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ContactName", DbType="NVarChar(30)")]
+		public string ContactName
+		{
+			get
+			{
+				return this._ContactName;
+			}
+			set
+			{
+				if ((this._ContactName != value))
+				{
+					this.OnContactNameChanging(value);
+					this.SendPropertyChanging();
+					this._ContactName = value;
+					this.SendPropertyChanged("ContactName");
+					this.OnContactNameChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ContactTitle", DbType="NVarChar(30)")]
+		public string ContactTitle
+		{
+			get
+			{
+				return this._ContactTitle;
+			}
+			set
+			{
+				if ((this._ContactTitle != value))
+				{
+					this.OnContactTitleChanging(value);
+					this.SendPropertyChanging();
+					this._ContactTitle = value;
+					this.SendPropertyChanged("ContactTitle");
+					this.OnContactTitleChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Address", DbType="NVarChar(60)")]
+		public string Address
+		{
+			get
+			{
+				return this._Address;
+			}
+			set
+			{
+				if ((this._Address != value))
+				{
+					this.OnAddressChanging(value);
+					this.SendPropertyChanging();
+					this._Address = value;
+					this.SendPropertyChanged("Address");
+					this.OnAddressChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_City", DbType="NVarChar(15)")]
+		public string City
+		{
+			get
+			{
+				return this._City;
+			}
+			set
+			{
+				if ((this._City != value))
+				{
+					this.OnCityChanging(value);
+					this.SendPropertyChanging();
+					this._City = value;
+					this.SendPropertyChanged("City");
+					this.OnCityChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Region", DbType="NVarChar(15)")]
+		public string Region
+		{
+			get
+			{
+				return this._Region;
+			}
+			set
+			{
+				if ((this._Region != value))
+				{
+					this.OnRegionChanging(value);
+					this.SendPropertyChanging();
+					this._Region = value;
+					this.SendPropertyChanged("Region");
+					this.OnRegionChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PostalCode", DbType="NVarChar(10)")]
+		public string PostalCode
+		{
+			get
+			{
+				return this._PostalCode;
+			}
+			set
+			{
+				if ((this._PostalCode != value))
+				{
+					this.OnPostalCodeChanging(value);
+					this.SendPropertyChanging();
+					this._PostalCode = value;
+					this.SendPropertyChanged("PostalCode");
+					this.OnPostalCodeChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Country", DbType="NVarChar(15)")]
+		public string Country
+		{
+			get
+			{
+				return this._Country;
+			}
+			set
+			{
+				if ((this._Country != value))
+				{
+					this.OnCountryChanging(value);
+					this.SendPropertyChanging();
+					this._Country = value;
+					this.SendPropertyChanged("Country");
+					this.OnCountryChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Phone", DbType="NVarChar(24)")]
+		public string Phone
+		{
+			get
+			{
+				return this._Phone;
+			}
+			set
+			{
+				if ((this._Phone != value))
+				{
+					this.OnPhoneChanging(value);
+					this.SendPropertyChanging();
+					this._Phone = value;
+					this.SendPropertyChanged("Phone");
+					this.OnPhoneChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Fax", DbType="NVarChar(24)")]
+		public string Fax
+		{
+			get
+			{
+				return this._Fax;
+			}
+			set
+			{
+				if ((this._Fax != value))
+				{
+					this.OnFaxChanging(value);
+					this.SendPropertyChanging();
+					this._Fax = value;
+					this.SendPropertyChanged("Fax");
+					this.OnFaxChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Customer_CustomerCustomerDemo", Storage="_CustomerCustomerDemos", ThisKey="CustomerID", OtherKey="CustomerID")]
+		public EntitySet<CustomerCustomerDemo> CustomerCustomerDemos
+		{
+			get
+			{
+				return this._CustomerCustomerDemos;
+			}
+			set
+			{
+				this._CustomerCustomerDemos.Assign(value);
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Customer_Order", Storage="_Orders", ThisKey="CustomerID", OtherKey="CustomerID")]
+		public EntitySet<Order> Orders
+		{
+			get
+			{
+				return this._Orders;
+			}
+			set
+			{
+				this._Orders.Assign(value);
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_CustomerCustomerDemos(CustomerCustomerDemo entity)
+		{
+			this.SendPropertyChanging();
+			entity.Customer = this;
+		}
+		
+		private void detach_CustomerCustomerDemos(CustomerCustomerDemo entity)
+		{
+			this.SendPropertyChanging();
+			entity.Customer = null;
+		}
+		
+		private void attach_Orders(Order entity)
+		{
+			this.SendPropertyChanging();
+			entity.Customer = this;
+		}
+		
+		private void detach_Orders(Order entity)
+		{
+			this.SendPropertyChanging();
+			entity.Customer = null;
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Employees")]
+	public partial class Employee : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private int _EmployeeID;
+		
+		private string _LastName;
+		
+		private string _FirstName;
+		
+		private string _Title;
+		
+		private string _TitleOfCourtesy;
+		
+		private System.Nullable<System.DateTime> _BirthDate;
+		
+		private System.Nullable<System.DateTime> _HireDate;
+		
+		private string _Address;
+		
+		private string _City;
+		
+		private string _Region;
+		
+		private string _PostalCode;
+		
+		private string _Country;
+		
+		private string _HomePhone;
+		
+		private string _Extension;
+		
+		private System.Data.Linq.Binary _Photo;
+		
+		private string _Notes;
+		
+		private System.Nullable<int> _ReportsTo;
+		
+		private string _PhotoPath;
+		
+		private EntitySet<Employee> _Employees;
+		
+		private EntitySet<EmployeeTerritory> _EmployeeTerritories;
+		
+		private EntitySet<Order> _Orders;
+		
+		private EntityRef<Employee> _Employee1;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnEmployeeIDChanging(int value);
+    partial void OnEmployeeIDChanged();
+    partial void OnLastNameChanging(string value);
+    partial void OnLastNameChanged();
+    partial void OnFirstNameChanging(string value);
+    partial void OnFirstNameChanged();
+    partial void OnTitleChanging(string value);
+    partial void OnTitleChanged();
+    partial void OnTitleOfCourtesyChanging(string value);
+    partial void OnTitleOfCourtesyChanged();
+    partial void OnBirthDateChanging(System.Nullable<System.DateTime> value);
+    partial void OnBirthDateChanged();
+    partial void OnHireDateChanging(System.Nullable<System.DateTime> value);
+    partial void OnHireDateChanged();
+    partial void OnAddressChanging(string value);
+    partial void OnAddressChanged();
+    partial void OnCityChanging(string value);
+    partial void OnCityChanged();
+    partial void OnRegionChanging(string value);
+    partial void OnRegionChanged();
+    partial void OnPostalCodeChanging(string value);
+    partial void OnPostalCodeChanged();
+    partial void OnCountryChanging(string value);
+    partial void OnCountryChanged();
+    partial void OnHomePhoneChanging(string value);
+    partial void OnHomePhoneChanged();
+    partial void OnExtensionChanging(string value);
+    partial void OnExtensionChanged();
+    partial void OnPhotoChanging(System.Data.Linq.Binary value);
+    partial void OnPhotoChanged();
+    partial void OnNotesChanging(string value);
+    partial void OnNotesChanged();
+    partial void OnReportsToChanging(System.Nullable<int> value);
+    partial void OnReportsToChanged();
+    partial void OnPhotoPathChanging(string value);
+    partial void OnPhotoPathChanged();
+    #endregion
+		
+		public Employee()
+		{
+			this._Employees = new EntitySet<Employee>(new Action<Employee>(this.attach_Employees), new Action<Employee>(this.detach_Employees));
+			this._EmployeeTerritories = new EntitySet<EmployeeTerritory>(new Action<EmployeeTerritory>(this.attach_EmployeeTerritories), new Action<EmployeeTerritory>(this.detach_EmployeeTerritories));
+			this._Orders = new EntitySet<Order>(new Action<Order>(this.attach_Orders), new Action<Order>(this.detach_Orders));
+			this._Employee1 = default(EntityRef<Employee>);
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmployeeID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+		public int EmployeeID
+		{
+			get
+			{
+				return this._EmployeeID;
+			}
+			set
+			{
+				if ((this._EmployeeID != value))
+				{
+					this.OnEmployeeIDChanging(value);
+					this.SendPropertyChanging();
+					this._EmployeeID = value;
+					this.SendPropertyChanged("EmployeeID");
+					this.OnEmployeeIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_LastName", DbType="NVarChar(20) NOT NULL", CanBeNull=false)]
+		public string LastName
+		{
+			get
+			{
+				return this._LastName;
+			}
+			set
+			{
+				if ((this._LastName != value))
+				{
+					this.OnLastNameChanging(value);
+					this.SendPropertyChanging();
+					this._LastName = value;
+					this.SendPropertyChanged("LastName");
+					this.OnLastNameChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FirstName", DbType="NVarChar(10) NOT NULL", CanBeNull=false)]
+		public string FirstName
+		{
+			get
+			{
+				return this._FirstName;
+			}
+			set
+			{
+				if ((this._FirstName != value))
+				{
+					this.OnFirstNameChanging(value);
+					this.SendPropertyChanging();
+					this._FirstName = value;
+					this.SendPropertyChanged("FirstName");
+					this.OnFirstNameChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Title", DbType="NVarChar(30)")]
+		public string Title
+		{
+			get
+			{
+				return this._Title;
+			}
+			set
+			{
+				if ((this._Title != value))
+				{
+					this.OnTitleChanging(value);
+					this.SendPropertyChanging();
+					this._Title = value;
+					this.SendPropertyChanged("Title");
+					this.OnTitleChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_TitleOfCourtesy", DbType="NVarChar(25)")]
+		public string TitleOfCourtesy
+		{
+			get
+			{
+				return this._TitleOfCourtesy;
+			}
+			set
+			{
+				if ((this._TitleOfCourtesy != value))
+				{
+					this.OnTitleOfCourtesyChanging(value);
+					this.SendPropertyChanging();
+					this._TitleOfCourtesy = value;
+					this.SendPropertyChanged("TitleOfCourtesy");
+					this.OnTitleOfCourtesyChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_BirthDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> BirthDate
+		{
+			get
+			{
+				return this._BirthDate;
+			}
+			set
+			{
+				if ((this._BirthDate != value))
+				{
+					this.OnBirthDateChanging(value);
+					this.SendPropertyChanging();
+					this._BirthDate = value;
+					this.SendPropertyChanged("BirthDate");
+					this.OnBirthDateChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_HireDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> HireDate
+		{
+			get
+			{
+				return this._HireDate;
+			}
+			set
+			{
+				if ((this._HireDate != value))
+				{
+					this.OnHireDateChanging(value);
+					this.SendPropertyChanging();
+					this._HireDate = value;
+					this.SendPropertyChanged("HireDate");
+					this.OnHireDateChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Address", DbType="NVarChar(60)")]
+		public string Address
+		{
+			get
+			{
+				return this._Address;
+			}
+			set
+			{
+				if ((this._Address != value))
+				{
+					this.OnAddressChanging(value);
+					this.SendPropertyChanging();
+					this._Address = value;
+					this.SendPropertyChanged("Address");
+					this.OnAddressChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_City", DbType="NVarChar(15)")]
+		public string City
+		{
+			get
+			{
+				return this._City;
+			}
+			set
+			{
+				if ((this._City != value))
+				{
+					this.OnCityChanging(value);
+					this.SendPropertyChanging();
+					this._City = value;
+					this.SendPropertyChanged("City");
+					this.OnCityChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Region", DbType="NVarChar(15)")]
+		public string Region
+		{
+			get
+			{
+				return this._Region;
+			}
+			set
+			{
+				if ((this._Region != value))
+				{
+					this.OnRegionChanging(value);
+					this.SendPropertyChanging();
+					this._Region = value;
+					this.SendPropertyChanged("Region");
+					this.OnRegionChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PostalCode", DbType="NVarChar(10)")]
+		public string PostalCode
+		{
+			get
+			{
+				return this._PostalCode;
+			}
+			set
+			{
+				if ((this._PostalCode != value))
+				{
+					this.OnPostalCodeChanging(value);
+					this.SendPropertyChanging();
+					this._PostalCode = value;
+					this.SendPropertyChanged("PostalCode");
+					this.OnPostalCodeChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Country", DbType="NVarChar(15)")]
+		public string Country
+		{
+			get
+			{
+				return this._Country;
+			}
+			set
+			{
+				if ((this._Country != value))
+				{
+					this.OnCountryChanging(value);
+					this.SendPropertyChanging();
+					this._Country = value;
+					this.SendPropertyChanged("Country");
+					this.OnCountryChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_HomePhone", DbType="NVarChar(24)")]
+		public string HomePhone
+		{
+			get
+			{
+				return this._HomePhone;
+			}
+			set
+			{
+				if ((this._HomePhone != value))
+				{
+					this.OnHomePhoneChanging(value);
+					this.SendPropertyChanging();
+					this._HomePhone = value;
+					this.SendPropertyChanged("HomePhone");
+					this.OnHomePhoneChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Extension", DbType="NVarChar(4)")]
+		public string Extension
+		{
+			get
+			{
+				return this._Extension;
+			}
+			set
+			{
+				if ((this._Extension != value))
+				{
+					this.OnExtensionChanging(value);
+					this.SendPropertyChanging();
+					this._Extension = value;
+					this.SendPropertyChanged("Extension");
+					this.OnExtensionChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Photo", DbType="Image", UpdateCheck=UpdateCheck.Never)]
+		public System.Data.Linq.Binary Photo
+		{
+			get
+			{
+				return this._Photo;
+			}
+			set
+			{
+				if ((this._Photo != value))
+				{
+					this.OnPhotoChanging(value);
+					this.SendPropertyChanging();
+					this._Photo = value;
+					this.SendPropertyChanged("Photo");
+					this.OnPhotoChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Notes", DbType="NText", UpdateCheck=UpdateCheck.Never)]
+		public string Notes
+		{
+			get
+			{
+				return this._Notes;
+			}
+			set
+			{
+				if ((this._Notes != value))
+				{
+					this.OnNotesChanging(value);
+					this.SendPropertyChanging();
+					this._Notes = value;
+					this.SendPropertyChanged("Notes");
+					this.OnNotesChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ReportsTo", DbType="Int")]
+		public System.Nullable<int> ReportsTo
+		{
+			get
+			{
+				return this._ReportsTo;
+			}
+			set
+			{
+				if ((this._ReportsTo != value))
+				{
+					if (this._Employee1.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnReportsToChanging(value);
+					this.SendPropertyChanging();
+					this._ReportsTo = value;
+					this.SendPropertyChanged("ReportsTo");
+					this.OnReportsToChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PhotoPath", DbType="NVarChar(255)")]
+		public string PhotoPath
+		{
+			get
+			{
+				return this._PhotoPath;
+			}
+			set
+			{
+				if ((this._PhotoPath != value))
+				{
+					this.OnPhotoPathChanging(value);
+					this.SendPropertyChanging();
+					this._PhotoPath = value;
+					this.SendPropertyChanged("PhotoPath");
+					this.OnPhotoPathChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Employee_Employee", Storage="_Employees", ThisKey="EmployeeID", OtherKey="ReportsTo")]
+		public EntitySet<Employee> Employees
+		{
+			get
+			{
+				return this._Employees;
+			}
+			set
+			{
+				this._Employees.Assign(value);
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Employee_EmployeeTerritory", Storage="_EmployeeTerritories", ThisKey="EmployeeID", OtherKey="EmployeeID")]
+		public EntitySet<EmployeeTerritory> EmployeeTerritories
+		{
+			get
+			{
+				return this._EmployeeTerritories;
+			}
+			set
+			{
+				this._EmployeeTerritories.Assign(value);
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Employee_Order", Storage="_Orders", ThisKey="EmployeeID", OtherKey="EmployeeID")]
+		public EntitySet<Order> Orders
+		{
+			get
+			{
+				return this._Orders;
+			}
+			set
+			{
+				this._Orders.Assign(value);
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Employee_Employee", Storage="_Employee1", ThisKey="ReportsTo", OtherKey="EmployeeID", IsForeignKey=true)]
+		public Employee Employee1
+		{
+			get
+			{
+				return this._Employee1.Entity;
+			}
+			set
+			{
+				Employee previousValue = this._Employee1.Entity;
+				if (((previousValue != value) 
+							|| (this._Employee1.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Employee1.Entity = null;
+						previousValue.Employees.Remove(this);
+					}
+					this._Employee1.Entity = value;
+					if ((value != null))
+					{
+						value.Employees.Add(this);
+						this._ReportsTo = value.EmployeeID;
+					}
+					else
+					{
+						this._ReportsTo = default(Nullable<int>);
+					}
+					this.SendPropertyChanged("Employee1");
+				}
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_Employees(Employee entity)
+		{
+			this.SendPropertyChanging();
+			entity.Employee1 = this;
+		}
+		
+		private void detach_Employees(Employee entity)
+		{
+			this.SendPropertyChanging();
+			entity.Employee1 = null;
+		}
+		
+		private void attach_EmployeeTerritories(EmployeeTerritory entity)
+		{
+			this.SendPropertyChanging();
+			entity.Employee = this;
+		}
+		
+		private void detach_EmployeeTerritories(EmployeeTerritory entity)
+		{
+			this.SendPropertyChanging();
+			entity.Employee = null;
+		}
+		
+		private void attach_Orders(Order entity)
+		{
+			this.SendPropertyChanging();
+			entity.Employee = this;
+		}
+		
+		private void detach_Orders(Order entity)
+		{
+			this.SendPropertyChanging();
+			entity.Employee = null;
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.EmployeeTerritories")]
+	public partial class EmployeeTerritory : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private int _EmployeeID;
+		
+		private string _TerritoryID;
+		
+		private EntityRef<Employee> _Employee;
+		
+		private EntityRef<Territory> _Territory;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnEmployeeIDChanging(int value);
+    partial void OnEmployeeIDChanged();
+    partial void OnTerritoryIDChanging(string value);
+    partial void OnTerritoryIDChanged();
+    #endregion
+		
+		public EmployeeTerritory()
+		{
+			this._Employee = default(EntityRef<Employee>);
+			this._Territory = default(EntityRef<Territory>);
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmployeeID", DbType="Int NOT NULL", IsPrimaryKey=true)]
+		public int EmployeeID
+		{
+			get
+			{
+				return this._EmployeeID;
+			}
+			set
+			{
+				if ((this._EmployeeID != value))
+				{
+					if (this._Employee.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnEmployeeIDChanging(value);
+					this.SendPropertyChanging();
+					this._EmployeeID = value;
+					this.SendPropertyChanged("EmployeeID");
+					this.OnEmployeeIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_TerritoryID", DbType="NVarChar(20) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]
+		public string TerritoryID
+		{
+			get
+			{
+				return this._TerritoryID;
+			}
+			set
+			{
+				if ((this._TerritoryID != value))
+				{
+					if (this._Territory.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnTerritoryIDChanging(value);
+					this.SendPropertyChanging();
+					this._TerritoryID = value;
+					this.SendPropertyChanged("TerritoryID");
+					this.OnTerritoryIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Employee_EmployeeTerritory", Storage="_Employee", ThisKey="EmployeeID", OtherKey="EmployeeID", IsForeignKey=true)]
+		public Employee Employee
+		{
+			get
+			{
+				return this._Employee.Entity;
+			}
+			set
+			{
+				Employee previousValue = this._Employee.Entity;
+				if (((previousValue != value) 
+							|| (this._Employee.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Employee.Entity = null;
+						previousValue.EmployeeTerritories.Remove(this);
+					}
+					this._Employee.Entity = value;
+					if ((value != null))
+					{
+						value.EmployeeTerritories.Add(this);
+						this._EmployeeID = value.EmployeeID;
+					}
+					else
+					{
+						this._EmployeeID = default(int);
+					}
+					this.SendPropertyChanged("Employee");
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Territory_EmployeeTerritory", Storage="_Territory", ThisKey="TerritoryID", OtherKey="TerritoryID", IsForeignKey=true)]
+		public Territory Territory
+		{
+			get
+			{
+				return this._Territory.Entity;
+			}
+			set
+			{
+				Territory previousValue = this._Territory.Entity;
+				if (((previousValue != value) 
+							|| (this._Territory.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Territory.Entity = null;
+						previousValue.EmployeeTerritories.Remove(this);
+					}
+					this._Territory.Entity = value;
+					if ((value != null))
+					{
+						value.EmployeeTerritories.Add(this);
+						this._TerritoryID = value.TerritoryID;
+					}
+					else
+					{
+						this._TerritoryID = default(string);
+					}
+					this.SendPropertyChanged("Territory");
+				}
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Order Details]")]
+	public partial class Order_Detail : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private int _OrderID;
+		
+		private int _ProductID;
+		
+		private decimal _UnitPrice;
+		
+		private short _Quantity;
+		
+		private float _Discount;
+		
+		private EntityRef<Order> _Order;
+		
+		private EntityRef<Product> _Product;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnOrderIDChanging(int value);
+    partial void OnOrderIDChanged();
+    partial void OnProductIDChanging(int value);
+    partial void OnProductIDChanged();
+    partial void OnUnitPriceChanging(decimal value);
+    partial void OnUnitPriceChanged();
+    partial void OnQuantityChanging(short value);
+    partial void OnQuantityChanged();
+    partial void OnDiscountChanging(float value);
+    partial void OnDiscountChanged();
+    #endregion
+		
+		public Order_Detail()
+		{
+			this._Order = default(EntityRef<Order>);
+			this._Product = default(EntityRef<Product>);
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL", IsPrimaryKey=true)]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					if (this._Order.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnOrderIDChanging(value);
+					this.SendPropertyChanging();
+					this._OrderID = value;
+					this.SendPropertyChanged("OrderID");
+					this.OnOrderIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductID", DbType="Int NOT NULL", IsPrimaryKey=true)]
+		public int ProductID
+		{
+			get
+			{
+				return this._ProductID;
+			}
+			set
+			{
+				if ((this._ProductID != value))
+				{
+					if (this._Product.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnProductIDChanging(value);
+					this.SendPropertyChanging();
+					this._ProductID = value;
+					this.SendPropertyChanged("ProductID");
+					this.OnProductIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitPrice", DbType="Money NOT NULL")]
+		public decimal UnitPrice
+		{
+			get
+			{
+				return this._UnitPrice;
+			}
+			set
+			{
+				if ((this._UnitPrice != value))
+				{
+					this.OnUnitPriceChanging(value);
+					this.SendPropertyChanging();
+					this._UnitPrice = value;
+					this.SendPropertyChanged("UnitPrice");
+					this.OnUnitPriceChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Quantity", DbType="SmallInt NOT NULL")]
+		public short Quantity
+		{
+			get
+			{
+				return this._Quantity;
+			}
+			set
+			{
+				if ((this._Quantity != value))
+				{
+					this.OnQuantityChanging(value);
+					this.SendPropertyChanging();
+					this._Quantity = value;
+					this.SendPropertyChanged("Quantity");
+					this.OnQuantityChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Discount", DbType="Real NOT NULL")]
+		public float Discount
+		{
+			get
+			{
+				return this._Discount;
+			}
+			set
+			{
+				if ((this._Discount != value))
+				{
+					this.OnDiscountChanging(value);
+					this.SendPropertyChanging();
+					this._Discount = value;
+					this.SendPropertyChanged("Discount");
+					this.OnDiscountChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Order_Order_Detail", Storage="_Order", ThisKey="OrderID", OtherKey="OrderID", IsForeignKey=true)]
+		public Order Order
+		{
+			get
+			{
+				return this._Order.Entity;
+			}
+			set
+			{
+				Order previousValue = this._Order.Entity;
+				if (((previousValue != value) 
+							|| (this._Order.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Order.Entity = null;
+						previousValue.Order_Details.Remove(this);
+					}
+					this._Order.Entity = value;
+					if ((value != null))
+					{
+						value.Order_Details.Add(this);
+						this._OrderID = value.OrderID;
+					}
+					else
+					{
+						this._OrderID = default(int);
+					}
+					this.SendPropertyChanged("Order");
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Product_Order_Detail", Storage="_Product", ThisKey="ProductID", OtherKey="ProductID", IsForeignKey=true)]
+		public Product Product
+		{
+			get
+			{
+				return this._Product.Entity;
+			}
+			set
+			{
+				Product previousValue = this._Product.Entity;
+				if (((previousValue != value) 
+							|| (this._Product.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Product.Entity = null;
+						previousValue.Order_Details.Remove(this);
+					}
+					this._Product.Entity = value;
+					if ((value != null))
+					{
+						value.Order_Details.Add(this);
+						this._ProductID = value.ProductID;
+					}
+					else
+					{
+						this._ProductID = default(int);
+					}
+					this.SendPropertyChanged("Product");
+				}
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Orders")]
+	public partial class Order : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private int _OrderID;
+		
+		private string _CustomerID;
+		
+		private System.Nullable<int> _EmployeeID;
+		
+		private System.Nullable<System.DateTime> _OrderDate;
+		
+		private System.Nullable<System.DateTime> _RequiredDate;
+		
+		private System.Nullable<System.DateTime> _ShippedDate;
+		
+		private System.Nullable<int> _ShipVia;
+		
+		private System.Nullable<decimal> _Freight;
+		
+		private string _ShipName;
+		
+		private string _ShipAddress;
+		
+		private string _ShipCity;
+		
+		private string _ShipRegion;
+		
+		private string _ShipPostalCode;
+		
+		private string _ShipCountry;
+		
+		private EntitySet<Order_Detail> _Order_Details;
+		
+		private EntityRef<Customer> _Customer;
+		
+		private EntityRef<Employee> _Employee;
+		
+		private EntityRef<Shipper> _Shipper;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnOrderIDChanging(int value);
+    partial void OnOrderIDChanged();
+    partial void OnCustomerIDChanging(string value);
+    partial void OnCustomerIDChanged();
+    partial void OnEmployeeIDChanging(System.Nullable<int> value);
+    partial void OnEmployeeIDChanged();
+    partial void OnOrderDateChanging(System.Nullable<System.DateTime> value);
+    partial void OnOrderDateChanged();
+    partial void OnRequiredDateChanging(System.Nullable<System.DateTime> value);
+    partial void OnRequiredDateChanged();
+    partial void OnShippedDateChanging(System.Nullable<System.DateTime> value);
+    partial void OnShippedDateChanged();
+    partial void OnShipViaChanging(System.Nullable<int> value);
+    partial void OnShipViaChanged();
+    partial void OnFreightChanging(System.Nullable<decimal> value);
+    partial void OnFreightChanged();
+    partial void OnShipNameChanging(string value);
+    partial void OnShipNameChanged();
+    partial void OnShipAddressChanging(string value);
+    partial void OnShipAddressChanged();
+    partial void OnShipCityChanging(string value);
+    partial void OnShipCityChanged();
+    partial void OnShipRegionChanging(string value);
+    partial void OnShipRegionChanged();
+    partial void OnShipPostalCodeChanging(string value);
+    partial void OnShipPostalCodeChanged();
+    partial void OnShipCountryChanging(string value);
+    partial void OnShipCountryChanged();
+    #endregion
+		
+		public Order()
+		{
+			this._Order_Details = new EntitySet<Order_Detail>(new Action<Order_Detail>(this.attach_Order_Details), new Action<Order_Detail>(this.detach_Order_Details));
+			this._Customer = default(EntityRef<Customer>);
+			this._Employee = default(EntityRef<Employee>);
+			this._Shipper = default(EntityRef<Shipper>);
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this.OnOrderIDChanging(value);
+					this.SendPropertyChanging();
+					this._OrderID = value;
+					this.SendPropertyChanged("OrderID");
+					this.OnOrderIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CustomerID", DbType="NChar(5)")]
+		public string CustomerID
+		{
+			get
+			{
+				return this._CustomerID;
+			}
+			set
+			{
+				if ((this._CustomerID != value))
+				{
+					if (this._Customer.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnCustomerIDChanging(value);
+					this.SendPropertyChanging();
+					this._CustomerID = value;
+					this.SendPropertyChanged("CustomerID");
+					this.OnCustomerIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmployeeID", DbType="Int")]
+		public System.Nullable<int> EmployeeID
+		{
+			get
+			{
+				return this._EmployeeID;
+			}
+			set
+			{
+				if ((this._EmployeeID != value))
+				{
+					if (this._Employee.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnEmployeeIDChanging(value);
+					this.SendPropertyChanging();
+					this._EmployeeID = value;
+					this.SendPropertyChanged("EmployeeID");
+					this.OnEmployeeIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> OrderDate
+		{
+			get
+			{
+				return this._OrderDate;
+			}
+			set
+			{
+				if ((this._OrderDate != value))
+				{
+					this.OnOrderDateChanging(value);
+					this.SendPropertyChanging();
+					this._OrderDate = value;
+					this.SendPropertyChanged("OrderDate");
+					this.OnOrderDateChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RequiredDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> RequiredDate
+		{
+			get
+			{
+				return this._RequiredDate;
+			}
+			set
+			{
+				if ((this._RequiredDate != value))
+				{
+					this.OnRequiredDateChanging(value);
+					this.SendPropertyChanging();
+					this._RequiredDate = value;
+					this.SendPropertyChanged("RequiredDate");
+					this.OnRequiredDateChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShippedDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> ShippedDate
+		{
+			get
+			{
+				return this._ShippedDate;
+			}
+			set
+			{
+				if ((this._ShippedDate != value))
+				{
+					this.OnShippedDateChanging(value);
+					this.SendPropertyChanging();
+					this._ShippedDate = value;
+					this.SendPropertyChanged("ShippedDate");
+					this.OnShippedDateChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipVia", DbType="Int")]
+		public System.Nullable<int> ShipVia
+		{
+			get
+			{
+				return this._ShipVia;
+			}
+			set
+			{
+				if ((this._ShipVia != value))
+				{
+					if (this._Shipper.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnShipViaChanging(value);
+					this.SendPropertyChanging();
+					this._ShipVia = value;
+					this.SendPropertyChanged("ShipVia");
+					this.OnShipViaChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Freight", DbType="Money")]
+		public System.Nullable<decimal> Freight
+		{
+			get
+			{
+				return this._Freight;
+			}
+			set
+			{
+				if ((this._Freight != value))
+				{
+					this.OnFreightChanging(value);
+					this.SendPropertyChanging();
+					this._Freight = value;
+					this.SendPropertyChanged("Freight");
+					this.OnFreightChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipName", DbType="NVarChar(40)")]
+		public string ShipName
+		{
+			get
+			{
+				return this._ShipName;
+			}
+			set
+			{
+				if ((this._ShipName != value))
+				{
+					this.OnShipNameChanging(value);
+					this.SendPropertyChanging();
+					this._ShipName = value;
+					this.SendPropertyChanged("ShipName");
+					this.OnShipNameChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipAddress", DbType="NVarChar(60)")]
+		public string ShipAddress
+		{
+			get
+			{
+				return this._ShipAddress;
+			}
+			set
+			{
+				if ((this._ShipAddress != value))
+				{
+					this.OnShipAddressChanging(value);
+					this.SendPropertyChanging();
+					this._ShipAddress = value;
+					this.SendPropertyChanged("ShipAddress");
+					this.OnShipAddressChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipCity", DbType="NVarChar(15)")]
+		public string ShipCity
+		{
+			get
+			{
+				return this._ShipCity;
+			}
+			set
+			{
+				if ((this._ShipCity != value))
+				{
+					this.OnShipCityChanging(value);
+					this.SendPropertyChanging();
+					this._ShipCity = value;
+					this.SendPropertyChanged("ShipCity");
+					this.OnShipCityChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipRegion", DbType="NVarChar(15)")]
+		public string ShipRegion
+		{
+			get
+			{
+				return this._ShipRegion;
+			}
+			set
+			{
+				if ((this._ShipRegion != value))
+				{
+					this.OnShipRegionChanging(value);
+					this.SendPropertyChanging();
+					this._ShipRegion = value;
+					this.SendPropertyChanged("ShipRegion");
+					this.OnShipRegionChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipPostalCode", DbType="NVarChar(10)")]
+		public string ShipPostalCode
+		{
+			get
+			{
+				return this._ShipPostalCode;
+			}
+			set
+			{
+				if ((this._ShipPostalCode != value))
+				{
+					this.OnShipPostalCodeChanging(value);
+					this.SendPropertyChanging();
+					this._ShipPostalCode = value;
+					this.SendPropertyChanged("ShipPostalCode");
+					this.OnShipPostalCodeChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipCountry", DbType="NVarChar(15)")]
+		public string ShipCountry
+		{
+			get
+			{
+				return this._ShipCountry;
+			}
+			set
+			{
+				if ((this._ShipCountry != value))
+				{
+					this.OnShipCountryChanging(value);
+					this.SendPropertyChanging();
+					this._ShipCountry = value;
+					this.SendPropertyChanged("ShipCountry");
+					this.OnShipCountryChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Order_Order_Detail", Storage="_Order_Details", ThisKey="OrderID", OtherKey="OrderID")]
+		public EntitySet<Order_Detail> Order_Details
+		{
+			get
+			{
+				return this._Order_Details;
+			}
+			set
+			{
+				this._Order_Details.Assign(value);
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Customer_Order", Storage="_Customer", ThisKey="CustomerID", OtherKey="CustomerID", IsForeignKey=true)]
+		public Customer Customer
+		{
+			get
+			{
+				return this._Customer.Entity;
+			}
+			set
+			{
+				Customer previousValue = this._Customer.Entity;
+				if (((previousValue != value) 
+							|| (this._Customer.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Customer.Entity = null;
+						previousValue.Orders.Remove(this);
+					}
+					this._Customer.Entity = value;
+					if ((value != null))
+					{
+						value.Orders.Add(this);
+						this._CustomerID = value.CustomerID;
+					}
+					else
+					{
+						this._CustomerID = default(string);
+					}
+					this.SendPropertyChanged("Customer");
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Employee_Order", Storage="_Employee", ThisKey="EmployeeID", OtherKey="EmployeeID", IsForeignKey=true)]
+		public Employee Employee
+		{
+			get
+			{
+				return this._Employee.Entity;
+			}
+			set
+			{
+				Employee previousValue = this._Employee.Entity;
+				if (((previousValue != value) 
+							|| (this._Employee.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Employee.Entity = null;
+						previousValue.Orders.Remove(this);
+					}
+					this._Employee.Entity = value;
+					if ((value != null))
+					{
+						value.Orders.Add(this);
+						this._EmployeeID = value.EmployeeID;
+					}
+					else
+					{
+						this._EmployeeID = default(Nullable<int>);
+					}
+					this.SendPropertyChanged("Employee");
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Shipper_Order", Storage="_Shipper", ThisKey="ShipVia", OtherKey="ShipperID", IsForeignKey=true)]
+		public Shipper Shipper
+		{
+			get
+			{
+				return this._Shipper.Entity;
+			}
+			set
+			{
+				Shipper previousValue = this._Shipper.Entity;
+				if (((previousValue != value) 
+							|| (this._Shipper.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Shipper.Entity = null;
+						previousValue.Orders.Remove(this);
+					}
+					this._Shipper.Entity = value;
+					if ((value != null))
+					{
+						value.Orders.Add(this);
+						this._ShipVia = value.ShipperID;
+					}
+					else
+					{
+						this._ShipVia = default(Nullable<int>);
+					}
+					this.SendPropertyChanged("Shipper");
+				}
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_Order_Details(Order_Detail entity)
+		{
+			this.SendPropertyChanging();
+			entity.Order = this;
+		}
+		
+		private void detach_Order_Details(Order_Detail entity)
+		{
+			this.SendPropertyChanging();
+			entity.Order = null;
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Products")]
+	public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private int _ProductID;
+		
+		private string _ProductName;
+		
+		private System.Nullable<int> _SupplierID;
+		
+		private System.Nullable<int> _CategoryID;
+		
+		private string _QuantityPerUnit;
+		
+		private System.Nullable<decimal> _UnitPrice;
+		
+		private System.Nullable<short> _UnitsInStock;
+		
+		private System.Nullable<short> _UnitsOnOrder;
+		
+		private System.Nullable<short> _ReorderLevel;
+		
+		private bool _Discontinued;
+		
+		private EntitySet<Order_Detail> _Order_Details;
+		
+		private EntityRef<Category> _Category;
+		
+		private EntityRef<Supplier> _Supplier;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnProductIDChanging(int value);
+    partial void OnProductIDChanged();
+    partial void OnProductNameChanging(string value);
+    partial void OnProductNameChanged();
+    partial void OnSupplierIDChanging(System.Nullable<int> value);
+    partial void OnSupplierIDChanged();
+    partial void OnCategoryIDChanging(System.Nullable<int> value);
+    partial void OnCategoryIDChanged();
+    partial void OnQuantityPerUnitChanging(string value);
+    partial void OnQuantityPerUnitChanged();
+    partial void OnUnitPriceChanging(System.Nullable<decimal> value);
+    partial void OnUnitPriceChanged();
+    partial void OnUnitsInStockChanging(System.Nullable<short> value);
+    partial void OnUnitsInStockChanged();
+    partial void OnUnitsOnOrderChanging(System.Nullable<short> value);
+    partial void OnUnitsOnOrderChanged();
+    partial void OnReorderLevelChanging(System.Nullable<short> value);
+    partial void OnReorderLevelChanged();
+    partial void OnDiscontinuedChanging(bool value);
+    partial void OnDiscontinuedChanged();
+    #endregion
+		
+		public Product()
+		{
+			this._Order_Details = new EntitySet<Order_Detail>(new Action<Order_Detail>(this.attach_Order_Details), new Action<Order_Detail>(this.detach_Order_Details));
+			this._Category = default(EntityRef<Category>);
+			this._Supplier = default(EntityRef<Supplier>);
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+		public int ProductID
+		{
+			get
+			{
+				return this._ProductID;
+			}
+			set
+			{
+				if ((this._ProductID != value))
+				{
+					this.OnProductIDChanging(value);
+					this.SendPropertyChanging();
+					this._ProductID = value;
+					this.SendPropertyChanged("ProductID");
+					this.OnProductIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this.OnProductNameChanging(value);
+					this.SendPropertyChanging();
+					this._ProductName = value;
+					this.SendPropertyChanged("ProductName");
+					this.OnProductNameChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SupplierID", DbType="Int")]
+		public System.Nullable<int> SupplierID
+		{
+			get
+			{
+				return this._SupplierID;
+			}
+			set
+			{
+				if ((this._SupplierID != value))
+				{
+					if (this._Supplier.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnSupplierIDChanging(value);
+					this.SendPropertyChanging();
+					this._SupplierID = value;
+					this.SendPropertyChanged("SupplierID");
+					this.OnSupplierIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategoryID", DbType="Int")]
+		public System.Nullable<int> CategoryID
+		{
+			get
+			{
+				return this._CategoryID;
+			}
+			set
+			{
+				if ((this._CategoryID != value))
+				{
+					if (this._Category.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnCategoryIDChanging(value);
+					this.SendPropertyChanging();
+					this._CategoryID = value;
+					this.SendPropertyChanged("CategoryID");
+					this.OnCategoryIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_QuantityPerUnit", DbType="NVarChar(20)")]
+		public string QuantityPerUnit
+		{
+			get
+			{
+				return this._QuantityPerUnit;
+			}
+			set
+			{
+				if ((this._QuantityPerUnit != value))
+				{
+					this.OnQuantityPerUnitChanging(value);
+					this.SendPropertyChanging();
+					this._QuantityPerUnit = value;
+					this.SendPropertyChanged("QuantityPerUnit");
+					this.OnQuantityPerUnitChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitPrice", DbType="Money")]
+		public System.Nullable<decimal> UnitPrice
+		{
+			get
+			{
+				return this._UnitPrice;
+			}
+			set
+			{
+				if ((this._UnitPrice != value))
+				{
+					this.OnUnitPriceChanging(value);
+					this.SendPropertyChanging();
+					this._UnitPrice = value;
+					this.SendPropertyChanged("UnitPrice");
+					this.OnUnitPriceChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitsInStock", DbType="SmallInt")]
+		public System.Nullable<short> UnitsInStock
+		{
+			get
+			{
+				return this._UnitsInStock;
+			}
+			set
+			{
+				if ((this._UnitsInStock != value))
+				{
+					this.OnUnitsInStockChanging(value);
+					this.SendPropertyChanging();
+					this._UnitsInStock = value;
+					this.SendPropertyChanged("UnitsInStock");
+					this.OnUnitsInStockChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitsOnOrder", DbType="SmallInt")]
+		public System.Nullable<short> UnitsOnOrder
+		{
+			get
+			{
+				return this._UnitsOnOrder;
+			}
+			set
+			{
+				if ((this._UnitsOnOrder != value))
+				{
+					this.OnUnitsOnOrderChanging(value);
+					this.SendPropertyChanging();
+					this._UnitsOnOrder = value;
+					this.SendPropertyChanged("UnitsOnOrder");
+					this.OnUnitsOnOrderChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ReorderLevel", DbType="SmallInt")]
+		public System.Nullable<short> ReorderLevel
+		{
+			get
+			{
+				return this._ReorderLevel;
+			}
+			set
+			{
+				if ((this._ReorderLevel != value))
+				{
+					this.OnReorderLevelChanging(value);
+					this.SendPropertyChanging();
+					this._ReorderLevel = value;
+					this.SendPropertyChanged("ReorderLevel");
+					this.OnReorderLevelChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Discontinued", DbType="Bit NOT NULL")]
+		public bool Discontinued
+		{
+			get
+			{
+				return this._Discontinued;
+			}
+			set
+			{
+				if ((this._Discontinued != value))
+				{
+					this.OnDiscontinuedChanging(value);
+					this.SendPropertyChanging();
+					this._Discontinued = value;
+					this.SendPropertyChanged("Discontinued");
+					this.OnDiscontinuedChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Product_Order_Detail", Storage="_Order_Details", ThisKey="ProductID", OtherKey="ProductID")]
+		public EntitySet<Order_Detail> Order_Details
+		{
+			get
+			{
+				return this._Order_Details;
+			}
+			set
+			{
+				this._Order_Details.Assign(value);
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Category_Product", Storage="_Category", ThisKey="CategoryID", OtherKey="CategoryID", IsForeignKey=true)]
+		public Category Category
+		{
+			get
+			{
+				return this._Category.Entity;
+			}
+			set
+			{
+				Category previousValue = this._Category.Entity;
+				if (((previousValue != value) 
+							|| (this._Category.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Category.Entity = null;
+						previousValue.Products.Remove(this);
+					}
+					this._Category.Entity = value;
+					if ((value != null))
+					{
+						value.Products.Add(this);
+						this._CategoryID = value.CategoryID;
+					}
+					else
+					{
+						this._CategoryID = default(Nullable<int>);
+					}
+					this.SendPropertyChanged("Category");
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Supplier_Product", Storage="_Supplier", ThisKey="SupplierID", OtherKey="SupplierID", IsForeignKey=true)]
+		public Supplier Supplier
+		{
+			get
+			{
+				return this._Supplier.Entity;
+			}
+			set
+			{
+				Supplier previousValue = this._Supplier.Entity;
+				if (((previousValue != value) 
+							|| (this._Supplier.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Supplier.Entity = null;
+						previousValue.Products.Remove(this);
+					}
+					this._Supplier.Entity = value;
+					if ((value != null))
+					{
+						value.Products.Add(this);
+						this._SupplierID = value.SupplierID;
+					}
+					else
+					{
+						this._SupplierID = default(Nullable<int>);
+					}
+					this.SendPropertyChanged("Supplier");
+				}
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_Order_Details(Order_Detail entity)
+		{
+			this.SendPropertyChanging();
+			entity.Product = this;
+		}
+		
+		private void detach_Order_Details(Order_Detail entity)
+		{
+			this.SendPropertyChanging();
+			entity.Product = null;
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Region")]
+	public partial class Region : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private int _RegionID;
+		
+		private string _RegionDescription;
+		
+		private EntitySet<Territory> _Territories;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnRegionIDChanging(int value);
+    partial void OnRegionIDChanged();
+    partial void OnRegionDescriptionChanging(string value);
+    partial void OnRegionDescriptionChanged();
+    #endregion
+		
+		public Region()
+		{
+			this._Territories = new EntitySet<Territory>(new Action<Territory>(this.attach_Territories), new Action<Territory>(this.detach_Territories));
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RegionID", DbType="Int NOT NULL", IsPrimaryKey=true)]
+		public int RegionID
+		{
+			get
+			{
+				return this._RegionID;
+			}
+			set
+			{
+				if ((this._RegionID != value))
+				{
+					this.OnRegionIDChanging(value);
+					this.SendPropertyChanging();
+					this._RegionID = value;
+					this.SendPropertyChanged("RegionID");
+					this.OnRegionIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RegionDescription", DbType="NChar(50) NOT NULL", CanBeNull=false)]
+		public string RegionDescription
+		{
+			get
+			{
+				return this._RegionDescription;
+			}
+			set
+			{
+				if ((this._RegionDescription != value))
+				{
+					this.OnRegionDescriptionChanging(value);
+					this.SendPropertyChanging();
+					this._RegionDescription = value;
+					this.SendPropertyChanged("RegionDescription");
+					this.OnRegionDescriptionChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Region_Territory", Storage="_Territories", ThisKey="RegionID", OtherKey="RegionID")]
+		public EntitySet<Territory> Territories
+		{
+			get
+			{
+				return this._Territories;
+			}
+			set
+			{
+				this._Territories.Assign(value);
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_Territories(Territory entity)
+		{
+			this.SendPropertyChanging();
+			entity.Region = this;
+		}
+		
+		private void detach_Territories(Territory entity)
+		{
+			this.SendPropertyChanging();
+			entity.Region = null;
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Shippers")]
+	public partial class Shipper : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private int _ShipperID;
+		
+		private string _CompanyName;
+		
+		private string _Phone;
+		
+		private EntitySet<Order> _Orders;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnShipperIDChanging(int value);
+    partial void OnShipperIDChanged();
+    partial void OnCompanyNameChanging(string value);
+    partial void OnCompanyNameChanged();
+    partial void OnPhoneChanging(string value);
+    partial void OnPhoneChanged();
+    #endregion
+		
+		public Shipper()
+		{
+			this._Orders = new EntitySet<Order>(new Action<Order>(this.attach_Orders), new Action<Order>(this.detach_Orders));
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipperID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+		public int ShipperID
+		{
+			get
+			{
+				return this._ShipperID;
+			}
+			set
+			{
+				if ((this._ShipperID != value))
+				{
+					this.OnShipperIDChanging(value);
+					this.SendPropertyChanging();
+					this._ShipperID = value;
+					this.SendPropertyChanged("ShipperID");
+					this.OnShipperIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string CompanyName
+		{
+			get
+			{
+				return this._CompanyName;
+			}
+			set
+			{
+				if ((this._CompanyName != value))
+				{
+					this.OnCompanyNameChanging(value);
+					this.SendPropertyChanging();
+					this._CompanyName = value;
+					this.SendPropertyChanged("CompanyName");
+					this.OnCompanyNameChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Phone", DbType="NVarChar(24)")]
+		public string Phone
+		{
+			get
+			{
+				return this._Phone;
+			}
+			set
+			{
+				if ((this._Phone != value))
+				{
+					this.OnPhoneChanging(value);
+					this.SendPropertyChanging();
+					this._Phone = value;
+					this.SendPropertyChanged("Phone");
+					this.OnPhoneChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Shipper_Order", Storage="_Orders", ThisKey="ShipperID", OtherKey="ShipVia")]
+		public EntitySet<Order> Orders
+		{
+			get
+			{
+				return this._Orders;
+			}
+			set
+			{
+				this._Orders.Assign(value);
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_Orders(Order entity)
+		{
+			this.SendPropertyChanging();
+			entity.Shipper = this;
+		}
+		
+		private void detach_Orders(Order entity)
+		{
+			this.SendPropertyChanging();
+			entity.Shipper = null;
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Suppliers")]
+	public partial class Supplier : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private int _SupplierID;
+		
+		private string _CompanyName;
+		
+		private string _ContactName;
+		
+		private string _ContactTitle;
+		
+		private string _Address;
+		
+		private string _City;
+		
+		private string _Region;
+		
+		private string _PostalCode;
+		
+		private string _Country;
+		
+		private string _Phone;
+		
+		private string _Fax;
+		
+		private string _HomePage;
+		
+		private EntitySet<Product> _Products;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnSupplierIDChanging(int value);
+    partial void OnSupplierIDChanged();
+    partial void OnCompanyNameChanging(string value);
+    partial void OnCompanyNameChanged();
+    partial void OnContactNameChanging(string value);
+    partial void OnContactNameChanged();
+    partial void OnContactTitleChanging(string value);
+    partial void OnContactTitleChanged();
+    partial void OnAddressChanging(string value);
+    partial void OnAddressChanged();
+    partial void OnCityChanging(string value);
+    partial void OnCityChanged();
+    partial void OnRegionChanging(string value);
+    partial void OnRegionChanged();
+    partial void OnPostalCodeChanging(string value);
+    partial void OnPostalCodeChanged();
+    partial void OnCountryChanging(string value);
+    partial void OnCountryChanged();
+    partial void OnPhoneChanging(string value);
+    partial void OnPhoneChanged();
+    partial void OnFaxChanging(string value);
+    partial void OnFaxChanged();
+    partial void OnHomePageChanging(string value);
+    partial void OnHomePageChanged();
+    #endregion
+		
+		public Supplier()
+		{
+			this._Products = new EntitySet<Product>(new Action<Product>(this.attach_Products), new Action<Product>(this.detach_Products));
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SupplierID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+		public int SupplierID
+		{
+			get
+			{
+				return this._SupplierID;
+			}
+			set
+			{
+				if ((this._SupplierID != value))
+				{
+					this.OnSupplierIDChanging(value);
+					this.SendPropertyChanging();
+					this._SupplierID = value;
+					this.SendPropertyChanged("SupplierID");
+					this.OnSupplierIDChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string CompanyName
+		{
+			get
+			{
+				return this._CompanyName;
+			}
+			set
+			{
+				if ((this._CompanyName != value))
+				{
+					this.OnCompanyNameChanging(value);
+					this.SendPropertyChanging();
+					this._CompanyName = value;
+					this.SendPropertyChanged("CompanyName");
+					this.OnCompanyNameChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ContactName", DbType="NVarChar(30)")]
+		public string ContactName
+		{
+			get
+			{
+				return this._ContactName;
+			}
+			set
+			{
+				if ((this._ContactName != value))
+				{
+					this.OnContactNameChanging(value);
+					this.SendPropertyChanging();
+					this._ContactName = value;
+					this.SendPropertyChanged("ContactName");
+					this.OnContactNameChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ContactTitle", DbType="NVarChar(30)")]
+		public string ContactTitle
+		{
+			get
+			{
+				return this._ContactTitle;
+			}
+			set
+			{
+				if ((this._ContactTitle != value))
+				{
+					this.OnContactTitleChanging(value);
+					this.SendPropertyChanging();
+					this._ContactTitle = value;
+					this.SendPropertyChanged("ContactTitle");
+					this.OnContactTitleChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Address", DbType="NVarChar(60)")]
+		public string Address
+		{
+			get
+			{
+				return this._Address;
+			}
+			set
+			{
+				if ((this._Address != value))
+				{
+					this.OnAddressChanging(value);
+					this.SendPropertyChanging();
+					this._Address = value;
+					this.SendPropertyChanged("Address");
+					this.OnAddressChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_City", DbType="NVarChar(15)")]
+		public string City
+		{
+			get
+			{
+				return this._City;
+			}
+			set
+			{
+				if ((this._City != value))
+				{
+					this.OnCityChanging(value);
+					this.SendPropertyChanging();
+					this._City = value;
+					this.SendPropertyChanged("City");
+					this.OnCityChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Region", DbType="NVarChar(15)")]
+		public string Region
+		{
+			get
+			{
+				return this._Region;
+			}
+			set
+			{
+				if ((this._Region != value))
+				{
+					this.OnRegionChanging(value);
+					this.SendPropertyChanging();
+					this._Region = value;
+					this.SendPropertyChanged("Region");
+					this.OnRegionChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PostalCode", DbType="NVarChar(10)")]
+		public string PostalCode
+		{
+			get
+			{
+				return this._PostalCode;
+			}
+			set
+			{
+				if ((this._PostalCode != value))
+				{
+					this.OnPostalCodeChanging(value);
+					this.SendPropertyChanging();
+					this._PostalCode = value;
+					this.SendPropertyChanged("PostalCode");
+					this.OnPostalCodeChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Country", DbType="NVarChar(15)")]
+		public string Country
+		{
+			get
+			{
+				return this._Country;
+			}
+			set
+			{
+				if ((this._Country != value))
+				{
+					this.OnCountryChanging(value);
+					this.SendPropertyChanging();
+					this._Country = value;
+					this.SendPropertyChanged("Country");
+					this.OnCountryChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Phone", DbType="NVarChar(24)")]
+		public string Phone
+		{
+			get
+			{
+				return this._Phone;
+			}
+			set
+			{
+				if ((this._Phone != value))
+				{
+					this.OnPhoneChanging(value);
+					this.SendPropertyChanging();
+					this._Phone = value;
+					this.SendPropertyChanged("Phone");
+					this.OnPhoneChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Fax", DbType="NVarChar(24)")]
+		public string Fax
+		{
+			get
+			{
+				return this._Fax;
+			}
+			set
+			{
+				if ((this._Fax != value))
+				{
+					this.OnFaxChanging(value);
+					this.SendPropertyChanging();
+					this._Fax = value;
+					this.SendPropertyChanged("Fax");
+					this.OnFaxChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_HomePage", DbType="NText", UpdateCheck=UpdateCheck.Never)]
+		public string HomePage
+		{
+			get
+			{
+				return this._HomePage;
+			}
+			set
+			{
+				if ((this._HomePage != value))
+				{
+					this.OnHomePageChanging(value);
+					this.SendPropertyChanging();
+					this._HomePage = value;
+					this.SendPropertyChanged("HomePage");
+					this.OnHomePageChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Supplier_Product", Storage="_Products", ThisKey="SupplierID", OtherKey="SupplierID")]
+		public EntitySet<Product> Products
+		{
+			get
+			{
+				return this._Products;
+			}
+			set
+			{
+				this._Products.Assign(value);
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_Products(Product entity)
+		{
+			this.SendPropertyChanging();
+			entity.Supplier = this;
+		}
+		
+		private void detach_Products(Product entity)
+		{
+			this.SendPropertyChanging();
+			entity.Supplier = null;
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Alphabetical list of products]")]
+	public partial class Alphabetical_list_of_product
+	{
+		
+		private int _ProductID;
+		
+		private string _ProductName;
+		
+		private System.Nullable<int> _SupplierID;
+		
+		private System.Nullable<int> _CategoryID;
+		
+		private string _QuantityPerUnit;
+		
+		private System.Nullable<decimal> _UnitPrice;
+		
+		private System.Nullable<short> _UnitsInStock;
+		
+		private System.Nullable<short> _UnitsOnOrder;
+		
+		private System.Nullable<short> _ReorderLevel;
+		
+		private bool _Discontinued;
+		
+		private string _CategoryName;
+		
+		public Alphabetical_list_of_product()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductID", DbType="Int NOT NULL")]
+		public int ProductID
+		{
+			get
+			{
+				return this._ProductID;
+			}
+			set
+			{
+				if ((this._ProductID != value))
+				{
+					this._ProductID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SupplierID", DbType="Int")]
+		public System.Nullable<int> SupplierID
+		{
+			get
+			{
+				return this._SupplierID;
+			}
+			set
+			{
+				if ((this._SupplierID != value))
+				{
+					this._SupplierID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategoryID", DbType="Int")]
+		public System.Nullable<int> CategoryID
+		{
+			get
+			{
+				return this._CategoryID;
+			}
+			set
+			{
+				if ((this._CategoryID != value))
+				{
+					this._CategoryID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_QuantityPerUnit", DbType="NVarChar(20)")]
+		public string QuantityPerUnit
+		{
+			get
+			{
+				return this._QuantityPerUnit;
+			}
+			set
+			{
+				if ((this._QuantityPerUnit != value))
+				{
+					this._QuantityPerUnit = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitPrice", DbType="Money")]
+		public System.Nullable<decimal> UnitPrice
+		{
+			get
+			{
+				return this._UnitPrice;
+			}
+			set
+			{
+				if ((this._UnitPrice != value))
+				{
+					this._UnitPrice = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitsInStock", DbType="SmallInt")]
+		public System.Nullable<short> UnitsInStock
+		{
+			get
+			{
+				return this._UnitsInStock;
+			}
+			set
+			{
+				if ((this._UnitsInStock != value))
+				{
+					this._UnitsInStock = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitsOnOrder", DbType="SmallInt")]
+		public System.Nullable<short> UnitsOnOrder
+		{
+			get
+			{
+				return this._UnitsOnOrder;
+			}
+			set
+			{
+				if ((this._UnitsOnOrder != value))
+				{
+					this._UnitsOnOrder = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ReorderLevel", DbType="SmallInt")]
+		public System.Nullable<short> ReorderLevel
+		{
+			get
+			{
+				return this._ReorderLevel;
+			}
+			set
+			{
+				if ((this._ReorderLevel != value))
+				{
+					this._ReorderLevel = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Discontinued", DbType="Bit NOT NULL")]
+		public bool Discontinued
+		{
+			get
+			{
+				return this._Discontinued;
+			}
+			set
+			{
+				if ((this._Discontinued != value))
+				{
+					this._Discontinued = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategoryName", DbType="NVarChar(15) NOT NULL", CanBeNull=false)]
+		public string CategoryName
+		{
+			get
+			{
+				return this._CategoryName;
+			}
+			set
+			{
+				if ((this._CategoryName != value))
+				{
+					this._CategoryName = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Summary of Sales by Year]")]
+	public partial class Summary_of_Sales_by_Year
+	{
+		
+		private System.Nullable<System.DateTime> _ShippedDate;
+		
+		private int _OrderID;
+		
+		private System.Nullable<decimal> _Subtotal;
+		
+		public Summary_of_Sales_by_Year()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShippedDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> ShippedDate
+		{
+			get
+			{
+				return this._ShippedDate;
+			}
+			set
+			{
+				if ((this._ShippedDate != value))
+				{
+					this._ShippedDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL")]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this._OrderID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Subtotal", DbType="Money")]
+		public System.Nullable<decimal> Subtotal
+		{
+			get
+			{
+				return this._Subtotal;
+			}
+			set
+			{
+				if ((this._Subtotal != value))
+				{
+					this._Subtotal = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Category Sales for 1997]")]
+	public partial class Category_Sales_for_1997
+	{
+		
+		private string _CategoryName;
+		
+		private System.Nullable<decimal> _CategorySales;
+		
+		public Category_Sales_for_1997()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategoryName", DbType="NVarChar(15) NOT NULL", CanBeNull=false)]
+		public string CategoryName
+		{
+			get
+			{
+				return this._CategoryName;
+			}
+			set
+			{
+				if ((this._CategoryName != value))
+				{
+					this._CategoryName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategorySales", DbType="Money")]
+		public System.Nullable<decimal> CategorySales
+		{
+			get
+			{
+				return this._CategorySales;
+			}
+			set
+			{
+				if ((this._CategorySales != value))
+				{
+					this._CategorySales = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Current Product List]")]
+	public partial class Current_Product_List
+	{
+		
+		private int _ProductID;
+		
+		private string _ProductName;
+		
+		public Current_Product_List()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductID", AutoSync=AutoSync.Always, DbType="Int NOT NULL IDENTITY", IsDbGenerated=true)]
+		public int ProductID
+		{
+			get
+			{
+				return this._ProductID;
+			}
+			set
+			{
+				if ((this._ProductID != value))
+				{
+					this._ProductID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Customer and Suppliers by City]")]
+	public partial class Customer_and_Suppliers_by_City
+	{
+		
+		private string _City;
+		
+		private string _CompanyName;
+		
+		private string _ContactName;
+		
+		private string _Relationship;
+		
+		public Customer_and_Suppliers_by_City()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_City", DbType="NVarChar(15)")]
+		public string City
+		{
+			get
+			{
+				return this._City;
+			}
+			set
+			{
+				if ((this._City != value))
+				{
+					this._City = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string CompanyName
+		{
+			get
+			{
+				return this._CompanyName;
+			}
+			set
+			{
+				if ((this._CompanyName != value))
+				{
+					this._CompanyName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ContactName", DbType="NVarChar(30)")]
+		public string ContactName
+		{
+			get
+			{
+				return this._ContactName;
+			}
+			set
+			{
+				if ((this._ContactName != value))
+				{
+					this._ContactName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Relationship", DbType="VarChar(9) NOT NULL", CanBeNull=false)]
+		public string Relationship
+		{
+			get
+			{
+				return this._Relationship;
+			}
+			set
+			{
+				if ((this._Relationship != value))
+				{
+					this._Relationship = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Invoices")]
+	public partial class Invoice
+	{
+		
+		private string _ShipName;
+		
+		private string _ShipAddress;
+		
+		private string _ShipCity;
+		
+		private string _ShipRegion;
+		
+		private string _ShipPostalCode;
+		
+		private string _ShipCountry;
+		
+		private string _CustomerID;
+		
+		private string _CustomerName;
+		
+		private string _Address;
+		
+		private string _City;
+		
+		private string _Region;
+		
+		private string _PostalCode;
+		
+		private string _Country;
+		
+		private string _Salesperson;
+		
+		private int _OrderID;
+		
+		private System.Nullable<System.DateTime> _OrderDate;
+		
+		private System.Nullable<System.DateTime> _RequiredDate;
+		
+		private System.Nullable<System.DateTime> _ShippedDate;
+		
+		private string _ShipperName;
+		
+		private int _ProductID;
+		
+		private string _ProductName;
+		
+		private decimal _UnitPrice;
+		
+		private short _Quantity;
+		
+		private float _Discount;
+		
+		private System.Nullable<decimal> _ExtendedPrice;
+		
+		private System.Nullable<decimal> _Freight;
+		
+		public Invoice()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipName", DbType="NVarChar(40)")]
+		public string ShipName
+		{
+			get
+			{
+				return this._ShipName;
+			}
+			set
+			{
+				if ((this._ShipName != value))
+				{
+					this._ShipName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipAddress", DbType="NVarChar(60)")]
+		public string ShipAddress
+		{
+			get
+			{
+				return this._ShipAddress;
+			}
+			set
+			{
+				if ((this._ShipAddress != value))
+				{
+					this._ShipAddress = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipCity", DbType="NVarChar(15)")]
+		public string ShipCity
+		{
+			get
+			{
+				return this._ShipCity;
+			}
+			set
+			{
+				if ((this._ShipCity != value))
+				{
+					this._ShipCity = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipRegion", DbType="NVarChar(15)")]
+		public string ShipRegion
+		{
+			get
+			{
+				return this._ShipRegion;
+			}
+			set
+			{
+				if ((this._ShipRegion != value))
+				{
+					this._ShipRegion = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipPostalCode", DbType="NVarChar(10)")]
+		public string ShipPostalCode
+		{
+			get
+			{
+				return this._ShipPostalCode;
+			}
+			set
+			{
+				if ((this._ShipPostalCode != value))
+				{
+					this._ShipPostalCode = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipCountry", DbType="NVarChar(15)")]
+		public string ShipCountry
+		{
+			get
+			{
+				return this._ShipCountry;
+			}
+			set
+			{
+				if ((this._ShipCountry != value))
+				{
+					this._ShipCountry = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CustomerID", DbType="NChar(5)")]
+		public string CustomerID
+		{
+			get
+			{
+				return this._CustomerID;
+			}
+			set
+			{
+				if ((this._CustomerID != value))
+				{
+					this._CustomerID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CustomerName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string CustomerName
+		{
+			get
+			{
+				return this._CustomerName;
+			}
+			set
+			{
+				if ((this._CustomerName != value))
+				{
+					this._CustomerName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Address", DbType="NVarChar(60)")]
+		public string Address
+		{
+			get
+			{
+				return this._Address;
+			}
+			set
+			{
+				if ((this._Address != value))
+				{
+					this._Address = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_City", DbType="NVarChar(15)")]
+		public string City
+		{
+			get
+			{
+				return this._City;
+			}
+			set
+			{
+				if ((this._City != value))
+				{
+					this._City = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Region", DbType="NVarChar(15)")]
+		public string Region
+		{
+			get
+			{
+				return this._Region;
+			}
+			set
+			{
+				if ((this._Region != value))
+				{
+					this._Region = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PostalCode", DbType="NVarChar(10)")]
+		public string PostalCode
+		{
+			get
+			{
+				return this._PostalCode;
+			}
+			set
+			{
+				if ((this._PostalCode != value))
+				{
+					this._PostalCode = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Country", DbType="NVarChar(15)")]
+		public string Country
+		{
+			get
+			{
+				return this._Country;
+			}
+			set
+			{
+				if ((this._Country != value))
+				{
+					this._Country = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Salesperson", DbType="NVarChar(31) NOT NULL", CanBeNull=false)]
+		public string Salesperson
+		{
+			get
+			{
+				return this._Salesperson;
+			}
+			set
+			{
+				if ((this._Salesperson != value))
+				{
+					this._Salesperson = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL")]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this._OrderID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> OrderDate
+		{
+			get
+			{
+				return this._OrderDate;
+			}
+			set
+			{
+				if ((this._OrderDate != value))
+				{
+					this._OrderDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RequiredDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> RequiredDate
+		{
+			get
+			{
+				return this._RequiredDate;
+			}
+			set
+			{
+				if ((this._RequiredDate != value))
+				{
+					this._RequiredDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShippedDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> ShippedDate
+		{
+			get
+			{
+				return this._ShippedDate;
+			}
+			set
+			{
+				if ((this._ShippedDate != value))
+				{
+					this._ShippedDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipperName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ShipperName
+		{
+			get
+			{
+				return this._ShipperName;
+			}
+			set
+			{
+				if ((this._ShipperName != value))
+				{
+					this._ShipperName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductID", DbType="Int NOT NULL")]
+		public int ProductID
+		{
+			get
+			{
+				return this._ProductID;
+			}
+			set
+			{
+				if ((this._ProductID != value))
+				{
+					this._ProductID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitPrice", DbType="Money NOT NULL")]
+		public decimal UnitPrice
+		{
+			get
+			{
+				return this._UnitPrice;
+			}
+			set
+			{
+				if ((this._UnitPrice != value))
+				{
+					this._UnitPrice = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Quantity", DbType="SmallInt NOT NULL")]
+		public short Quantity
+		{
+			get
+			{
+				return this._Quantity;
+			}
+			set
+			{
+				if ((this._Quantity != value))
+				{
+					this._Quantity = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Discount", DbType="Real NOT NULL")]
+		public float Discount
+		{
+			get
+			{
+				return this._Discount;
+			}
+			set
+			{
+				if ((this._Discount != value))
+				{
+					this._Discount = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExtendedPrice", DbType="Money")]
+		public System.Nullable<decimal> ExtendedPrice
+		{
+			get
+			{
+				return this._ExtendedPrice;
+			}
+			set
+			{
+				if ((this._ExtendedPrice != value))
+				{
+					this._ExtendedPrice = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Freight", DbType="Money")]
+		public System.Nullable<decimal> Freight
+		{
+			get
+			{
+				return this._Freight;
+			}
+			set
+			{
+				if ((this._Freight != value))
+				{
+					this._Freight = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Order Details Extended]")]
+	public partial class Order_Details_Extended
+	{
+		
+		private int _OrderID;
+		
+		private int _ProductID;
+		
+		private string _ProductName;
+		
+		private decimal _UnitPrice;
+		
+		private short _Quantity;
+		
+		private float _Discount;
+		
+		private System.Nullable<decimal> _ExtendedPrice;
+		
+		public Order_Details_Extended()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL")]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this._OrderID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductID", DbType="Int NOT NULL")]
+		public int ProductID
+		{
+			get
+			{
+				return this._ProductID;
+			}
+			set
+			{
+				if ((this._ProductID != value))
+				{
+					this._ProductID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitPrice", DbType="Money NOT NULL")]
+		public decimal UnitPrice
+		{
+			get
+			{
+				return this._UnitPrice;
+			}
+			set
+			{
+				if ((this._UnitPrice != value))
+				{
+					this._UnitPrice = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Quantity", DbType="SmallInt NOT NULL")]
+		public short Quantity
+		{
+			get
+			{
+				return this._Quantity;
+			}
+			set
+			{
+				if ((this._Quantity != value))
+				{
+					this._Quantity = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Discount", DbType="Real NOT NULL")]
+		public float Discount
+		{
+			get
+			{
+				return this._Discount;
+			}
+			set
+			{
+				if ((this._Discount != value))
+				{
+					this._Discount = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExtendedPrice", DbType="Money")]
+		public System.Nullable<decimal> ExtendedPrice
+		{
+			get
+			{
+				return this._ExtendedPrice;
+			}
+			set
+			{
+				if ((this._ExtendedPrice != value))
+				{
+					this._ExtendedPrice = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Order Subtotals]")]
+	public partial class Order_Subtotal
+	{
+		
+		private int _OrderID;
+		
+		private System.Nullable<decimal> _Subtotal;
+		
+		public Order_Subtotal()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL")]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this._OrderID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Subtotal", DbType="Money")]
+		public System.Nullable<decimal> Subtotal
+		{
+			get
+			{
+				return this._Subtotal;
+			}
+			set
+			{
+				if ((this._Subtotal != value))
+				{
+					this._Subtotal = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Orders Qry]")]
+	public partial class Orders_Qry
+	{
+		
+		private int _OrderID;
+		
+		private string _CustomerID;
+		
+		private System.Nullable<int> _EmployeeID;
+		
+		private System.Nullable<System.DateTime> _OrderDate;
+		
+		private System.Nullable<System.DateTime> _RequiredDate;
+		
+		private System.Nullable<System.DateTime> _ShippedDate;
+		
+		private System.Nullable<int> _ShipVia;
+		
+		private System.Nullable<decimal> _Freight;
+		
+		private string _ShipName;
+		
+		private string _ShipAddress;
+		
+		private string _ShipCity;
+		
+		private string _ShipRegion;
+		
+		private string _ShipPostalCode;
+		
+		private string _ShipCountry;
+		
+		private string _CompanyName;
+		
+		private string _Address;
+		
+		private string _City;
+		
+		private string _Region;
+		
+		private string _PostalCode;
+		
+		private string _Country;
+		
+		public Orders_Qry()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL")]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this._OrderID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CustomerID", DbType="NChar(5)")]
+		public string CustomerID
+		{
+			get
+			{
+				return this._CustomerID;
+			}
+			set
+			{
+				if ((this._CustomerID != value))
+				{
+					this._CustomerID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmployeeID", DbType="Int")]
+		public System.Nullable<int> EmployeeID
+		{
+			get
+			{
+				return this._EmployeeID;
+			}
+			set
+			{
+				if ((this._EmployeeID != value))
+				{
+					this._EmployeeID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> OrderDate
+		{
+			get
+			{
+				return this._OrderDate;
+			}
+			set
+			{
+				if ((this._OrderDate != value))
+				{
+					this._OrderDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RequiredDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> RequiredDate
+		{
+			get
+			{
+				return this._RequiredDate;
+			}
+			set
+			{
+				if ((this._RequiredDate != value))
+				{
+					this._RequiredDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShippedDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> ShippedDate
+		{
+			get
+			{
+				return this._ShippedDate;
+			}
+			set
+			{
+				if ((this._ShippedDate != value))
+				{
+					this._ShippedDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipVia", DbType="Int")]
+		public System.Nullable<int> ShipVia
+		{
+			get
+			{
+				return this._ShipVia;
+			}
+			set
+			{
+				if ((this._ShipVia != value))
+				{
+					this._ShipVia = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Freight", DbType="Money")]
+		public System.Nullable<decimal> Freight
+		{
+			get
+			{
+				return this._Freight;
+			}
+			set
+			{
+				if ((this._Freight != value))
+				{
+					this._Freight = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipName", DbType="NVarChar(40)")]
+		public string ShipName
+		{
+			get
+			{
+				return this._ShipName;
+			}
+			set
+			{
+				if ((this._ShipName != value))
+				{
+					this._ShipName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipAddress", DbType="NVarChar(60)")]
+		public string ShipAddress
+		{
+			get
+			{
+				return this._ShipAddress;
+			}
+			set
+			{
+				if ((this._ShipAddress != value))
+				{
+					this._ShipAddress = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipCity", DbType="NVarChar(15)")]
+		public string ShipCity
+		{
+			get
+			{
+				return this._ShipCity;
+			}
+			set
+			{
+				if ((this._ShipCity != value))
+				{
+					this._ShipCity = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipRegion", DbType="NVarChar(15)")]
+		public string ShipRegion
+		{
+			get
+			{
+				return this._ShipRegion;
+			}
+			set
+			{
+				if ((this._ShipRegion != value))
+				{
+					this._ShipRegion = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipPostalCode", DbType="NVarChar(10)")]
+		public string ShipPostalCode
+		{
+			get
+			{
+				return this._ShipPostalCode;
+			}
+			set
+			{
+				if ((this._ShipPostalCode != value))
+				{
+					this._ShipPostalCode = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShipCountry", DbType="NVarChar(15)")]
+		public string ShipCountry
+		{
+			get
+			{
+				return this._ShipCountry;
+			}
+			set
+			{
+				if ((this._ShipCountry != value))
+				{
+					this._ShipCountry = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string CompanyName
+		{
+			get
+			{
+				return this._CompanyName;
+			}
+			set
+			{
+				if ((this._CompanyName != value))
+				{
+					this._CompanyName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Address", DbType="NVarChar(60)")]
+		public string Address
+		{
+			get
+			{
+				return this._Address;
+			}
+			set
+			{
+				if ((this._Address != value))
+				{
+					this._Address = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_City", DbType="NVarChar(15)")]
+		public string City
+		{
+			get
+			{
+				return this._City;
+			}
+			set
+			{
+				if ((this._City != value))
+				{
+					this._City = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Region", DbType="NVarChar(15)")]
+		public string Region
+		{
+			get
+			{
+				return this._Region;
+			}
+			set
+			{
+				if ((this._Region != value))
+				{
+					this._Region = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PostalCode", DbType="NVarChar(10)")]
+		public string PostalCode
+		{
+			get
+			{
+				return this._PostalCode;
+			}
+			set
+			{
+				if ((this._PostalCode != value))
+				{
+					this._PostalCode = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Country", DbType="NVarChar(15)")]
+		public string Country
+		{
+			get
+			{
+				return this._Country;
+			}
+			set
+			{
+				if ((this._Country != value))
+				{
+					this._Country = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Product Sales for 1997]")]
+	public partial class Product_Sales_for_1997
+	{
+		
+		private string _CategoryName;
+		
+		private string _ProductName;
+		
+		private System.Nullable<decimal> _ProductSales;
+		
+		public Product_Sales_for_1997()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategoryName", DbType="NVarChar(15) NOT NULL", CanBeNull=false)]
+		public string CategoryName
+		{
+			get
+			{
+				return this._CategoryName;
+			}
+			set
+			{
+				if ((this._CategoryName != value))
+				{
+					this._CategoryName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductSales", DbType="Money")]
+		public System.Nullable<decimal> ProductSales
+		{
+			get
+			{
+				return this._ProductSales;
+			}
+			set
+			{
+				if ((this._ProductSales != value))
+				{
+					this._ProductSales = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Products Above Average Price]")]
+	public partial class Products_Above_Average_Price
+	{
+		
+		private string _ProductName;
+		
+		private System.Nullable<decimal> _UnitPrice;
+		
+		public Products_Above_Average_Price()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitPrice", DbType="Money")]
+		public System.Nullable<decimal> UnitPrice
+		{
+			get
+			{
+				return this._UnitPrice;
+			}
+			set
+			{
+				if ((this._UnitPrice != value))
+				{
+					this._UnitPrice = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Products by Category]")]
+	public partial class Products_by_Category
+	{
+		
+		private string _CategoryName;
+		
+		private string _ProductName;
+		
+		private string _QuantityPerUnit;
+		
+		private System.Nullable<short> _UnitsInStock;
+		
+		private bool _Discontinued;
+		
+		public Products_by_Category()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategoryName", DbType="NVarChar(15) NOT NULL", CanBeNull=false)]
+		public string CategoryName
+		{
+			get
+			{
+				return this._CategoryName;
+			}
+			set
+			{
+				if ((this._CategoryName != value))
+				{
+					this._CategoryName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_QuantityPerUnit", DbType="NVarChar(20)")]
+		public string QuantityPerUnit
+		{
+			get
+			{
+				return this._QuantityPerUnit;
+			}
+			set
+			{
+				if ((this._QuantityPerUnit != value))
+				{
+					this._QuantityPerUnit = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitsInStock", DbType="SmallInt")]
+		public System.Nullable<short> UnitsInStock
+		{
+			get
+			{
+				return this._UnitsInStock;
+			}
+			set
+			{
+				if ((this._UnitsInStock != value))
+				{
+					this._UnitsInStock = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Discontinued", DbType="Bit NOT NULL")]
+		public bool Discontinued
+		{
+			get
+			{
+				return this._Discontinued;
+			}
+			set
+			{
+				if ((this._Discontinued != value))
+				{
+					this._Discontinued = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Quarterly Orders]")]
+	public partial class Quarterly_Order
+	{
+		
+		private string _CustomerID;
+		
+		private string _CompanyName;
+		
+		private string _City;
+		
+		private string _Country;
+		
+		public Quarterly_Order()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CustomerID", DbType="NChar(5)")]
+		public string CustomerID
+		{
+			get
+			{
+				return this._CustomerID;
+			}
+			set
+			{
+				if ((this._CustomerID != value))
+				{
+					this._CustomerID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CompanyName", DbType="NVarChar(40)")]
+		public string CompanyName
+		{
+			get
+			{
+				return this._CompanyName;
+			}
+			set
+			{
+				if ((this._CompanyName != value))
+				{
+					this._CompanyName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_City", DbType="NVarChar(15)")]
+		public string City
+		{
+			get
+			{
+				return this._City;
+			}
+			set
+			{
+				if ((this._City != value))
+				{
+					this._City = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Country", DbType="NVarChar(15)")]
+		public string Country
+		{
+			get
+			{
+				return this._Country;
+			}
+			set
+			{
+				if ((this._Country != value))
+				{
+					this._Country = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Sales by Category]")]
+	public partial class Sales_by_Category
+	{
+		
+		private int _CategoryID;
+		
+		private string _CategoryName;
+		
+		private string _ProductName;
+		
+		private System.Nullable<decimal> _ProductSales;
+		
+		public Sales_by_Category()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategoryID", DbType="Int NOT NULL")]
+		public int CategoryID
+		{
+			get
+			{
+				return this._CategoryID;
+			}
+			set
+			{
+				if ((this._CategoryID != value))
+				{
+					this._CategoryID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CategoryName", DbType="NVarChar(15) NOT NULL", CanBeNull=false)]
+		public string CategoryName
+		{
+			get
+			{
+				return this._CategoryName;
+			}
+			set
+			{
+				if ((this._CategoryName != value))
+				{
+					this._CategoryName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductSales", DbType="Money")]
+		public System.Nullable<decimal> ProductSales
+		{
+			get
+			{
+				return this._ProductSales;
+			}
+			set
+			{
+				if ((this._ProductSales != value))
+				{
+					this._ProductSales = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Sales Totals by Amount]")]
+	public partial class Sales_Totals_by_Amount
+	{
+		
+		private System.Nullable<decimal> _SaleAmount;
+		
+		private int _OrderID;
+		
+		private string _CompanyName;
+		
+		private System.Nullable<System.DateTime> _ShippedDate;
+		
+		public Sales_Totals_by_Amount()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SaleAmount", DbType="Money")]
+		public System.Nullable<decimal> SaleAmount
+		{
+			get
+			{
+				return this._SaleAmount;
+			}
+			set
+			{
+				if ((this._SaleAmount != value))
+				{
+					this._SaleAmount = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL")]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this._OrderID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CompanyName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string CompanyName
+		{
+			get
+			{
+				return this._CompanyName;
+			}
+			set
+			{
+				if ((this._CompanyName != value))
+				{
+					this._CompanyName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShippedDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> ShippedDate
+		{
+			get
+			{
+				return this._ShippedDate;
+			}
+			set
+			{
+				if ((this._ShippedDate != value))
+				{
+					this._ShippedDate = value;
+				}
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Summary of Sales by Quarter]")]
+	public partial class Summary_of_Sales_by_Quarter
+	{
+		
+		private System.Nullable<System.DateTime> _ShippedDate;
+		
+		private int _OrderID;
+		
+		private System.Nullable<decimal> _Subtotal;
+		
+		public Summary_of_Sales_by_Quarter()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShippedDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> ShippedDate
+		{
+			get
+			{
+				return this._ShippedDate;
+			}
+			set
+			{
+				if ((this._ShippedDate != value))
+				{
+					this._ShippedDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL")]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this._OrderID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Subtotal", DbType="Money")]
+		public System.Nullable<decimal> Subtotal
+		{
+			get
+			{
+				return this._Subtotal;
+			}
+			set
+			{
+				if ((this._Subtotal != value))
+				{
+					this._Subtotal = value;
+				}
+			}
+		}
+	}
+	
+	public partial class CustOrderHistResult
+	{
+		
+		private string _ProductName;
+		
+		private System.Nullable<int> _Total;
+		
+		public CustOrderHistResult()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Total", DbType="Int")]
+		public System.Nullable<int> Total
+		{
+			get
+			{
+				return this._Total;
+			}
+			set
+			{
+				if ((this._Total != value))
+				{
+					this._Total = value;
+				}
+			}
+		}
+	}
+	
+	public partial class Ten_Most_Expensive_ProductsResult
+	{
+		
+		private string _TenMostExpensiveProducts;
+		
+		private System.Nullable<decimal> _UnitPrice;
+		
+		public Ten_Most_Expensive_ProductsResult()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_TenMostExpensiveProducts", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string TenMostExpensiveProducts
+		{
+			get
+			{
+				return this._TenMostExpensiveProducts;
+			}
+			set
+			{
+				if ((this._TenMostExpensiveProducts != value))
+				{
+					this._TenMostExpensiveProducts = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitPrice", DbType="Money")]
+		public System.Nullable<decimal> UnitPrice
+		{
+			get
+			{
+				return this._UnitPrice;
+			}
+			set
+			{
+				if ((this._UnitPrice != value))
+				{
+					this._UnitPrice = value;
+				}
+			}
+		}
+	}
+	
+	public partial class CustOrdersDetailResult
+	{
+		
+		private string _ProductName;
+		
+		private decimal _UnitPrice;
+		
+		private short _Quantity;
+		
+		private System.Nullable<int> _Discount;
+		
+		private System.Nullable<decimal> _ExtendedPrice;
+		
+		public CustOrdersDetailResult()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitPrice", DbType="Money NOT NULL")]
+		public decimal UnitPrice
+		{
+			get
+			{
+				return this._UnitPrice;
+			}
+			set
+			{
+				if ((this._UnitPrice != value))
+				{
+					this._UnitPrice = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Quantity", DbType="SmallInt NOT NULL")]
+		public short Quantity
+		{
+			get
+			{
+				return this._Quantity;
+			}
+			set
+			{
+				if ((this._Quantity != value))
+				{
+					this._Quantity = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Discount", DbType="Int")]
+		public System.Nullable<int> Discount
+		{
+			get
+			{
+				return this._Discount;
+			}
+			set
+			{
+				if ((this._Discount != value))
+				{
+					this._Discount = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExtendedPrice", DbType="Money")]
+		public System.Nullable<decimal> ExtendedPrice
+		{
+			get
+			{
+				return this._ExtendedPrice;
+			}
+			set
+			{
+				if ((this._ExtendedPrice != value))
+				{
+					this._ExtendedPrice = value;
+				}
+			}
+		}
+	}
+	
+	public partial class CustOrdersOrdersResult
+	{
+		
+		private int _OrderID;
+		
+		private System.Nullable<System.DateTime> _OrderDate;
+		
+		private System.Nullable<System.DateTime> _RequiredDate;
+		
+		private System.Nullable<System.DateTime> _ShippedDate;
+		
+		public CustOrdersOrdersResult()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL")]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this._OrderID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> OrderDate
+		{
+			get
+			{
+				return this._OrderDate;
+			}
+			set
+			{
+				if ((this._OrderDate != value))
+				{
+					this._OrderDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RequiredDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> RequiredDate
+		{
+			get
+			{
+				return this._RequiredDate;
+			}
+			set
+			{
+				if ((this._RequiredDate != value))
+				{
+					this._RequiredDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShippedDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> ShippedDate
+		{
+			get
+			{
+				return this._ShippedDate;
+			}
+			set
+			{
+				if ((this._ShippedDate != value))
+				{
+					this._ShippedDate = value;
+				}
+			}
+		}
+	}
+	
+	public partial class Employee_Sales_by_CountryResult
+	{
+		
+		private string _Country;
+		
+		private string _LastName;
+		
+		private string _FirstName;
+		
+		private System.Nullable<System.DateTime> _ShippedDate;
+		
+		private int _OrderID;
+		
+		private System.Nullable<decimal> _SaleAmount;
+		
+		public Employee_Sales_by_CountryResult()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Country", DbType="NVarChar(15)")]
+		public string Country
+		{
+			get
+			{
+				return this._Country;
+			}
+			set
+			{
+				if ((this._Country != value))
+				{
+					this._Country = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_LastName", DbType="NVarChar(20) NOT NULL", CanBeNull=false)]
+		public string LastName
+		{
+			get
+			{
+				return this._LastName;
+			}
+			set
+			{
+				if ((this._LastName != value))
+				{
+					this._LastName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FirstName", DbType="NVarChar(10) NOT NULL", CanBeNull=false)]
+		public string FirstName
+		{
+			get
+			{
+				return this._FirstName;
+			}
+			set
+			{
+				if ((this._FirstName != value))
+				{
+					this._FirstName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShippedDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> ShippedDate
+		{
+			get
+			{
+				return this._ShippedDate;
+			}
+			set
+			{
+				if ((this._ShippedDate != value))
+				{
+					this._ShippedDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL")]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this._OrderID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SaleAmount", DbType="Money")]
+		public System.Nullable<decimal> SaleAmount
+		{
+			get
+			{
+				return this._SaleAmount;
+			}
+			set
+			{
+				if ((this._SaleAmount != value))
+				{
+					this._SaleAmount = value;
+				}
+			}
+		}
+	}
+	
+	public partial class Sales_by_YearResult
+	{
+		
+		private System.Nullable<System.DateTime> _ShippedDate;
+		
+		private int _OrderID;
+		
+		private System.Nullable<decimal> _Subtotal;
+		
+		private string _Year;
+		
+		public Sales_by_YearResult()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ShippedDate", DbType="DateTime")]
+		public System.Nullable<System.DateTime> ShippedDate
+		{
+			get
+			{
+				return this._ShippedDate;
+			}
+			set
+			{
+				if ((this._ShippedDate != value))
+				{
+					this._ShippedDate = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OrderID", DbType="Int NOT NULL")]
+		public int OrderID
+		{
+			get
+			{
+				return this._OrderID;
+			}
+			set
+			{
+				if ((this._OrderID != value))
+				{
+					this._OrderID = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Subtotal", DbType="Money")]
+		public System.Nullable<decimal> Subtotal
+		{
+			get
+			{
+				return this._Subtotal;
+			}
+			set
+			{
+				if ((this._Subtotal != value))
+				{
+					this._Subtotal = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Year", DbType="NVarChar(30)")]
+		public string Year
+		{
+			get
+			{
+				return this._Year;
+			}
+			set
+			{
+				if ((this._Year != value))
+				{
+					this._Year = value;
+				}
+			}
+		}
+	}
+	
+	public partial class SalesByCategoryResult
+	{
+		
+		private string _ProductName;
+		
+		private System.Nullable<decimal> _TotalPurchase;
+		
+		public SalesByCategoryResult()
+		{
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProductName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
+		public string ProductName
+		{
+			get
+			{
+				return this._ProductName;
+			}
+			set
+			{
+				if ((this._ProductName != value))
+				{
+					this._ProductName = value;
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_TotalPurchase", DbType="Decimal(38,2)")]
+		public System.Nullable<decimal> TotalPurchase
+		{
+			get
+			{
+				return this._TotalPurchase;
+			}
+			set
+			{
+				if ((this._TotalPurchase != value))
+				{
+					this._TotalPurchase = value;
+				}
+			}
+		}
+	}
+}
+#pragma warning restore 1591
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Properties/AssemblyInfo.cs b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6d2f4b4
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("LinqToSql.Northwind")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("LinqToSql.Northwind")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
+[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("12be0a70-38cc-4bd9-9aab-fe5baca58f68")]
+
+// 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/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Properties/Settings.Designer.cs b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..edd41fd
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Properties/Settings.Designer.cs
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.1
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace LinqToSql.Northwind.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+        
+        [global::System.Configuration.ApplicationScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
+        [global::System.Configuration.DefaultSettingValueAttribute("Data Source=.\\SQLEXPRESS;AttachDbFilename=\"C:\\Tomas\\Projects\\Documents\\Templates\\" +
+            "Web\\WebApplication (MVC 3)\\WebApplication\\App_Data\\NORTHWND.MDF\";Integrated Secu" +
+            "rity=True;User Instance=True")]
+        public string NORTHWNDConnectionString {
+            get {
+                return ((string)(this["NORTHWNDConnectionString"]));
+            }
+        }
+    }
+}
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Properties/Settings.settings b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Properties/Settings.settings
new file mode 100644
index 0000000..98173d0
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/Properties/Settings.settings
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="LinqToSql.Northwind.Properties" GeneratedClassName="Settings">
+  <Profiles />
+  <Settings>
+    <Setting Name="NORTHWNDConnectionString" Type="(Connection string)" Scope="Application">
+      <DesignTimeValue Profile="(Default)"><?xml version="1.0" encoding="utf-16"?>
+<SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <ConnectionString>Data Source=.\SQLEXPRESS;AttachDbFilename="C:\Tomas\Projects\Documents\Templates\Web\WebApplication (MVC 3)\WebApplication\App_Data\NORTHWND.MDF";Integrated Security=True;User Instance=True</ConnectionString>
+  <ProviderName>System.Data.SqlClient</ProviderName>
+</SerializableConnectionString></DesignTimeValue>
+      <Value Profile="(Default)">Data Source=.\SQLEXPRESS;AttachDbFilename="C:\Tomas\Projects\Documents\Templates\Web\WebApplication (MVC 3)\WebApplication\App_Data\NORTHWND.MDF";Integrated Security=True;User Instance=True</Value>
+    </Setting>
+  </Settings>
+</SettingsFile>
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/app.config b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/app.config
new file mode 100644
index 0000000..db0fb49
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Linq/LinqToSql.Northwind/app.config
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <configSections>
+    </configSections>
+    <connectionStrings>
+        <add name="LinqToSql.Northwind.Properties.Settings.NORTHWNDConnectionString"
+            connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename="C:\Tomas\Projects\Documents\Templates\Web\WebApplication (MVC 3)\WebApplication\App_Data\NORTHWND.MDF";Integrated Security=True;User Instance=True"
+            providerName="System.Data.SqlClient" />
+    </connectionStrings>
+</configuration>
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/MatrixVectorTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/MatrixVectorTests.fs
new file mode 100644
index 0000000..25a08e6
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/MatrixVectorTests.fs
@@ -0,0 +1,1686 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+
+module MG = Microsoft.FSharp.Math.Matrix.Generic
+module MDouble  = Math.Matrix
+module VGeneric = Math.Vector.Generic
+module VDouble  = Math.Vector
+
+#nowarn "44" // This construct is deprecated. 
+
+module Notation = 
+
+    type matrix = Matrix<float>
+    type vector = Vector<float>
+    type rowvec = RowVector<float>
+    type complex = Complex
+  
+    let gmatrix ll = Matrix.Generic.ofSeq ll
+    let gvector l = Vector.Generic.ofSeq  l
+    let growvec l = RowVector.Generic.ofSeq l
+      
+    let S x = Matrix.Generic.ofScalar x
+    let RV x = Matrix.Generic.ofRowVector x 
+    let V x  = Matrix.Generic.ofVector x
+    let M2V x = Matrix.Generic.toVector x
+    let M2RV x = Matrix.Generic.toRowVector x
+    let M2S x = Matrix.Generic.toScalar x
+
+    let complex x y = Complex.mkRect (x,y)
+    // Notational conveniences
+    let matrix ll = Matrix.ofSeq ll
+    let vector l = Vector.ofSeq l
+    let rowvec l = RowVector.ofSeq l
+
+// This code used to be in the power pack but is now part of these tests
+module LinearAlgebra = 
+        let inline sumfR f (a,b) =
+            let mutable res = 0.0 in
+            for i = a to b do
+                res <- res + f i;
+            done;
+            res
+
+        let isSymmetric a = a |> Matrix.foralli (fun i j aij -> aij = a.[j,i]) 
+        let isLowerTriangular a = a |> Matrix.foralli (fun i j aij -> i>=j || aij=0.0)
+
+        let choleskyFactor (a: matrix) =
+          let nA,mA = a.Dimensions in
+          if nA<>mA              then invalid_arg "choleskyFactor: not square";
+          if not (isSymmetric a) then invalid_arg "choleskyFactor: not symmetric";
+          let lres = Matrix.zero nA nA  in(* nA=mA *)
+          for j=0 to nA-1 do
+            for i=j to nA-1 do (* j <= i *)
+              let psum = sumfR (fun k -> lres.[i,k] * lres.[j,k]) (0,j-1) in
+              let a_ij = a.[i,j] in
+              if i=j then
+                lres.[i,i] <- (System.Math.Sqrt (a_ij - psum))
+              else
+                lres.[i,j] <- ((a_ij - psum) / lres.[j,j])
+          lres
+
+        let lowerTriangularInverse (l: matrix) =
+          let nA,mA = l.Dimensions in
+          let res = Matrix.zero nA nA  in (* nA=mA *)
+          for j=0 to nA-1 do
+            for i=j to nA-1 do (* j <= i *)
+              let psum   = sumfR (fun k -> l.[i,k] * res.[k,j]) (0,i-1) in
+              let id_ij  = if i=j then 1.0 else 0.0 in
+              let res_ij = (id_ij - psum) / l.[i,i] in
+              res.[i, j] <- res_ij
+          res
+
+        let symmetricInverse a =
+          let l     = choleskyFactor a         in
+          let l_t   = l.Transpose                in 
+          let l_inv = lowerTriangularInverse l in
+          let a_inv = l_inv.Transpose * l_inv in
+          a_inv
+
+        let determinant (a: matrix) =
+          let rec det js ks =
+            match ks with
+              | []    -> 1.0
+              | k::ks -> 
+                let rec split sign (preJs,js) =
+                  match js with
+                  | []    -> 0.0
+                  | j::js -> sign * a.[j,k] * det (List.rev preJs @ js) ks
+                             +
+                             split (0.0 - sign) (j::preJs,js) in
+                split 1.0 ([],js) in
+          let nA,mA = a.Dimensions in
+          if nA<>mA then invalid_arg "determinant: not square";
+          det [0..nA-1] [0..nA-1]
+
+        let cholesky a =
+          let l    = choleskyFactor         a in
+          let lInv = lowerTriangularInverse l in
+          l,lInv
+
+open Notation
+open LinearAlgebra
+
+[<TestFixture>]
+type public MatrixVectorTests() =
+  
+    [<Test>]
+    member this.VectorSlicingTests() = 
+
+            let v1 = vector [| 1.0;2.0;3.0;4.0;5.0;6.0 |]
+            test "vslice1923" (v1.[*] = v1)
+            test "vslice1923" (v1.[0..] = v1)
+            test "vslice1924" (v1.[1..] = vector [| 2.0;3.0;4.0;5.0;6.0 |])
+            test "vslice1925" (v1.[2..] = vector [| 3.0;4.0;5.0;6.0 |])
+            test "vslice1926" (v1.[5..] = vector [| 6.0 |])
+            test "vslice1927" (v1.[6..] = vector [| |])
+            test "vslice1928" (try v1.[7..] |> ignore; false with _ -> true)
+            test "vslice1929" (try v1.[-1 ..] |> ignore; false with _ -> true)
+            test "vslice1917" (v1.[..0] = vector [| 1.0 |])
+            test "vslice1911" (v1.[..1] = vector [| 1.0;2.0|])
+            test "vslice1912" (v1.[..2] = vector [| 1.0;2.0;3.0 |])
+            test "vslice1913" (v1.[..3] = vector [| 1.0;2.0;3.0;4.0|])
+            test "vslice1914" (v1.[..4] = vector [| 1.0;2.0;3.0;4.0;5.0 |])
+            test "vslice1915" (v1.[..5] = vector [| 1.0;2.0;3.0;4.0;5.0;6.0 |])
+            test "vslice1918" (try v1.[..6] |> ignore; false with _ -> true)
+            test "vslice1817" (v1.[1..0] = vector [|  |])
+            test "vslice1811" (v1.[1..1] = vector [| 2.0 |])
+            test "vslice1812" (v1.[1..2] = vector [| 2.0;3.0 |])
+            test "vslice1813" (v1.[1..3] = vector [| 2.0;3.0;4.0|])
+            test "vslice1814" (v1.[1..4] = vector [| 2.0;3.0;4.0;5.0|])
+            test "vslice1815" (v1.[1 ..5] = vector [| 2.0;3.0;4.0;5.0;6.0|])
+            test "vslice1818" (try v1.[1..6] |> ignore; false with _ -> true)
+
+    [<Test>]
+    member this.MatrixSlicingTests() = 
+
+        let m1 = matrix [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |];
+                           [| 10.0;20.0;30.0;40.0;50.0;60.0 |]  |]
+        test "mslice1923" (m1.[*,*] = m1)
+        test "mslice1924" (m1.[0..,*] = matrix [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |];
+                                                  [| 10.0;20.0;30.0;40.0;50.0;60.0 |]  |])
+        test "mslice1924" (m1.[1..,*] = matrix [| //[| 1.0;2.0;3.0;4.0;5.0;6.0 |];
+                                                  [| 10.0;20.0;30.0;40.0;50.0;60.0 |]  |])
+        test "mslice1924" (m1.[..0,*] = matrix [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |];
+                                                  //[| 10.0;20.0;30.0;40.0;50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,0..] = matrix [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |];
+                                                  [| 10.0;20.0;30.0;40.0;50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,1..] = matrix [| [| 2.0;3.0;4.0;5.0;6.0 |];
+                                                  [| 20.0;30.0;40.0;50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,2..] = matrix [| [| 3.0;4.0;5.0;6.0 |];
+                                                  [| 30.0;40.0;50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,3..] = matrix [| [| 4.0;5.0;6.0 |];
+                                                  [| 40.0;50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,4..] = matrix [| [| 5.0;6.0 |];
+                                                  [| 50.0;60.0 |]  
+                                                |])
+        test "mslice1924" (m1.[*,5..] = matrix [| [| 6.0 |];
+                                                  [| 60.0 |]  
+                                                |])
+
+    [<Test>]
+    member this.SomeSlicingTests() = 
+
+        let M = matrix [[ 0.0; 1.0; 2.0];[ 0.0; 1.0; 2.0];[ 0.0; 1.0; 2.0]]
+
+        check "ce0cew9js" M.[0..,0..] M
+        M.[1..2,0..1] <- matrix [[ 10.0;11.0];[ 12.0;13.0]]
+        check "ce0cew9js" M.[0..,0..] (matrix [[ 0.0; 1.0; 2.0];[ 10.0; 11.0; 2.0];[ 12.0; 13.0; 2.0]])
+
+        
+    [<Test>]
+    member this.ComplexOpsTest() = 
+
+        do test "989w42rra1" ((complex 1.0 2.0).RealPart = 1.0)
+        do test "989w42rra2" ((complex 1.0 2.0).ImaginaryPart = 2.0)
+        do test "989w42rra3" ((complex 1.0 2.0).i = 2.0)
+        do test "989w42rra4" ((complex 1.0 2.0).r = 1.0)
+        do test "989w42rra5" ((complex 3.0 4.0).Magnitude = 5.0)
+        do test "989w42rra6" ((complex 1.0 0.0).Phase = 0.0)
+        do test "989w42rra7" ((complex 1.0 0.0).Conjugate = (complex 1.0 0.0))
+        do test "989w42rra8" (Math.Complex.Create(1.0,2.0) = (complex 1.0 2.0))
+        do test "989w42rra9" (Math.Complex.Zero = complex 0.0 0.0)
+        do test "989w42rra0" (Math.Complex.Zero = Math.Complex.CreatePolar(0.0,1.0))
+        do test "989w42rra11" (Math.Complex.One = complex 1.0 0.0)
+        do test "989w42rra12" (Math.Complex.OneI = complex 0.0 1.0)
+        do test "989w42rra13" ((complex 2.0 0.0) = Math.Complex.CreatePolar(2.0,0.0) )
+        do test "989w42rra14" (complex 1.0 2.0 + complex (-1.0) (-2.0) = complex 0.0 0.0)
+        do test "989w42rra15" (complex 1.0 2.0 - (-(complex (-1.0) (-2.0))) = complex 0.0 0.0)
+        do test "989w42rra16" ((complex 1.0 0.0) * complex (-1.0) 0.0 = complex (-1.0) 0.0)
+        do test "989w42rra17" ((complex 1.0 0.0) * 2.0 = complex 2.0 0.0)
+        do test "989w42rra18" (2.0 * (complex 1.0 0.0) = complex 2.0 0.0)
+
+        do test "vrkhwe3r4y19" ((complex 1.0 1.0).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "1r+1i")
+        do test "vrkhwe3r4y20" ((complex 1.0 (-1.0)).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "1r-1i")
+        do test "vrkhwe3r4y21" ((complex (-1.0) (-1.0)).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "-1r-1i")
+        do test "vrkhwe3r4y22" ((complex (-1.0) 1.0).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "-1r+1i")
+        do test "vrkhwe3r4y23" ((complex (-1.0) 0.0).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "-1r+0i")
+        do test "vrkhwe3r4y24" ((complex 0.0 0.0).ToString("g", System.Globalization.CultureInfo.InvariantCulture) = "0r+0i")
+
+    [<Test>]
+    member this.MatrixOpsTest() = 
+
+        test "989w42rra" (Matrix.get (matrix [[1.0;2.0;1.0]]) 0 0 = 1.0)
+        test "989w42rrb" (Matrix.get (Matrix.zero 1 2) 0 0 = 0.0)
+        test "989w42rrc" (Matrix.get (Matrix.zero 1 2) 0 1 = 0.0)
+        test "989w42rrd" (Matrix.get (Matrix.create 1 2 1.1) 0 0 = 1.1)
+        test "989w42rre" (Matrix.get (Matrix.create 1 2 1.1) 0 1 = 1.1)
+        test "989w42rrf" (Matrix.get (Matrix.constDiag 2 1.1) 0 0 = 1.1)
+        test "989w42rrg" (Matrix.get (Matrix.constDiag 2 1.1) 0 1 = 0.0)
+        test "989w42rrh" (Matrix.get (Matrix.constDiag 2 1.1) 1 0 = 0.0)
+        test "989w42rri" (Matrix.get (Matrix.constDiag 2 1.1) 1 1 = 1.1)
+        test "989w42rrj" ((matrix [[1.0;2.0;1.0]]).Item(0,0) = 1.0)
+        test "989w42rrk" ((matrix [[1.0;2.0;1.0]]).Item(0,1) = 2.0)
+        test "989w42rrl" ((matrix [[1.0;2.0;1.0]]).Item(0,2) = 1.0)
+        test "989w42rr1" ((matrix [[1.0;2.0;1.0]]).[0,0] = 1.0)
+        test "989w42rr2" ((matrix [[1.0;2.0;1.0]]).[0,1] = 2.0)
+        test "989w42rr3" ((matrix [[1.0;2.0;1.0]]).[0,2] = 1.0)
+        test "989h42rr" ((matrix [[1.0;2.0;1.0]]).Dimensions = (1,3))
+        test "8f3fo3ij" ((matrix [[1.0];[2.0];[1.0]]).Dimensions = (3,1))
+        test "989hf2f2a" (Matrix.toScalar (Matrix.mul (matrix [[1.0;2.0;1.0]]) (matrix [[1.0];[2.0];[1.0]])) = 6.0)
+
+        test "989hf2f2b" ((let m = matrix [[1.0;2.0;1.0]] in 
+                           Matrix.inplace_add m (matrix [[1.0;2.0;3.0]]);
+                           m) = matrix [[2.0;4.0;4.0]])
+
+        test "989hf2f2c" (Matrix.toScalar (matrix [[1.0;2.0;1.0]] * matrix [[1.0];[2.0];[1.0]]) = 6.0)
+        test "989hf2f2d" (Matrix.toScalar (matrix [[1.0;2.0]; [3.0;4.0]] * 
+                              matrix [[1.0;2.0];[1.0;2.0]]) = 3.0)
+        test "989hf2f2e" (compare (matrix [[1.0]]) (matrix [[1.0]]) = 0)
+        test "989hf2f2f" (compare (matrix [[1.0]]) (matrix [[2.0]]) = -1)
+        test "989hf2f2g" (compare (matrix [[2.0]]) (matrix [[1.0]]) = 1)
+        test "989hf2f2h" (-(matrix [[2.0]]) = matrix [[-2.0]])
+        test "989hf2f2i" (-(matrix [[2.0; -1.0]]) = matrix [[-2.0; 1.0]])
+        test "989hf2f2j" (matrix [[1.0;2.0]; [3.0;4.0]] * matrix [[1.0;2.0]; [1.0;2.0]] = matrix [[3.0;6.0]; [7.0; 14.0]])
+
+        test "989hf2f2q" (Matrix.getCol (matrix [[1.0;2.0]; 
+                                                 [3.0;4.0]]) 0 =
+                                 vector [1.0;
+                                         3.0])
+
+        test "989hf2f3q1" (Matrix.foldByCol (fun x y -> x@[y]) (RowVector.Generic.of_list []) (matrix [[]; []])   = (RowVector.Generic.of_list []))
+        test "989hf2f3q1" (Matrix.foldByCol (fun x y -> x+y) (RowVector.Generic.of_list []) (matrix [[]; []])   = (RowVector.Generic.of_list []))
+
+        test "989hf2f3q2" (Matrix.foldByCol (fun x y -> x@[y]) (RowVector.Generic.of_list [[];[]]) (matrix [[1.0;2.0]; [3.0;4.0]])   = (RowVector.Generic.of_list [[1.0;3.0];[2.0;4.0]]))
+        test "989hf2f3q2" (Matrix.foldByCol (fun x y -> x+y) (RowVector.Generic.of_list [0.0;0.0]) (matrix [[1.0;2.0]; [3.0;4.0]])   = (RowVector.Generic.of_list [4.0;6.0]))
+
+        test "989hf2f3q3" (Matrix.foldByCol (fun x y -> x@[y]) (RowVector.Generic.of_list [[];[]]) (matrix [[1.0;2.0]; [3.0;4.0]; [5.0;6.0]])   = (RowVector.Generic.of_list [[1.0;3.0;5.0];[2.0;4.0;6.0]]))
+        test "989hf2f3q3" (Matrix.foldByCol (fun x y -> x+y) (RowVector.Generic.of_list [0.0;0.0]) (matrix [[1.0;2.0]; [3.0;4.0]; [5.0;6.0]])   = (RowVector.Generic.of_list [9.0;12.0]))
+
+        test "989hf2f3r4" (Matrix.foldByRow (fun x y -> x@[y]) (Vector.Generic.of_list [[];[]]) (matrix [[1.0;2.0]; [3.0;4.0]])   = (Vector.Generic.of_list [[1.0;2.0];[3.0;4.0]]))
+        test "989hf2f3r4" (Matrix.foldByRow (fun x y -> x+y) (Vector.Generic.of_list [0.0;0.0]) (matrix [[1.0;2.0]; [3.0;4.0]])   = (Vector.Generic.of_list [3.0;7.0]))
+
+        test "989hf2f3r5" (Matrix.foldByRow (fun x y -> x@[y]) (Vector.Generic.of_list [[];[];[]]) (matrix [[1.0;2.0]; [3.0;4.0]; [5.0;6.0]])   = (Vector.Generic.of_list [[1.0;2.0];[3.0;4.0]; [5.0;6.0];]))
+        test "989hf2f3r5" (Matrix.foldByRow (fun x y -> x+y) (Vector.Generic.of_list [0.0;0.0;0.0]) (matrix [[1.0;2.0]; [3.0;4.0]; [5.0;6.0]])   = (Vector.Generic.of_list [3.0;7.0; 11.0;]))
+
+        test "989hf2f3r4" (Matrix.foldRow (fun x y -> x@[y]) [] (matrix [[1.0;2.0]; [3.0;4.0]]) 0   = [1.0;2.0])
+        test "989hf2f3r4" (Matrix.foldCol (fun x y -> x@[y]) [] (matrix [[1.0;2.0]; [3.0;4.0]]) 0   = [1.0;3.0])
+        test "989hf2f3r4" (Matrix.foldRow (fun x y -> x@[y]) [] (matrix [[1.0;2.0]; [3.0;4.0]]) 1   = [3.0;4.0])
+        test "989hf2f3r4" (Matrix.foldCol (fun x y -> x@[y]) [] (matrix [[1.0;2.0]; [3.0;4.0]]) 1   = [2.0;4.0])
+
+
+        test "989hf2f2r1" (Matrix.getRow (matrix [[1.0;2.0]; 
+                                                 [3.0;4.0]]) 0 =
+                                 rowvec [1.0;2.0])
+
+        test "989hf2f2r2" (Matrix.getDiag (matrix [[1.0;2.0]; 
+                                                  [3.0;4.0]]) =
+                                 vector [1.0;4.0])
+
+        test "989hf2f2r3" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) 0 =
+                                 vector [1.0;4.0])
+
+        test "989hf2f2r4" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) 1 =
+                                 vector [2.0])
+
+        test "989hf2f2r5" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) 2 =
+                                 vector [])
+
+        test "989hf2f2r6" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) 3 =
+                                 vector [])
+
+        test "989hf2f2r7" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) (-1) =
+                                 vector [3.0])
+
+        test "989hf2f2r8" (Matrix.getDiagN (matrix [[1.0;2.0]; 
+                                                   [3.0;4.0]]) (-2) =
+                                 vector [])
+
+        test "989hf2f2s9" (Matrix.getRow (matrix [[1.0;2.0]; 
+                                                 [3.0;4.0]]) 1 =
+                                 rowvec [3.0;4.0])
+
+        test "989hf2f2tq" (Matrix.getRows (matrix [[1.0;2.0]; 
+                                                  [3.0;4.0]]) 1 1 =
+                                  (Matrix.ofRowVector (rowvec [3.0;4.0])))
+
+        test "989hf2f2u" (Matrix.getCols (matrix [[1.0;2.0]; 
+                                                  [3.0;4.0]]) 0 1 =
+                                  (Matrix.ofVector (vector [1.0;3.0])))
+        test "989hf2f2v" (Matrix.getRegion (matrix [[1.0;2.0]; 
+                                                    [3.0;4.0]]) 0 1 1 1 =
+                                  (matrix[[2.0]]))
+
+
+        test "989w42rrw" (Vector.range 0 3 = vector [0.0; 1.0; 2.0; 3.0])
+        test "989w42rrx" (Matrix.diag (vector [1.0; 2.0]) = matrix [[1.0;0.0]; 
+                                                             [0.0;2.0]])
+        test "989w42rry" (Vector.rangef 0.0 1.0 3.0 = vector [0.0; 1.0; 2.0; 3.0])
+        test "989w42rrz" (Vector.rangef 1.0 1.0 3.0 = vector [1.0; 2.0; 3.0])
+        test "989w42rra" (Vector.rangef 0.0 2.0 3.0 = vector [0.0; 2.0; 3.0])
+        test "989w42rrb" (determinant (matrix [[1.0]]) = 1.0)
+        test "989w42rrc" (determinant (matrix [[1.0;2.0];[3.0;4.0]]) = -2.0)
+
+        let a  = matrix [[1.0;2.0;1.0]; 
+                         [2.0;13.0;2.0]; 
+                         [1.0;2.0;5.0]]
+        let l  = choleskyFactor a
+        test "caeirj20" (l = matrix [[1.0; 0.0; 0.0];
+                                     [2.0; 3.0; 0.0];
+                                     [1.0; 0.0; 2.0]])
+        let lt = Matrix.transpose l
+        test "caeirj20" (l |> Matrix.transpose |> Matrix.transpose = l)
+        let a2 = l * lt
+        let zz = a2 - a
+        test "caeirj20" (zz = Matrix.zero 3 3)
+        let li = lowerTriangularInverse l
+        let uu1 = l * li  
+        let uu2 = li * l
+          
+        test "cdwioeu" (uu1 = matrix [[1.;0.;0.];[0.;1.;0.];[0.;0.;1.]])
+        test "cdwioeu" (uu2 = matrix [[1.;0.;0.];[0.;1.;0.];[0.;0.;1.]])
+
+        let m = matrix [[1.0;2.0;1.0];
+                        [3.0;8.0;5.0];
+                        [4.0;2.0;1.0]]
+        let d = determinant m
+        test "caeirj20" (d = 6.0)
+
+        
+        for i = 0 to 100000 do
+          ignore(determinant m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m .* m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m * m)
+        done
+        
+
+
+        let aa = Matrix.constDiag 2 2.0
+        let bb = Matrix.constDiag 2 1.5
+        let cc = aa + bb 
+        let dd = aa * cc
+
+        let xx = (Matrix.create 4 4 1.0) + (Matrix.constDiag 4 1.0)
+        let ll  = choleskyFactor xx
+        let llT = Matrix.transpose ll
+        let yy = ll * llT
+
+        let llInv = lowerTriangularInverse ll
+        let uu = ll * llInv
+        let aaa = Matrix.constDiag  4   1.0
+        let v   = Matrix.create 4 1 2.0
+        let w   = aaa * v
+
+        let zzz = aa + bb
+        let zz2 = aa * bb
+        let zz3 = 3.0 * bb
+        let zz4 = bb * 3.0
+        //let zz5 = bb * 3.0
+
+        zzz.Item(1,1) <- 3.0
+        test "ehoihoi" (zzz.Item(1,1) = 3.0)
+
+        zzz.[1,1] <- 4.0
+        test "ehoihoi" (zzz.[1,1] = 4.0)
+
+        
+    [<Test>]
+    member this.MiscRalfTest() = 
+
+        (*----------------------------------------------------------------------------
+        !* Ralf's test
+         *--------------------------------------------------------------------------*)
+            
+        let n = 30
+        let b = Matrix.randomize (Matrix.create n n 1.2)
+            
+        let testCholesky (b:matrix) =
+          let C = b * b.Transpose in
+          let d = choleskyFactor C in
+          let diff = d * d.Transpose - C in
+          let mm = Matrix.fold max 0.0 diff in
+          mm
+        
+
+        printf "minimum result = %O\n" (testCholesky b)
+        test "check very small" (testCholesky b < 0.000000001)
+
+    [<Test>]
+    member this.PermuteColumns() =
+        let u = matrix [ [1.;2.]; [3.;4.]; [5.;6.] ] 
+        let u' = u.PermuteColumns (fun j -> j)
+        Assert.AreEqual(u, u')
+
+        let u1 = matrix [ [1.;2.;3.]; [4.;5.;6.]; ] 
+        let u1' = u1.PermuteColumns (fun j -> 2 - j)
+        Assert.AreEqual(matrix [[3.;2.;1.]; [6.;5.;4.]], u1')
+
+        let u1transposed = u1.Transpose
+        Assert.AreEqual(matrix [[1.;4.];[2.;5.];[3.;6.]], u1transposed)
+
+       
+    [<Test>]
+    member this.PerfTest() = 
+        // sums over all elements of a vector
+
+        //-----------------------------------------------------
+        // Matrix Loop Perf: Example sumM1 (recommended, though sumM3 more explicitly better)
+        //
+        // This is simple code.  The indirect call in "Matrix.fold" may turn out to be a little
+        // costly, and either expanding by hand or using "inline" on Matrix.fold will
+        // help a lot (see sumM3)
+        let fold f z (A: matrix) = 
+          let mutable res = z in
+          for i = 0 to A.NumRows-1 do
+            for j = 0 to A.NumCols-1 do
+              res <- f res (A.Item(i, j));
+            done;
+          done;
+          res
+
+        let sumM1 (m:matrix) = fold (fun acc x -> acc + x) 0.0 m
+
+
+        //-----------------------------------------------------
+        // Matrix Loop Perf: Example sumM1a (recommended, though sumM3 more explicitly better)
+        //
+        // This is simple code.  The indirect call in "Matrix.fold" may turn out to be a little
+        // costly, and either expanding by hand or using "inline" on Matrix.fold will
+        // help a lot (see sumM3)
+        let folda f z (A: matrix) = 
+          let mutable res = z in
+          for i = 0 to A.NumRows-1 do
+            for j = 0 to A.NumCols-1 do
+              res <- f res (A.[i, j]);
+            done;
+          done;
+          res
+
+        let sumM1a (m:matrix) = folda (fun acc x -> acc + x) 0.0 m
+
+        //-----------------------------------------------------
+        // Matrix Loop Perf: Example sumM2 (not recommended)
+        //
+        // This is simple code and gives a reusable operator that 
+        // may come in handy. The tail recursive functions go1 and go2  in foldM2 will be turned 
+        // into loops and will run pretty fast, but variables 'd1' and 'd2' are
+        // captured as a free variables within the inner functions
+        // and no guarantees are made that the information necessary for
+        // array-bounds-check elimination will be propagated down.
+        let foldM2 f z (A: matrix) = 
+          let d1 = A.NumRows-1 in 
+          let d2 = A.NumCols-1 in 
+          let rec go2 acc i j = if j < d2 then f acc (A.Item(i,j)) else acc in 
+          let rec go1 acc i = if i < d1 then go1 (go2 acc i 0) (i+1) else acc in 
+          go1 z 0
+
+        let sumM2 (m:matrix) = foldM2 (fun acc x -> acc + x) 0.0 m
+
+
+        //-----------------------------------------------------
+        // Matrix Loop Perf: Example sumM3 (recommended)
+        //
+        // This is about as good as it gets.  My only performance
+        // concern here is that the array is hidden by an abstraction
+        // boundary and so the calls to A.NumRows, A.NumCols, A.Item etc.
+        // may not be optimizaed to act directly on the array.  Given
+        // the relative simplicity of the implementations of those
+        // functions that would be considered a bug in F#.
+        let sumM3 (A: matrix) = 
+          let mutable res = 0.0 in
+          for i = 0 to A.NumRows-1 do
+            for j = 0 to A.NumCols-1 do
+              res <-  res + (A.Item(i, j));
+            done;
+          done;
+          res
+
+        //-----------------------------------------------------
+        // Matrix Loop Perf: Example sumM4 (not recommended)
+        //
+        // This is sumM2 expanded by hand.
+        // Again the tail recursive functions go1 and go2 will be turned 
+        // into loops and will run pretty fast, but variables 'd1' and 'd2' are
+        // captured as a free variables within the inner functions
+        // functions, and so no guarantees are made that the information necessary for
+        // arry-bounds-check elimination will be propagated down
+        let sumM4 (A: matrix) = 
+          let d1 = A.NumRows-1 in 
+          let d2 = A.NumCols-1 in 
+          let rec go2 acc i j = if j < d2 then acc + (A.Item(i,j)) else acc in 
+          let rec go1 acc i = if i < d1 then go1 (go2 acc i 0) (i+1) else acc in 
+          go1 0.0 0
+        ()
+
+
+    [<Test>]
+    member this.GMatrixOpsAtFloatTest() = 
+
+
+        test "989w42rr" (MG.get (matrix [[1.0;2.0;1.0]]) 0 0 = 1.0)
+        test "989h42rr" ((matrix [[1.0;2.0;1.0]]).Dimensions = (1,3))
+        test "8f3fo3ij" ((matrix [[1.0];[2.0];[1.0]]).Dimensions = (3,1))
+        test "989hf2f2a" (Matrix.toScalar (MG.mul (matrix [[1.0;2.0;1.0]]) (matrix [[1.0];[2.0];[1.0]])) = 6.0)
+        test "989hf2f2q" (Matrix.toScalar (matrix [[1.0;2.0;1.0]] * matrix [[1.0];[2.0];[1.0]]) = 6.0)
+        test "989hf2f2w" (Matrix.toScalar (matrix [[1.0;2.0]; [3.0;4.0]] * 
+                              matrix [[1.0;2.0];[1.0;2.0]]) = 3.0)
+        test "989hf2f2e" (compare (matrix [[1.0]]) (matrix [[1.0]]) = 0)
+        test "989hf2f2rw" (compare (matrix [[1.0]]) (matrix [[2.0]]) = -1)
+        test "989hf2f2t" (compare (matrix [[2.0]]) (matrix [[1.0]]) = 1)
+        test "989hf2f2y" (-(matrix [[2.0; -1.0]]) = matrix [[-2.0; 1.0]])
+        test "989hf2f2u" (matrix [[1.0;2.0]; [3.0;4.0]] *  matrix [[1.0;2.0]; [1.0;2.0]] = matrix [[3.0;6.0]; [7.0; 14.0]])
+        test "989hf2f2g" (MG.getCol (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 0 =
+                                 vector [1.0;
+                                         3.0])
+
+        test "989hf2f2h" (MG.getRow (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 0 =
+                                 rowvec [1.0;2.0])
+
+        test "989hf2f2j" (MG.getRow (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 1 =
+                                 rowvec [3.0;4.0])
+
+        test "989hf2f2k" (MG.getRows (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 1 1 =
+                                  (MG.ofRowVector (rowvec [3.0;4.0])))
+
+        test "989hf2f2l" (MG.getCols (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 0 1 =
+                                  (V (vector [1.0;3.0])))
+        test "989hf2f2z" (MG.getRegion (matrix [[1.0;2.0]; 
+                                          [3.0;4.0]]) 0 1 1 1 =
+                                  (matrix[[2.0]]))
+
+
+        //test "989w42rr" (rangeVG 0 3 = vector [0.0; 1.0; 2.0; 3.0])
+        test "989w42rr" (MG.diag (vector [1.0; 2.0]) = matrix [[1.0;0.0]; 
+                                                               [0.0;2.0]])
+
+
+
+    [<Test>]
+    member this.GMatrixOpsAtFloat32Test() = 
+
+        test "989w42rr" (MG.get (gmatrix [[1.0f;2.0f;1.0f]]) 0 0 = 1.0f)
+        test "989h42rr" ((gmatrix [[1.0f;2.0f;1.0f]]).Dimensions = (1,3))
+        test "8f3fo3ij" ((gmatrix [[1.0f];[2.0f];[1.0f]]).Dimensions = (3,1))
+        test "98439hf2f2" (MG.toScalar (MG.mul (gmatrix [[1.0f;2.0f;1.0f]]) (gmatrix [[1.0f];[2.0f];[1.0f]])) = 6.0f)
+        test "98439hf2f2" (MG.toScalar (gmatrix [[1.0f;2.0f;1.0f]] * gmatrix [[1.0f];[2.0f];[1.0f]]) = 6.0f)
+        test "98439hf2f2" (MG.toScalar (gmatrix [[1.0f;2.0f]; [3.0f;4.0f]] * 
+                              gmatrix [[1.0f;2.0f];[1.0f;2.0f]]) = 3.0f)
+        test "98439hf2f2" (compare (gmatrix [[1.0f]]) (gmatrix [[1.0f]]) = 0)
+        test "98439hf2f2" (compare (gmatrix [[1.0f]]) (gmatrix [[2.0f]]) = -1)
+        test "98439hf2f2" (compare (gmatrix [[2.0f]]) (gmatrix [[1.0f]]) = 1)
+        test "98439hf2f2" (-(gmatrix [[2.0f; -1.0f]]) = gmatrix [[-2.0f; 1.0f]])
+        test "98439hf2f2" (gmatrix [[1.0f;2.0f]; [3.0f;4.0f]] * gmatrix [[1.0f;2.0f]; [1.0f;2.0f]] = gmatrix [[3.0f;6.0f]; [7.0f; 14.0f]])
+        test "98439hf2f2" (MG.getCol (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]]) 0 =
+                                 gvector [1.0f;3.0f])
+
+        test "98439hf2f2" (MG.getRow (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]]) 0 =
+                                 growvec [1.0f;2.0f])
+
+        test "98439hf2f2" (MG.getRow (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]]) 1 =
+                                 growvec [3.0f;4.0f])
+
+        test "98439hf2f2" (MG.getRows (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]]) 1 1 =
+                                  (MG.ofRowVector (growvec [3.0f;4.0f])))
+
+        test "98439hf2f2" (MG.getCols (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]])  0 1 =
+                                  (V (gvector [1.0f;3.0f])))
+        test "98439hf2f2" (MG.getRegion (gmatrix [[1.0f;2.0f]; 
+                                          [3.0f;4.0f]]) 0 1 1 1 =
+                                  (gmatrix[[2.0f]]))
+
+
+
+    [<Test>]
+    member this.GMatrixOpsAtBigNumTest() = 
+
+        test "989w42rr" (MG.get (gmatrix [[1N;2N;1N]]) 0 0 = 1N)
+        test "989h42rr" ((gmatrix [[1N;2N;1N]]).Dimensions = (1,3))
+        test "8f3fo3ij" ((gmatrix [[1N];[2N];[1N]]).Dimensions = (3,1))
+        test "68439hf2f2a" (MG.toScalar (MG.mul (gmatrix [[1N;2N;1N]]) (gmatrix [[1N];[2N];[1N]])) = 6N)
+        test "68439hf2f2s" (MG.toScalar (gmatrix [[1N;2N;1N]] * gmatrix [[1N];[2N];[1N]]) = 6N)
+        test "68439hf2f2d" (MG.toScalar (gmatrix [[1N;2N]; [3N;4N]] * 
+                              gmatrix [[1N;2N];[1N;2N]]) = 3N)
+        test "68439hf2f2f" (compare (gmatrix [[1N]]) (gmatrix [[1N]]) = 0)
+        test "68439hf2f2g" (compare (gmatrix [[1N]]) (gmatrix [[2N]]) = -1)
+        test "68439hf2f2h" (compare (gmatrix [[2N]]) (gmatrix [[1N]]) = 1)
+        test "68439hf2f2j" (-(gmatrix [[2N; -1N]]) = gmatrix [[-2N; 1N]])
+        test "68439hf2f2k" (gmatrix [[1N;2N]; [3N;4N]] * gmatrix [[1N;2N]; [1N;2N]] = gmatrix [[3N;6N]; [7N; 14N]])
+        test "68439hf2f2ppp" (1N = 1N)
+        test "68439hf2f2ppp" ([| 1N; 3N |] = [| 1N ; 3N |])
+
+        test "68439hf2f2m" (MG.getCol (gmatrix [[1N;2N]; 
+                                          [3N;4N]]) 0 =
+                                 gvector [1N;
+                                         3N])
+
+        test "68439hf2f2q" (MG.getRow (gmatrix [[1N;2N]; 
+                                          [3N;4N]]) 0 =
+                                 growvec [1N;2N])
+
+        test "68439hf2f2w" (MG.getRow (gmatrix [[1N;2N]; 
+                                          [3N;4N]]) 1 =
+                                 growvec [3N;4N])
+
+        test "68439hf2f2e" (MG.getRows (gmatrix [[1N;2N]; 
+                                          [3N;4N]]) 1 1 =
+                                  (MG.ofRowVector (growvec [3N;4N])))
+
+        test "68439hf2f2r" (MG.getCols (gmatrix [[1N;2N]; 
+                                                 [3N;4N]]) 0 1 =
+                                  (V (gvector [1N;3N])))
+        test "68439hf2f2t" (MG.getRegion (gmatrix [[1N;2N]; 
+                                                   [3N;4N]]) 0 1 1 1 =
+                                  (gmatrix[[2N]]))
+
+
+    [<Test>]
+    member this.FloatMatrixPerfTest() = 
+
+        let m = matrix [[1.0;2.0;1.0];
+                        [3.0;8.0;5.0];
+                        [4.0;2.0;1.0]]
+
+        let d = determinant m
+        test "caeirj20" (d = 6.0)
+
+        for i = 0 to 100000 do
+          ignore(determinant m)
+        done
+        for i = 0 to 100000 do
+          ignore(m .* m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m * m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m + m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m * m * m)
+        done
+
+    [<Test>]
+    member this.Float32MatrixPerf() = 
+
+        let m = gmatrix [[1.0f;2.0f;1.0f];
+                        [3.0f;8.0f;5.0f];
+                        [4.0f;2.0f;1.0f]]
+
+
+        for i = 0 to 100000 do
+          ignore(m .* m)
+        done
+
+        for i = 0 to 100000 do
+          ignore(m * m)
+        done
+    
+    [<Test>]
+    member this.GMatrixOpsAtComplexTest() = 
+
+        let R r = complex r 0.0
+        let I i = complex 0.0 i
+        test "989w42rr" (MG.get (gmatrix [[R 1.0;R 2.0;R 1.0]]) 0 0 = R 1.0)
+        test "989h42rr" ((gmatrix [[R 1.0;R 2.0;R 1.0]]).Dimensions = (1,3))
+        test "8f3fo3ij" ((gmatrix [[R 1.0];[R 2.0];[R 1.0]]).Dimensions = (3,1))
+        test "28439hf2f2" (MG.toScalar (MG.mul (gmatrix [[R 1.0;R 2.0;R 1.0]]) (gmatrix [[R 1.0];[R 2.0];[R 1.0]])) = R 6.0)
+        test "28439hf2f2" (MG.toScalar (gmatrix [[R 1.0;R 2.0;R 1.0]] * gmatrix [[R 1.0];[R 2.0];[R 1.0]]) = R 6.0)
+        test "28439hf2f2" (MG.toScalar (gmatrix [[R 1.0;R 2.0]; [R 3.0;R 4.0]] * 
+                              gmatrix [[R 1.0;R 2.0];[R 1.0;R 2.0]]) = R 3.0)
+        test "28439hf2f2" (compare (gmatrix [[R 1.0]]) (gmatrix [[R 1.0]]) = 0)
+        test "28439hf2f2" (compare (gmatrix [[R 1.0]]) (gmatrix [[R 2.0]]) = -1)
+        test "28439hf2f2" (compare (gmatrix [[R 2.0]]) (gmatrix [[R 1.0]]) = 1)
+        test "28439hf2f2" (-(gmatrix [[R 2.0; -R 1.0]]) = gmatrix [[-R 2.0; R 1.0]])
+        test "28439hf2f2" (gmatrix [[R 1.0;R 2.0]; [R 3.0;R 4.0]] * gmatrix [[R 1.0;R 2.0]; [R 1.0;R 2.0]] = gmatrix [[R 3.0;R 6.0]; [R 7.0; R 14.0]])
+        test "28439hf2f2" (MG.getCol (gmatrix [[R 1.0;R 2.0]; 
+                                          [R 3.0;R 4.0]]) 0 =
+                                 gvector [R 1.0;
+                                         R 3.0])
+
+        test "28439hf2f2" (MG.getRow (gmatrix [[R 1.0;R 2.0]; 
+                                          [R 3.0;R 4.0]]) 0 =
+                                 growvec [R 1.0;R 2.0])
+
+        test "28439hf2f2" (MG.getRow (gmatrix [[R 1.0;R 2.0]; 
+                                          [R 3.0;R 4.0]]) 1 =
+                                 growvec [R 3.0;R 4.0])
+
+        test "28439hf2f2" (MG.getRows (gmatrix [[R 1.0;R 2.0]; 
+                                          [R 3.0;R 4.0]]) 1 1 =
+                                  (MG.ofRowVector (growvec [R 3.0;R 4.0])))
+
+        test "28439hf2f2" (MG.getCols (gmatrix [[R 1.0;R 2.0]; 
+                                          [R 3.0;R 4.0]]) 0 1 =
+                                  (V (gvector [R 1.0;R 3.0])))
+        test "28439hf2f2" ((gmatrix [[R 1.0;R 2.0]; 
+                                     [R 3.0;R 4.0]]).Region(0,1,1,1) =
+                                  (gmatrix[[R 2.0]]))
+
+        (* Test norm functions on gmatrix, note, there are 2 norm functions on gmatrix.
+         * One fast-path that assumes float elt type, one assuming generic element type.
+         * Similarly, two Vector norms to test.
+         * No RowVector norm.
+         *)
+
+        test "norm-gmatrix-generic-int32"   (MG.norm (MG.init 2 2 (fun _ _ -> 11))    = 22.0)
+        test "norm-gmatrix-generic-int64"   (MG.norm (MG.init 2 2 (fun _ _ -> 11L))   = 22.0)
+        test "norm-gmatrix-generic-float"   (MG.norm (MG.init 2 2 (fun _ _ -> 11.0))  = 22.0)
+        test "norm-gmatrix-generic-float32" (MG.norm (MG.init 2 2 (fun _ _ -> 11.0f)) = 22.0)
+        test "norm-gmatrix-generic-bigint"  (MG.norm (MG.init 2 2 (fun _ _ -> 11I))   = 22.0)
+        test "norm-gmatrix-generic-bignum"  (MG.norm (MG.init 2 2 (fun _ _ -> 11N))   = 22.0)
+        test "norm-gmatrix-float"           (MDouble .norm (MDouble .init 2 2 (fun _ _ -> 11.0))  = 22.0)
+
+        test "norm-vector-generic-int32"   (VGeneric.norm (VGeneric.init 4 (fun _ -> 11))    = 22.0)
+        test "norm-vector-generic-int64"   (VGeneric.norm (VGeneric.init 4 (fun _ -> 11L))   = 22.0)
+        test "norm-vector-generic-float"   (VGeneric.norm (VGeneric.init 4 (fun _ -> 11.0))  = 22.0)
+        test "norm-vector-generic-float32" (VGeneric.norm (VGeneric.init 4 (fun _ -> 11.0f)) = 22.0)
+        test "norm-vector-generic-bigint"  (VGeneric.norm (VGeneric.init 4 (fun _ -> 11I))   = 22.0)
+        test "norm-vector-generic-bignum"  (VGeneric.norm (VGeneric.init 4 (fun _ -> 11N))   = 22.0)
+        test "norm-vector-float"           (VDouble .norm (VDouble .init 4 (fun _ -> 11.0))  = 22.0)
+
+        (* norm is not provided on RowVector...
+        module RGeneric = Math.RowVector.Generic
+        module RDouble  = Math.RowVector
+        test "norm-rowvector-generic-float" (RGeneric.norm (RGeneric.init 4 (fun _ -> 1.1)) = 2.2)
+        test "norm-rowvector-float"         (RDouble .norm (RDouble .init 4 (fun _ -> 1.1)) = 2.2)
+        *)   
+
+    [<Test>]
+    member this.SizeOfFormattedMatrix() = 
+
+        //check the number of characters in this display is < 100000. In reality it displays 100 x 100, around 74000 characters
+        test "vrkomvrwe0" ((sprintf "%A" (matrix [ for i in 0 .. 1000 -> [ for j in 0 .. 1000 -> float (i+j) ] ])).Length < 100000)
+        //check the number of characters in this display is < 10000. In reality it displays 50 x 50, around 7000 characters
+        test "vrkomvrwe0" (((matrix [ for i in 0 .. 1000 -> [ for j in 0 .. 1000 -> float (i+j) ] ]).ToString()).Length < 10000)
+
+(* Regression 3716: ensure the members/properties mentioned in matrix Obsolete redirect messages exist *)
+module M3716 = begin
+  open Microsoft.FSharp.Math
+  let check_Dimensions     (m:matrix) = m.Dimensions     : int * int
+  let check_NumRows        (m:matrix) = m.NumRows        : int
+  let check_NumCols        (m:matrix) = m.NumCols        : int
+  let check_NonZeroEntries (m:matrix) = m.NonZeroEntries : seq<int * int * float> 
+  let check_Column         (m:matrix) = m.Column         : int -> Vector<float>
+  let check_Row            (m:matrix) = m.Row            : int -> RowVector<float>
+  let check_Columns        (m:matrix) = m.Columns        : int  * int -> Matrix<float>
+  let check_Rows           (m:matrix) = m.Rows           : int  * int -> Matrix<float>
+  let check_Region         (m:matrix) = m.Region         : int  * int * int * int -> Matrix<float>
+  let check_Diagonal       (m:matrix) = m.Diagonal       : Vector<float>
+  let check_ElementOps     (m:matrix) = m.ElementOps     : INumeric<float>
+end
+
+module Numeric = 
+
+    open System
+
+    open Microsoft.FSharp.Math
+    module LinearAlgebra = begin
+
+        open Microsoft.FSharp.Core
+        open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
+        open Microsoft.FSharp.Core.Operators
+        open Microsoft.FSharp.Collections
+        open Microsoft.FSharp.Math
+
+        let inline sumfR f (a,b) =
+            let mutable res = 0.0 in
+            for i = a to b do
+                res <- res + f i;
+            done;
+            res
+
+        (*----------------------------------------------------------------------------
+        !* predicates
+         *--------------------------------------------------------------------------*)
+
+        let isSymmetric a = a |> Matrix.foralli (fun i j aij -> aij = a.[j,i]) 
+        let isLowerTriangular a = a |> Matrix.foralli (fun i j aij -> i>=j || aij=0.0)
+
+        (*----------------------------------------------------------------------------
+        !* choleskyFactor
+         *--------------------------------------------------------------------------*)
+
+        let choleskyFactor (a: matrix) =
+          let nA,mA = a.Dimensions in
+          if nA<>mA              then invalid_arg "choleskyFactor: not square";
+          if not (isSymmetric a) then invalid_arg "choleskyFactor: not symmetric";
+          let lres = Matrix.zero nA nA  in(* nA=mA *)
+          for j=0 to nA-1 do
+            for i=j to nA-1 do (* j <= i *)
+              (* Consider a_ij = sum(k=0...n-1)  (lres_ik . lresT_kj)
+               *               = sum(k=0...n-1)  (lres_ik . lres_jk)
+               *               = sum(k=0...j-1)  (lres_ik . lres_jk) + lres_ij . lres_jj + (0 when k>j)
+               *               = psum                                + lres_ij . lres_jj
+               * This determines lres_ij terms of preceding terms.
+               * lres_ij depends on lres_ik and lres_jk (and maybe lres_ii) for k<i
+               *)
+              let psum = sumfR (fun k -> lres.[i,k] * lres.[j,k]) (0,j-1) in
+              let a_ij = a.[i,j] in
+              if i=j then
+                lres.[i,i] <- (System.Math.Sqrt (a_ij - psum))
+              else
+                lres.[i,j] <- ((a_ij - psum) / lres.[j,j])
+            done
+          done;
+          // if not (isLowerTriangular lres) then failwith "choleskyFactor: not lower triangular result";
+          lres
+
+        (*----------------------------------------------------------------------------
+        !* lowerTriangularInverse
+         *--------------------------------------------------------------------------*)
+            
+        let lowerTriangularInverse (l: matrix) =
+          (* Given l s.t. LT: l is lower_triangular (l_ij = 0 when i<j).
+           * Finds res s.t. l.res = id *)
+          let nA,mA = l.Dimensions in
+          let res = Matrix.zero nA nA  in (* nA=mA *)
+          for j=0 to nA-1 do
+            for i=j to nA-1 do (* j <= i *)
+              (* Consider id_ij = sum(k=0...n-1)  (l_ik . res_kj)
+               *                = sum(k=0...i-1)  (l_ik . res_kj) + l_ii . res_ij + (0 when k>i by LT)
+               *                = psum                            + l_ii . res_ij
+               * Have res_ij terms of res_kj for k<i and l_??.
+               *)
+              let psum   = sumfR (fun k -> l.[i,k] * res.[k,j]) (0,i-1) in
+              let id_ij  = if i=j then 1.0 else 0.0 in
+              let res_ij = (id_ij - psum) / l.[i,i] in
+              res.[i, j] <- res_ij
+            done
+          done;
+          res
+
+
+        (*----------------------------------------------------------------------------
+        !* symmetricInverse
+         *--------------------------------------------------------------------------*)
+
+        let symmetricInverse a =
+          (* Given a symmetric matix.
+           * Have l s.t. a = l . transpose(l)  where l is lowerTriangular.
+           * Have l_inv s.t. l.l_inv = id
+           * Have a_inv = transpose(l_inv).l_inv
+           *)
+          let l     = choleskyFactor a         in
+          let l_t   = l.Transpose                in 
+          let l_inv = lowerTriangularInverse l in
+          let a_inv = l_inv.Transpose * l_inv in
+          a_inv
+
+
+        (*----------------------------------------------------------------------------
+        !* determinant 
+         *--------------------------------------------------------------------------*)
+
+
+        let determinant (a: matrix) =
+          (* Allocates lists to manage walk over permutations.
+           * Iterating through permutations a mutable array may help GC.
+           *)
+          let rec det js ks =
+            match ks with
+              | []    -> 1.0
+              | k::ks -> 
+                let rec split sign (preJs,js) =
+                  match js with
+                  | []    -> 0.0
+                  | j::js -> sign * a.[j,k] * det (List.rev preJs @ js) ks
+                             +
+                             split (0.0 - sign) (j::preJs,js) in
+                split 1.0 ([],js) in
+          let nA,mA = a.Dimensions in
+          if nA<>mA then invalid_arg "determinant: not square";
+          det [0..nA-1] [0..nA-1]
+
+        let cholesky a =
+          let l    = choleskyFactor         a in
+          let lInv = lowerTriangularInverse l in
+          l,lInv
+
+    end
+    module Notation = begin
+
+        type matrix = Matrix<float>
+        type vector = Vector<float>
+        type rowvec = RowVector<float>
+        type complex = Complex
+      
+        module Generic = begin
+            type 'a matrix = Matrix<'a>
+            type 'a vector = Vector<'a>
+            type 'a rowvec = RowVector<'a>
+            type complex = Complex
+          
+            let complex x y = Complex.mkRect (x,y)
+            let matrix ll = Matrix.Generic.ofSeq ll
+            let vector l = Vector.Generic.ofSeq  l
+            let rowvec l = RowVector.Generic.ofSeq l
+            let S x = Matrix.Generic.ofScalar x
+            let RV x = Matrix.Generic.ofRowVector x 
+            let V x  = Matrix.Generic.ofVector x
+            let M2V x = Matrix.Generic.toVector x
+            let M2RV x = Matrix.Generic.toRowVector x
+            let M2S x = Matrix.Generic.toScalar x
+        end    
+
+        let complex x y = Complex.mkRect (x,y)
+        // Notational conveniences
+        let matrix ll = Matrix.ofSeq ll
+        let vector l = Vector.ofSeq l
+        let rowvec l = RowVector.ofSeq l
+        let S x = Matrix.ofScalar x
+        let RV x = Matrix.ofRowVector x 
+        let V x  = Matrix.ofVector x
+        let M2V x = Matrix.toVector x
+        let M2RV x = Matrix.toRowVector x
+        let M2S x = Matrix.toScalar x
+    end
+
+
+    open LinearAlgebra
+    open Notation 
+
+    let abs x = if x<0. then -. x   else x
+    let neg x = -. x
+
+    let poly x cs =
+      (* eval a poly expansion - could take a precision and terminate early... *)
+      let rec eval (* i *) acc cs xi = 
+        match cs with
+        | []    -> acc
+        | c::cs -> eval (* i+1 *) (acc + c * xi) cs (x * xi)
+      in
+      eval (* i=0 *) 0.0 cs 1.
+
+    let powerseries x cs =
+      (* eval a poly expansion - and divide by factorials along the way *)
+      let rec eval i acc cs xi ifact = 
+        match cs with
+        | []    -> acc
+        | c::cs -> eval (i+1) (acc + (c * xi) / ifact) cs (x * xi) (ifact * (float (i+1)))
+      in
+      eval 0 0.0 cs 1. 1. 
+
+    (*check*)
+    let e   = powerseries 1. [1.; 1.;1.; 1.;1.; 1.;1.; 1.;1.; 1.;1.; 1.;1.; 1.;]
+    let pi  = 2. * asin 1.0      
+
+
+    (*----------------------------------------------------------------------------
+    !* erfc - complementary error function and inverse
+     *--------------------------------------------------------------------------*)
+
+    (* NOTE: got sign wrong in poly factorisation *)  
+    let erfc x =
+      if x = neg_infinity then 2.0 else
+      if x = infinity then 0.0 else
+      let z = abs x in
+      let t = 1.0 / (1.0 + 0.5 * z) in
+      let y = t * exp (-. z*z 
+                       +. poly t [ -1.26551223;  1.00002368; 0.37409196;  0.09678418; -0.18628806;
+                                    0.27886807; -1.13520398; 1.48851587; -0.82215223;  0.17087277])
+      in
+      if x >= 0.0 then y else 2.0 - y
+
+    let erfcinv y =
+      if (y < 0. || y > 2.) then failwith "Inverse complementary function not defined outside [0,2]." else
+      if (y = 0.) then infinity else
+      if (y = 2.) then neg_infinity else
+      let central y =
+        let q = y - 1.0 in
+        let r = q * q in
+          poly r   [ - 0.8862269264526915; 2.710410832036097; -3.057303267970988;
+                     1.524304069216834; -0.3051415712357203; 0.01370600482778535 ]
+          * q
+          / poly r [ 1.0                ; -3.320170388221430;  4.175081992982483;
+                     - 2.432796560310728; 0.6311946752267222; -0.05319931523264068 ]
+      in
+      let lower y =
+        (* Rational approximation lower region *)
+          let q = sqrt (-2.0 * log (y / 2.0)) in
+          poly q [-2.077595676404383; -3.093354679843504;  1.802933168781950;
+                   1.697592457770869;  0.2279687217114118; 0.005504751339936943;] /
+          poly q [ 1.0;                3.754408661907416;  2.445134137142996;
+                   0.3224671290700398; 0.007784695709041462]
+      in
+      let upper y =
+        let  q = sqrt (-2.0 * log (1. - y / 2.0)) in
+        -.
+          poly q [ -2.077595676404383; -3.093354679843504;  1.802933168781950;
+                   1.697592457770869;  0.2279687217114118; 0.005504751339936943] /
+          poly q [ 1.0;                 3.754408661907416;  2.445134137142996;
+                    0.3224671290700398;  0.007784695709041462;
+                 ]
+      in
+      let halleys x = (* One iteration of Halley's rational method (third order) gives full machine precision. *)
+        let u = (erfc (x) - y) / (-2.0 / sqrt pi * exp (-. x * x)) in
+        x - u / (1.0 + x * u)
+      in
+     (* compute x according to region *)
+      let x =
+        if (y  >= 0.0485 && y <= 1.9515) then central y else
+        if (y < 0.0485) then lower y else
+        (* y > 1.9515 *) upper y
+      in
+      (* iterate halleys once *)
+      halleys x
+
+
+    (*----------------------------------------------------------------------------
+    !* phi and phi_inv - complementary error function 
+     *--------------------------------------------------------------------------*)
+      
+    let root2 = sqrt 2.0
+    let phi     t = erfc(-. t / root2) / 2.
+    let phi_inv p = -. root2 * erfcinv (2. * p)
+
+    let Phi t = phi t
+    let Phi_Inv p = phi_inv p
+
+
+    (*----------------------------------------------------------------------------
+    !* normalpdf, v3, w3
+     *--------------------------------------------------------------------------*)
+      
+    /// <summary>
+    /// Computes the normal density at a specified point of interest.
+    /// </summary>
+    /// <param name="t">The point of interest.</param>
+    /// <returns>The normal density at the point of interest.</returns>
+    let dSqrt2Pi = 2.5066282746310002 (* not checked *)
+    let normalpdf t = 1.0 / dSqrt2Pi * exp (-. t*t / 2.0)
+
+    /// <summary>
+    /// Computes the additive correction of a single-sided truncated Gaussian with unit variance.
+    /// </summary>
+    /// <param name="t">The mean of the non-truncated Gaussian.</param>
+    /// <param name="epsilon">The truncation point.</param>
+    /// <returns>The additive correction.</returns>
+    let doubleEpsilon = System.Double.Epsilon
+    let v t epsilon =
+      let dNumerator = normalpdf (t - epsilon) in
+      let dDenominator = phi (t - epsilon) in
+      if dDenominator < sqrt doubleEpsilon then
+        0.0-t + epsilon
+      else
+       dNumerator / dDenominator
+
+    /// <summary>
+    /// Computes the additive correction of a general double-sided truncated Gaussian with unit variance.
+    /// </summary>
+    /// <param name="t">The mean of the non-truncated Gaussian.</param>
+    /// <param name="l">The lower truncation point.</param>
+    /// <param name="u">The upper truncation point.</param>
+    /// <returns>The additive correction.</returns>
+    /// <remarks>This routine has not been tested in all regimes of t for a given l and u.</remarks>
+    /// <exception cref="ArithmeticException">Thrown if the computation is not numerically stable.</exception>
+    let v3 t l u =
+      let dNumerator = normalpdf (t - l) - normalpdf (t - u) in
+      let dDenominator = phi (u - t) - phi (l - t) in
+      if (dDenominator < sqrt (doubleEpsilon)) then
+        failwith "Unsafe v3 call" (* raise (new System.ArithmeticException("Unsafe computation of v"))*)
+        (* failwith "Unsafe computation of v" // was arithmetic exception *)
+      else
+        if t<0.0 then (* MatLab version only, not C# *)
+          (0.0 - dNumerator) / dDenominator
+        else
+          dNumerator / dDenominator
+
+    /// <summary>
+    /// Computes the multiplicative correction of a general double-sided truncated Gaussian with unit variance.
+    /// </summary>
+    /// <param name="t">The mean of the non-truncated Gaussian.</param>
+    /// <param name="l">The lower truncation point.</param>
+    /// <param name="u">The upper truncation point.</param>
+    /// <returns>The multiplicative correction.</returns>
+    /// <remarks>This routine has not been tested in all regimes of t for a given l and u.</remarks>
+    /// <exception cref="ArithmeticException">Thrown if the computation is not numerically stable.</exception>
+    let w3 t l u =
+      let dNumerator = (u - t) * normalpdf (u - t) - (l - t) * normalpdf (l - t) in
+      let dDenominator = phi (u - t) - phi (l - t) in
+      if (dDenominator < sqrt (doubleEpsilon)) then
+        failwith "unsafe w3 call" (* raise (new ArithmeticException ("Unsafe computation of v")) *)
+      else
+        let z = v3 t l u in
+        z * z + dNumerator / dDenominator
+
+
+    (*----------------------------------------------------------------------------
+    !* streams
+     *--------------------------------------------------------------------------*)
+
+    type 'a stream = SCONS of (unit -> ('a * 'a stream))  (* fully suspended *)
+    let rec constS x = SCONS (fun () -> (x,constS x))
+    let rec unfoldS   f z = SCONS (fun () -> let z,x = f z in x,unfoldS f z)
+    let rec generateS f   = SCONS(fun () -> f (),generateS f)
+    let pullS (SCONS xtailf) = xtailf()
+    let listS xs =
+      let pull = function (x::xs) -> xs,x | [] -> failwith "listS: exhausted points" in
+      unfoldS pull xs
+    let rec takeS n s = if n=0 then [] else let x,s = pullS s in x::takeS (n-1) s
+
+
+    (*----------------------------------------------------------------------------
+    !* streams - random, neiderreiter
+     *--------------------------------------------------------------------------*)
+    let randomM m n = Matrix.randomize (Matrix.zero m n)       
+    let randomPts dim = generateS (fun () -> randomM dim 1)
+
+    (* Neiderreiter series:
+     * Definition extracted from C# code.
+     * To generate npts random points of dimension d.
+     * 
+     * For k = 0 to npts-1   // over pts 
+     *  For i = 0 to ndims-1 // over dimension
+     *  
+     *   p(k).[i] = let t = (k+1).Neiderreiter(i)
+     *              in  abs(2*fract(t) - 1)
+     *
+     * where fract(t) = t - floor(t)
+     * where Neiderreiter(i) = 2 ^ ( (i+1)/(ndims+1) )
+     *
+     * So, Neiderreiter(i) falls inside [1,2].
+     *)
+    let neiderreiterS dim npts =
+      let fract x = x - floor x in
+      let neiderreiter  = Matrix.init dim 1 (fun i _ -> 2. ** (float (i + 1) / float (dim + 1))) in
+      let mkPoint k = Matrix.init dim 1 (fun i _ -> let t = float(k + 1) * Matrix.get neiderreiter i 0 in
+                                                    let x = abs (2.0 * fract t - 1.0) in
+                                                    assert (0.0 <= x && x <= 1.0);
+                                                    x)
+      in
+      let step k = if k<npts then k+1,mkPoint k
+                             else failwith "neiderreiterS: exhausted points"
+      in
+      unfoldS step 0
+
+    let dim,npts = 3,100
+    let pts = takeS npts (neiderreiterS dim npts)
+
+
+    (*----------------------------------------------------------------------------
+    !* unitIntegrals
+     *--------------------------------------------------------------------------*)
+
+    let unitIntegralOverPts pts nPts f =
+      (* unit integral of f by averaging nPts samples of f at pt where pt drawn from pts *)
+      let rec sum i total f pts =
+        if i=nPts then total
+                  else let pt,pts = pullS pts in
+                       let total = total + f pt in
+                       sum (i + 1) total f pts
+      in
+      sum 0 0. f pts / float nPts
+
+    let unitIntegralOverRandomPoints dim nPts f =
+      (* unit integral of f by averaging nPts samples of f at a random pt *)  
+      let eval () = let w = randomM dim 1 in
+                    f w
+      in
+      let sum = seq { for i in 0 .. nPts-1 -> eval() } |> Seq.fold (+) 0.0 in 
+      let res = sum / float nPts in
+      res
+
+    let f v = let x = Matrix.get v 0 0 in x*x  (* [1/3 x^3] 0,1 = 1/3 *)
+    let x1 = unitIntegralOverRandomPoints 1             1000 f   (* random pts *)
+    let x2 = unitIntegralOverPts (randomPts 1)          1000 f   (* random pt sequence *)
+    let x3 = unitIntegralOverPts (neiderreiterS 1 1000) 1000 f   (* pseudo random pt sequence *)
+
+
+    (*----------------------------------------------------------------------------
+    !* weightedGaussian - alg 9
+     *--------------------------------------------------------------------------*)
+
+    (* weightedGaussian: implements algorithm 8 *)
+    let weightedGaussian unitIntegrate g (mu:Matrix<_>,sigma:Matrix<_>) (alpha:Matrix<_>,beta:Matrix<_>) =
+      printf "dim(sigma) = %d,%d\n" sigma.NumRows sigma.NumCols;
+      printf "dim(mu) = %d,%d\n" mu.NumRows mu.NumCols;
+      printf "dim(alpha) = %d,%d\n" alpha.NumRows alpha.NumCols;
+      printf "dim(beta) = %d,%d\n" beta.NumRows beta.NumCols;
+      let l     = choleskyFactor sigma in
+      printf "dim(l) = %d,%d\n" l.NumRows l.NumCols;
+      let l_inv = lowerTriangularInverse l in
+      printf "dim(l_inv) = %d,%d\n" l_inv.NumRows l_inv.NumCols;
+      (* apply mu subst and L_inv subst *)
+      let alpha'  = l_inv * (alpha - mu) in
+      let beta'   = l_inv * (beta  - mu) in
+      printf "dim(alpha') = %d,%d\n" alpha'.NumRows alpha'.NumCols;
+      printf "dim(beta') = %d,%d\n" beta'.NumRows beta'.NumCols;
+
+      (* apply phi_inv subst *)
+      let alpha''     = Matrix.map phi alpha' in
+      let beta''      = Matrix.map phi beta'  in
+      printf "dim(alpha'') = %d,%d\n" alpha''.NumRows alpha''.NumCols;
+      printf "dim(beta'') = %d,%d\n" beta''.NumRows beta''.NumCols;
+      let alphabeta'' = beta'' - alpha'' in
+      (* reduced to unit integral *)
+      let eval w =
+        let v = alpha'' + (w .* alphabeta'') in
+        let z = Matrix.map phi_inv v in
+        let x = (l * z) + mu in
+        g x
+      in
+      unitIntegrate eval
+
+    let g v = let x = Matrix.get v 0 0 in
+              let y = Matrix.get v 1 0 in
+              x*y*y
+
+    (*	    
+    let integrate3 = weightedGaussian
+    let res1 = integrate3 (unitIntegralOverRandomPoints 3 100)                g (mu,sigma) (alpha,beta)  
+    let res2 = integrate3 (unitIntegralOverRandomPoints 3 1000)               g (mu,sigma) (alpha,beta)  
+    let res3 = integrate3 (unitIntegralOverRandomPoints 3 10000)              g (mu,sigma) (alpha,beta)
+    let res4 = integrate3 (unitIntegralOverPts (neiderreiterS 3 100) 100)     g (mu,sigma) (alpha,beta)
+    let res5 = integrate3 (unitIntegralOverPts (neiderreiterS 3 1000) 1000)   g (mu,sigma) (alpha,beta)
+    let res6 = integrate3 (unitIntegralOverPts (neiderreiterS 3 10000) 10000) g (mu,sigma) (alpha,beta)
+    *)
+
+    let res1 = 
+      let mu    = Matrix.create 3 1 0.2 in
+      let sigma = Matrix.add (Matrix.create 3 3 0.2) (Matrix.init 3 3 (fun _ _ -> 2.0)) in
+      let alpha = Matrix.create 3 1 0.1 in
+      let beta  = Matrix.create 3 1 0.3 in
+      weightedGaussian (unitIntegralOverRandomPoints 3 100) g (mu,sigma) (alpha,beta)
+
+
+    (*----------------------------------------------------------------------------
+    !* expectationPropagation - alg 8
+     *--------------------------------------------------------------------------*)
+      
+    let sqr x  : float  = x*x
+    let inv x = 1.0/x
+
+    let expectationPropagation (mu,sigma:matrix) m (a:matrix[],z:_[],alpha: _[],beta: _[]) nIters =
+
+      let mu0 = mu in
+
+      let mutable muHat    = mu0   in     
+      let mutable sigmaHat = sigma in     
+      let mu = Vector.create m 0.0 in  // nb: rebinds mu 
+      let pi = Vector.create m 0.0 in
+      let s  = Vector.create m 1.0 in
+
+      (* pre-compute *)
+      let aT = a |> Array.map (fun ai ->    printf "dim(ai) = %d,%d\n" ai.NumRows ai.NumCols; ai.Transpose)  in
+      Printf.printf "sigmaHat=\n%O\n\n" sigmaHat;
+
+      for i = 1 to nIters do
+       for j = 0 to m-1 do
+        Printf.printf "i=%d,j=%d,sigmaHat=\n%O\n\n" i j sigmaHat;
+
+        (* Pre-computations for jth factor *)    
+        let u_j      = sigmaHat * a.[j] in
+        Printf.printf "i=%d,j=%d,u_j=\n%O\n\n" i j u_j;
+
+        let c_j      = aT.[j] * u_j   |> Matrix.toScalar in
+        Printf.printf "i=%d,j=%d,c_j=\n%O\n\n" i j c_j;
+        let m_j      = aT.[j] * muHat |> Matrix.toScalar in
+        Printf.printf "i=%d,j=%d,m_j=\n%O\n\n" i j m_j;
+        let d_j      = pi.[j] * c_j in
+        Printf.printf "i=%d,j=%d,d_j=\n%O\n\n" i j d_j;
+        let phi_j    = m_j + d_j / (1.0 - d_j) * (m_j - mu.[j]) in
+        Printf.printf "i=%d,j=%d,phi_j=\n%O\n\n" i j phi_j;
+        let psi_j    = c_j / (1.0 - d_j) in
+        Printf.printf "i=%d,j=%d,psi_j=\n%O\n\n" i j psi_j;
+        let alpha_j  = alpha.[j] phi_j psi_j in
+        Printf.printf "i=%d,j=%d,alpha_j=\n%O\n\n" i j alpha_j;
+        let beta_j   = beta.[j]  phi_j psi_j in
+        Printf.printf "i=%d,j=%d,beta_j=\n%O\n\n" i j beta_j;
+       (* ADF update *)
+        muHat    <- (let factor = (pi.[j] * (m_j - mu.[j]) + alpha_j)  /  (1.0 - d_j) in muHat + (factor * u_j))
+        Printf.printf "i=%d,j=%d,muHat=\n%O\n\n" i j muHat;
+        sigmaHat <- (let factor = (pi.[j] * (1.0 - d_j) - beta_j)  /  (1.0 - d_j) ** 2.0 in sigmaHat + (factor * (u_j * u_j.Transpose)));
+        Printf.printf "i=%d,j=%d,ie1=\n%O\n\n" i j ((1.0 - d_j) ** 2.0);
+        Printf.printf "i=%d,j=%d,ie2=\n%O\n\n" i j u_j.Transpose;
+        Printf.printf "i=%d,j=%d,ie3=\n%O\n\n" i j ((pi.[j] * (1.0 - d_j) - beta_j));
+        Printf.printf "i=%d,j=%d,ie4=\n%O\n\n" i j ((pi.[j] * (1.0 - d_j) - beta_j)  /  (1.0 - d_j) ** 2.0);
+        Printf.printf "i=%d,j=%d,ie5=\n%O\n\n" i j (let factor = (pi.[j] * (1.0 - d_j) - beta_j)  /  (1.0 - d_j) ** 2.0 in factor * (u_j * u_j.Transpose));
+        Printf.printf "i=%d,j=%d,sigmaHat=\n%O\n\n" i j sigmaHat;
+        (* Factor update *)
+        pi.[j] <- 1.0 / (inv beta_j - psi_j);
+        mu.[j] <- alpha_j / beta_j + phi_j;
+        s.[j]  <- z.[j] phi_j psi_j * exp ( sqr(alpha_j) / (2.0 * beta_j)) / sqrt (1.0 - psi_j * beta_j);
+       done;
+      done;
+
+
+      (* result *)
+      let sigmaInv    = symmetricInverse sigma     in
+      let sigmaHatInv = symmetricInverse sigmaHat in (* invertible? *)
+
+      let zHat =
+        Vector.prod s *
+        sqrt (determinant (sigmaHat * sigmaInv)) *
+        exp (-0.5 * ( Vector.dot pi (mu .* mu)
+                + Matrix.toScalar (mu0.Transpose  *  sigmaInv * mu0)
+                - Matrix.toScalar (muHat.Transpose * sigmaHatInv * muHat)))
+      in
+      muHat, sigmaHat, zHat
+
+
+
+    type floatf = float -> float -> float
+
+    let expectationPropagationB 
+         (mu,sigma:matrix) 
+         m 
+         (a : matrix[]) 
+         (z : floatf[])
+         (alphas: floatf [])
+         (betas : floatf [])
+         nIters =
+
+      let mu0 = mu in
+
+      let mutable muHat    = mu0   in     
+      let mutable sigmaHat = sigma in     
+      let mu = Vector.create m 0.0 in  // nb: rebinds mu 
+      let pi = Vector.create m 0.0 in
+      let s  = Vector.create m 1.0 in
+
+      // pre-compute 
+      let aT = a |> Array.map (fun ai ->  ai.Transpose)  in
+
+      for i = 1 to nIters do
+       for j = 0 to m-1 do
+
+        // Pre-computations for jth factor 
+        let u      = sigmaHat * a.[j] in
+
+        let c      = aT.[j] * u   |> M2S in
+        let m      = aT.[j] * muHat |> M2S in
+        let d      = pi.[j] * c in
+        let phi    = m + d / (1.0 - d) * (m - mu.[j]) in
+        let psi    = c / (1.0 - d) in
+        let alpha  = alphas.[j] phi psi in
+        let beta   = betas.[j]  phi psi in
+       // ADF update 
+        muHat    <- (let factor = (pi.[j] * (m - mu.[j]) + alpha)  /  (1.0 - d) in
+                     muHat + (factor * u))
+        sigmaHat <- (let factor = (pi.[j] * (1.0 - d) - beta)  /  (1.0 - d) ** 2.0 in
+                     sigmaHat + (factor * (u * u.Transpose)))
+        // Factor update 
+        pi.[j] <- 1.0 / (inv beta - psi);
+        mu.[j] <- alpha / beta + phi;
+        s.[j]  <- z.[j] phi psi * exp ( sqr(alpha) / (2.0 * beta)) / sqrt (1.0 - psi * beta);
+       done;
+      done;
+
+
+      (* result *)
+      let sigmaInv    = symmetricInverse sigma     in
+      let sigmaHatInv = symmetricInverse sigmaHat in (* invertible? *)
+
+      let zHat =
+        Vector.prod s *
+        sqrt (determinant (sigmaHat * sigmaInv)) *
+        exp (-0.5 * ( Vector.dot pi (mu .* mu)
+                 + M2S (mu0.Transpose  *  sigmaInv * mu0)
+                 - M2S (muHat.Transpose * sigmaHatInv * muHat)))
+      in
+      muHat, sigmaHat, zHat
+
+    (*----------------------------------------------------------------------------
+    !* The MatLab version with hardwired functions
+     *--------------------------------------------------------------------------*)
+
+    let getV m i   = Matrix.get m i 0
+    let setV m i x = Matrix.set m i 0 x
+
+    (* TODO: syntax for matrix indexing and assignment *)
+    (* Recoded MatLab version *)
+    let zeros d = Matrix.create d 1 0.0
+    let expectationPropagationMatLab (mu,sigma) m (l,u) noIterations =
+      let siteMu            = zeros m in
+      let sitePi            = zeros m in
+      let siteS             = zeros m in
+      let newMu          = ref mu      in
+      let newSigma        = ref sigma   in
+
+      for i = 0 to noIterations-1 do
+        for j = 0 to m-1 do 
+          // prepare computation    
+          let t      = Matrix.init m 1 (fun i _ -> Matrix.get !newSigma i j) in
+          let d  = getV sitePi j * Matrix.get !newSigma j j in
+          let e  = 1.0 - d in
+          let phi  = getV !newMu j + d * (getV !newMu j - getV siteMu j) / e in
+          let psi  = Matrix.get !newSigma j j / e in
+          let sPsi  = sqrt psi in
+          let alpha  = v3 (phi / sPsi) (getV l j / sPsi) (getV u j / sPsi) / sPsi in
+          let beta  = w3 (phi / sPsi) (getV l j / sPsi) (getV u j / sPsi) / psi in
+          
+          // GDF update
+          newMu    := !newMu + (((getV sitePi j * (getV !newMu j - getV siteMu j) + alpha) / e) * t) ;
+          newSigma := !newSigma + (((getV sitePi j * e - beta) / (e * e)) * (t * Matrix.transpose t)) ;
+             
+          // Factor update
+          setV sitePi j (1.0 / (1.0/beta - psi));
+          setV siteMu j (alpha / beta + phi);
+          setV siteS  j ( (Phi ((getV u j - phi) / sPsi) - Phi ((getV l j - phi) / sPsi)) 
+                      * exp (alpha * alpha / (2.0 * beta)) / sqrt (1.0 - psi * beta))
+        done
+      done;
+      // compute the normalisation constant
+      let SigmaInv    = symmetricInverse sigma    in
+      let newSigmaInv = symmetricInverse !newSigma in
+      let Z = 
+         Matrix.prod siteS
+         * sqrt (determinant !newSigma / determinant sigma)
+         * exp (-0.5 * ( Matrix.dot sitePi (siteMu .* siteMu)
+                        + Matrix.toScalar (Matrix.transpose mu * SigmaInv * mu)
+                        - Matrix.toScalar (Matrix.transpose !newMu * newSigmaInv * !newMu)))
+      in
+      !newMu, !newSigma, Z
+
+
+    (*----------------------------------------------------------------------------
+    !* expectationPropagation - test code
+     *--------------------------------------------------------------------------*)
+
+    let mA = 1
+    let aA     = [| Matrix.create 3 1 0.2   |]
+    let zA     = [| fun (a:float) (b:float) -> a+b |]
+    let alphaA = [| fun (a:float) (b:float) -> 0.1 |]
+    let betaA  = [| fun (a:float) (b:float) -> 0.9 |]
+
+    let muA    = Matrix.create 3 1 0.2
+    let sigma' = matrix [[10.0; 2.0;-3.0];
+                         [ 2.0; 4.0; 5.0];
+                         [-3.0; 5.0;40.0]]
+    let sigmaA = Matrix.map (fun k -> k * 0.1) sigma'
+    let sInv  = symmetricInverse sigmaA (* check |R inverse exists *)
+
+
+    let nItersA = 8
+    let muHatA,sigmaHatA,zHatA = expectationPropagation (muA,sigmaA) mA (aA,zA,alphaA,betaA) nItersA
+
+    let dumpM str m = Printf.printf "%s:\n%O\n\n" str m
+    let dumpR str x = Printf.printf "%s = %f\n\n" str x
+    let _ = dumpM "muHat"    muHatA
+    let _ = dumpM "sigmaHat" sigmaHatA
+    let _ = dumpR "zHat"     zHatA
+
+
+    (*----------------------------------------------------------------------------
+    !* expectationPropagation - test code MatLab values
+     *--------------------------------------------------------------------------*)
+
+    (* Matlab:
+    >> [newMu, newSigma, evidence] = EP ([1;2],[[1 0];[0 2]], [0;0], [2; 3], 20)
+    newMu =
+        1.0000
+        1.6599
+    newSigma =
+        0.2911         0
+             0    0.6306
+    evidence =
+        0.4653
+    >>
+    >> help EP
+
+      EP		The EP algorithm for computing Gaussian approximation to a
+ 		    truncated Gaussian.
+     
+ 	    [newMu, newSigma, Z] = EP (mu, sigma, l, u, noIterations)
+     
+ 		    mu		mean of the untruncated Gaussian
+ 		    sigma		covariance of the untruncated Gaussian
+ 		    l		lower integration boundaries
+ 		    u		upper integration boundaries
+ 		    noIterations	number of iterations (default: 20)
+ 		    newMu		mean of the Gaussian approximation
+ 		    newSigma	covariance of the Gaussian approximation
+ 		    Z		normalisation constant of the untruncated Gaussian
+     
+      2005 written by Ralf Herbrich
+      Microsoft Research Ltd.
+    *)
+
+    let m = 2
+    let mu    = matrix [[1.0];[2.0]]
+    let sigma = matrix [[1.0; 0.0]; [0.0; 2.0]]
+    let l     = matrix [[0.0];[0.0]]
+    let u     = matrix [[2.0];[3.0]]
+    let nIters = 20
+
+    let x,y = l.Dimensions
+    let _ = assert(x=m)
+    let _ = assert(y=1)
+
+    let a     = [| matrix [[ 1.0]; [0.0 ]];
+                   matrix [[ 0.0]; [1.0 ]] |]
+                
+    (* factor l',u' *)
+    let zf j phi_j psi_j =
+      let k = inv(sqrt(psi_j)) in
+      let l_j' = Matrix.get l j 0 * k in
+      let u_j' = Matrix.get u j 0 * k in
+      phi (u_j' - phi_j * k) - phi (l_j' - phi_j * k)
+
+    let z = [| zf 0;zf 1 |]
+               
+    (* there is common code, compute both *)
+    let alpha i phi_i psi_i =
+      let root_psi_i = sqrt(psi_i) in
+      v3 (phi_i/root_psi_i) (Matrix.get l i 0 / root_psi_i) (Matrix.get u i 0 / root_psi_i) / root_psi_i
+
+    let beta i phi_i psi_i =
+      let root_psi_i = sqrt(psi_i) in
+      w3 (phi_i/root_psi_i) (Matrix.get l i 0 / root_psi_i) (Matrix.get u i 0 / root_psi_i) / psi_i
+
+        
+    let alphas = Array.init 2 (fun i -> alpha i)
+    let betas  = Array.init 2 (fun i -> beta  i)
+
+    let muHat ,sigmaHat ,zHat  = expectationPropagation (mu,sigma) m (a,z,alphas,betas) nIters
+
+    let _ = dumpM "muHat"    muHat 
+    let _ = dumpM "sigmaHat" sigmaHat   
+    let _ = dumpR "zHat"     zHat  
+
+
+
+    let muHatC,sigmaHatC,zHatC = expectationPropagationMatLab (mu,sigma) m (l,u) nIters
+
+    let _ = dumpM "muHatC"    muHatC 
+    let _ = dumpM "sigmaHatC" sigmaHatC   
+    let _ = dumpR "zHatC"     zHatC  
+
+    (*----------------------------------------------------------------------------
+    !* misc tests
+     *--------------------------------------------------------------------------*)
+
+
+    let _ = (box 1N).GetHashCode()
+    let _ = (box 1I).GetHashCode()
+    let _ = hash 10000000000000000000N
+    let _ = hash 1N
+    let _ = hash (-1N)
+    let _ = hash 1I
+    let _ = hash 1000000000000000000I
+    let _ = hash (-1I)
+    let _ = hash (-10000000000000000000000000000000000000000I)
+
+
+    (*----------------------------------------------------------------------------
+    !* comparison code
+     *--------------------------------------------------------------------------*)
+
+    
+    (*
+
+    // specific alpha and gamma functions
+    let alpha i phi psi (lower:matrix) (upper:matrix) = 
+	    let spsi = sqrt (psi) in 
+	    let u = upper.Item (i, 0)/spsi in
+	    if (System.Double.IsPositiveInfinity (u)) then
+		    1.0 / spsi * GaussianApproximations.v (phi/spsi, lower.Item (i, 0)/spsi)
+	    else
+		    1.0 / spsi * GaussianApproximations.v (phi/spsi, lower.Item (i, 0)/spsi, u)
+    	
+    let gamma i phi psi (lower:matrix) (upper:matrix) = 
+	    let spsi = sqrt (psi) in 
+	    let u = upper.Item (i, 0)/spsi in
+	    if (System.Double.IsPositiveInfinity (u)) then
+		    1.0 / psi * GaussianApproximations.w (phi/spsi, lower.Item (i, 0)/spsi)
+	    else
+		    1.0 / psi * GaussianApproximations.w (phi/spsi, lower.Item (i, 0)/spsi, u)
+    	
+    *)
+
+
+    (* FRAGS: test code
+
+    let n = 150
+    let mu = new Matrix (n, 1)
+    let sigma = new Matrix (n, n)
+    let A = new Matrix (n, n)
+    let lower = new Matrix (n, 1)
+    let upper = new Matrix (n, 1)
+
+    do
+      for i = 0 to n-1 do
+        mu.Item (i, 0) <- 1.0;
+        sigma.Item (i, i) <- 1.0 + (float) i;
+        A.Item (i, i) <- 1.0;
+        lower.Item (i, 0) <- 0.0;
+        upper.Item (i, 0) <- System.Double.PositiveInfinity;
+      done  
+
+    expectationPropagationMatLab (vnoc mu,vnoc sigma) n (vnoc lower,vnoc upper) 10
+
+    *)
+
+// These are really type checking tests
+module BasicOverloadTests = 
+
+    let f1 (a:matrix) (b:matrix) = a * b
+    let f2 (a:matrix) (b:vector) = a * b
+
+    let f12 (x1: Matrix<'a>) (x2: Matrix<'a>) = x1 * x2
+    let f13 (x1: Matrix<'a>) (x2: Vector<'a>) = x1 * x2
+    let f14 (x1: RowVector<'a>) (x2: Matrix<'a>) = x1 * x2
+
+    // Traditionally we've had a hard time supporting both 
+    //    'a * Matrix<'a>  -> Matrix<'a>
+    //    Matrix<'a> * 'a  -> Matrix<'a>
+    // overloads for multiplication. However these now work correctly
+    let f15 (x1: Matrix<float>) (x2: float) = x1 * x2
+    let f16 (x1: float) (x2: Matrix<float>) = x1 * x2
+    // This is an interesting case. Strictly speaking it seems there is not enough information to resolve the
+    // overload.
+    // let f23 (x1: Matrix<_>) (x2: Matrix<_>) = x1 * x2
+
+    let f24 (x1: Matrix<int>) (x2: Matrix<_>) = x1 * x2
+
+// These are really type checking tests
+module BasicGeneralizationTests = 
+    let MFMV = Microsoft.FSharp.Math.Vector.init 3 (fun i -> float(i))
+    let _ = MFMV.[1]
+    let _ = MFMV.[1] <- 3.13
+
+    // check we have generalized 
+    let MFMV_generic_function (k: 'a) = 
+      let MFMV = Microsoft.FSharp.Math.Vector.Generic.init 3 (fun i -> k) in
+      let _ = MFMV.[1] in
+      let _ =MFMV.[1] <- k in
+      ()
+
+    // check we have generalized 
+    do MFMV_generic_function 1
+    do MFMV_generic_function "3"
+
+    let MFMM = Microsoft.FSharp.Math.Matrix.init 3 3 (fun i j -> float(i+j))
+    let _ = MFMM.[1,1]
+    let _ = MFMM.[1,1] <- 3.13
+
+    // check we have generalized 
+    let MFMM_generic_function (k: 'a) = 
+      let MFMM = Microsoft.FSharp.Math.Matrix.Generic.init 3 3 (fun i j -> k) in
+      let _ = MFMM.[1,1] in
+      let _ =MFMM.[1,1] <- k in
+      ()
+
+    // check we have generalized 
+    do MFMM_generic_function 1
+    do MFMM_generic_function "3"
+
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/MetadataTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/MetadataTests.fs
new file mode 100644
index 0000000..cddca45
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/MetadataTests.fs
@@ -0,0 +1,425 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Metadata
+
+[<TestFixture>]
+type public MetadataTests() =
+  
+
+    let fsharpLibrary = Microsoft.FSharp.Metadata.FSharpAssembly.FSharpLibrary
+
+    let okAttribs (attrs:seq<FSharpAttribute>) = 
+        attrs |> Seq.forall (fun attr -> let ty = attr.ReflectionType in ty <> typeof<System.ObsoleteAttribute> && ty <> typeof<CompilerMessageAttribute>)
+
+    let okEntity (x:FSharpEntity) = x.Attributes |> okAttribs
+
+    let okVal (x:FSharpEntity,v:FSharpMemberOrVal) = v.Attributes |> okAttribs
+
+    let explore (library:FSharpAssembly) = 
+      for x in library.Entities do 
+        let rec loop (x:FSharpEntity) = 
+            if okEntity x then
+              logMessage (sprintf "entity %s : XMLDOC SIG = %s" x.DisplayName x.XmlDocSig)
+              for x in x.NestedEntities do 
+                 loop x
+              for v in x.MembersOrValues do 
+                   if okVal (x,v) then 
+                     logMessage (sprintf "value/member %s : XMLDOC SIG = %A" v.DisplayName v.XmlDocSig)
+        loop x
+    let seqItem item s = (s |> Seq.toArray).[item]
+
+    let assertEquality (o1:obj) (o2:obj) =
+        Assert.IsTrue((o1 = o2))
+        Assert.AreEqual(o1.GetHashCode(), o2.GetHashCode())
+
+    let assertInequality (o1:obj) (o2:obj) =
+        Assert.IsFalse((o1 = o2))
+        if o1.GetHashCode() = o2.GetHashCode() then
+            printfn "Same hashcode for unequal objects %A %A" o1 o2
+
+    let strictZip c1 c2 =
+        Assert.AreEqual(Seq.length c1, Seq.length c2)
+        Seq.zip c1 c2
+
+
+    [<Test>]
+    member this.Test1() = 
+
+        let fsharpEntity1 = fsharpLibrary.Entities |> Seq.find (fun y -> y.LogicalName = "ResizeArray`1")
+
+        check "cnwoein" fsharpEntity1.IsAbbreviation true 
+
+        // This gets the abbreviation 'ResizeArray<'T> = System.Collections.Generic.List<'T>'
+        let fsharpType1 = fsharpEntity1.AbbreviatedType
+
+        check "ckwjen0o" fsharpType1.IsNamed true
+
+        let fsharpEntity2 = fsharpType1.NamedEntity
+
+        check "ckwjen0o" fsharpEntity2.IsExternal true
+
+        let systemType = fsharpEntity2.ReflectionType
+        
+        check "ckwjen01" systemType.Name "List`1"
+        
+
+    [<Test>]
+    member this.Test2() = 
+
+        check "ckwfew0o4" fsharpLibrary.QualifiedName fsharpLibrary.ReflectionAssembly.FullName
+        check "ckwfew0o4" (fsharpLibrary.QualifiedName.Contains("FSharp.Core")) true
+
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.sbyte")
+
+        check "ckwfew0o441" fsharpEntity1.IsAbbreviation true    
+
+        // This gets the abbreviation 'sbyte = System.SByte'
+        let fsharpType1 = fsharpEntity1.AbbreviatedType
+
+        check "ckwjen0o4" fsharpType1.IsNamed true
+
+        let fsharpEntity2 = fsharpType1.NamedEntity
+
+        check "ckwjen0o4" fsharpEntity2.IsExternal true
+
+        let systemType = fsharpEntity2.ReflectionType
+        
+        check "ckwjen014" systemType typeof<sbyte>
+
+
+    [<Test>]
+    member this.Test3() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.sbyte")
+
+        check "ckwfew0o41" fsharpEntity1.IsExternal false
+        check "ckwfew0o42" fsharpEntity1.IsModule false
+        check "ckwfew0o43" fsharpEntity1.IsValueType false
+        check "ckwfew0o442" fsharpEntity1.LogicalName "sbyte"
+        check "ckwfew0o443" fsharpEntity1.IsAbbreviation true
+        check "ckwfew0o444" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types-prelude.fs")) true
+        check "ckwfew0o445" fsharpEntity1.HasAssemblyCodeRepresentation false
+        check "ckwfew0o446" fsharpEntity1.UnionCases.Count 0
+        check "ckwfew0o447" fsharpEntity1.RecordFields.Count 0
+        check "ckwfew0o448" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Core.sbyte"
+
+    // Test the entity used for an F# library module
+    [<Test>]
+    member this.Test4() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.LanguagePrimitives")
+
+        check "ckwfew0o41q" fsharpEntity1.IsExternal false
+        check "ckwfew0o42w" fsharpEntity1.IsModule true
+        check "ckwfew0o43e" fsharpEntity1.IsValueType false
+        check "ckwfew0o44r" fsharpEntity1.LogicalName "LanguagePrimitives"
+        check "ckwfew0o44t" fsharpEntity1.IsAbbreviation false
+        check "ckwfew0o44y" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types.fs")) true
+        check "ckwfew0o44u" fsharpEntity1.HasAssemblyCodeRepresentation false
+        check "ckwfew0o44i" fsharpEntity1.UnionCases.Count 0
+        check "ckwfew0o44o" fsharpEntity1.RecordFields.Count 0
+        check "ckwfew0o44p" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Core.LanguagePrimitives"
+
+    // Test the entity used for F# floating point types annotated with units of measure
+    [<Test>]
+    member this.Test5() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.float`1")
+
+        check "ckwfew0o41" fsharpEntity1.IsExternal false
+        check "ckwfew0o42" fsharpEntity1.IsModule false
+        check "ckwfew0o43" fsharpEntity1.IsValueType false
+        check "ckwfew0o44a" fsharpEntity1.LogicalName "float`1"
+        check "ckwfew0o44s" fsharpEntity1.IsAbbreviation false
+        check "ckwfew0o44d" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types.fs")) true
+        check "ckwfew0o44f" fsharpEntity1.HasAssemblyCodeRepresentation true
+        check "ckwfew0o44g" fsharpEntity1.UnionCases.Count 0
+        check "ckwfew0o44h" fsharpEntity1.RecordFields.Count 0
+        check "ckwfew0o44j" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Core.float`1"
+
+    // Test the entity used for F# array types
+    [<Test>]
+    member this.Test6() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.[]`1")
+
+        check "ckwfew0o41" fsharpEntity1.IsExternal false
+        check "ckwfew0o42" fsharpEntity1.IsModule false
+        check "ckwfew0o43" fsharpEntity1.IsValueType false
+        check "ckwfew0o44k" fsharpEntity1.LogicalName "[]`1"
+        check "ckwfew0o44l" fsharpEntity1.IsAbbreviation false
+        check "ckwfew0o44z" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types-prelude.fs")) true
+        check "ckwfew0o44x" fsharpEntity1.HasAssemblyCodeRepresentation true
+        check "ckwfew0o44c" fsharpEntity1.UnionCases.Count 0
+        check "ckwfew0o44v" fsharpEntity1.RecordFields.Count 0
+        check "ckwfew0o44b" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Core.[]`1"
+
+    // Test the value used for List.map
+    [<Test>]
+    member this.Test7() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Collections.ListModule")
+        let v = fsharpEntity1.MembersOrValues |> Seq.find (fun x -> x.CompiledName = "Map") 
+        
+        
+        check "ckwfew0o47qa" v.CompiledName "Map"
+        check "ckwfew0o47qb" v.IsCompilerGenerated false
+        check "ckwfew0o47qc" v.IsExtensionMember false
+        check "ckwfew0o47qd" v.IsImplicitConstructor false
+        check "ckwfew0o47qe" v.IsModuleValueOrMember true
+        check "ckwfew0o47qf" v.InlineAnnotation Microsoft.FSharp.Metadata.FSharpInlineAnnotation.OptionalInline
+        check "ckwfew0o47qg" v.IsMutable false
+        check "ckwfew0o47qh" v.IsTypeFunction false
+        check "ckwfew0o47qh" v.XmlDocSig "M:Microsoft.FSharp.Collections.ListModule.Map``2(Microsoft.FSharp.Core.FSharpFunc`2{``0,``1},Microsoft.FSharp.Collections.FSharpList{``0})"
+        
+        check "ckwfew0o47w" v.CurriedParameterGroups.Count 2
+        check "ckwfew0o47e" v.CurriedParameterGroups.[0].Count 1
+        check "ckwfew0o47r" v.CurriedParameterGroups.[1].Count 1
+        check "ckwfew0o47t" v.CurriedParameterGroups.[0].[0].Name "mapping"
+        check "ckwfew0o47y" v.CurriedParameterGroups.[1].[0].Name "list"
+        check "ckwfew0o47u" v.CurriedParameterGroups.[0].[0].Type.IsFunction true
+        check "ckwfew0o47i" v.CurriedParameterGroups.[0].[0].Type.IsNamed false
+        check "ckwfew0o47o" v.CurriedParameterGroups.[0].[0].Type.IsTuple false
+        check "ckwfew0o47p" v.CurriedParameterGroups.[0].[0].Type.IsGenericParameter false
+
+        check "ckwfew0o47a" (v.CurriedParameterGroups.[0].[0].Type.GenericArguments.[0].IsGenericParameter) true
+        check "ckwfew0o47s" (v.CurriedParameterGroups.[0].[0].Type.GenericArguments.[0].GenericParameterIndex) 0
+        check "ckwfew0o47d" (v.CurriedParameterGroups.[0].[0].Type.GenericArguments.[1].IsGenericParameter) true
+        check "ckwfew0o47f" (v.CurriedParameterGroups.[0].[0].Type.GenericArguments.[1].GenericParameterIndex) 1
+
+        check "ckwfew0o47g" v.CurriedParameterGroups.[1].[0].Type.IsFunction false
+        check "ckwfew0o47h" v.CurriedParameterGroups.[1].[0].Type.IsNamed true
+        check "ckwfew0o47j" v.CurriedParameterGroups.[1].[0].Type.IsTuple false
+        check "ckwfew0o47k" v.CurriedParameterGroups.[1].[0].Type.IsGenericParameter false
+
+        check "ckwfew0o47l" (v.CurriedParameterGroups.[1].[0].Type.NamedEntity.LogicalName) "list`1"
+        check "ckwfew0o47z" (v.CurriedParameterGroups.[1].[0].Type.NamedEntity.IsAbbreviation) true
+        check "ckwfew0o47x" (v.CurriedParameterGroups.[1].[0].Type.GenericArguments.Count) 1
+        check "ckwfew0o47c" (v.CurriedParameterGroups.[1].[0].Type.GenericArguments.[0].IsGenericParameter) true
+        check "ckwfew0o47v" (v.CurriedParameterGroups.[1].[0].Type.GenericArguments.[0].GenericParameterIndex) 0
+        check "ckwfew0o47b" (v.CurriedParameterGroups.[1].[0].Type.NamedEntity.IsAbbreviation) true
+
+        check "ckwfew0o47n" (v.ReturnParameter.Type.NamedEntity.LogicalName) "list`1"
+        check "ckwfew0o47m" (v.ReturnParameter.Type.GenericArguments.Count) 1
+        check "ckwfew0o474" (v.ReturnParameter.Type.GenericArguments.[0].IsGenericParameter) true
+        check "ckwfew0o475" (v.ReturnParameter.Type.GenericArguments.[0].GenericParameterIndex) 1
+
+    // Test the value for (|||)
+    [<Test>]
+    member this.Test7b() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.Operators")
+        let v = fsharpEntity1.MembersOrValues |> Seq.find (fun x -> x.CompiledName = "op_BitwiseOr") 
+        
+        
+        check "ckwfew0o47qa" v.CompiledName "op_BitwiseOr"
+        check "ckwfew0o47qb" v.IsCompilerGenerated false
+        check "ckwfew0o47qb" v.IsActivePattern false
+        check "ckwfew0o47qc" v.IsExtensionMember false
+        check "ckwfew0o47qd" v.IsImplicitConstructor false
+        check "ckwfew0o47qe" v.IsModuleValueOrMember true
+        check "ckwfew0o47qf" v.InlineAnnotation Microsoft.FSharp.Metadata.FSharpInlineAnnotation.PsuedoValue
+        check "ckwfew0o47qg" v.IsMutable false
+        check "ckwfew0o47qh" v.IsTypeFunction false
+        
+
+    // Test the value used for .Length on the list type
+    [<Test>]
+    member this.Test8() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Collections.List`1")
+        fsharpEntity1.MembersOrValues |> Seq.iter (fun x -> printfn "Found member '%s' in List`1 metadata" x.CompiledName)
+        let v = fsharpEntity1.MembersOrValues |> Seq.find (fun x -> x.CompiledName = "get_Length") 
+        
+        
+        check "ckwfew0o48q" v.CompiledName "get_Length"
+        // one argument group, no entries in it
+        check "ckwfew0o48w" v.CurriedParameterGroups.Count 1
+        check "ckwfew0o48w" v.CurriedParameterGroups.[0].Count 0
+
+        check "ckwfew0o48n" (v.ReturnParameter.Type.NamedEntity.LogicalName) "int"
+        check "ckwfew0o48m" (v.ReturnParameter.Type.GenericArguments.Count) 0
+
+
+    [<Test>]
+    member this.Test9() = 
+
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Collections.List`1")
+
+        check "ckwfew0o41" fsharpEntity1.IsExternal false
+        check "ckwfew0o42" fsharpEntity1.IsModule false
+        check "ckwfew0o43" fsharpEntity1.IsValueType false
+        check "ckwfew0o44" fsharpEntity1.LogicalName "List`1"
+        check "ckwfew0o44" fsharpEntity1.CompiledName "FSharpList`1"
+        check "ckwfew0o44" fsharpEntity1.IsAbbreviation false
+        check "ckwfew0o44" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types.fs")) true
+        check "ckwfew0o44" fsharpEntity1.HasAssemblyCodeRepresentation false
+        check "ckwfew0o44" fsharpEntity1.UnionCases.Count 2
+        check "ckwfew0o44" fsharpEntity1.RecordFields.Count 0
+        check "ckwfew0o44" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Collections.FSharpList`1"
+
+
+    [<Test>]
+    member this.Test10() = 
+        
+        let fsharpEntity1 = fsharpLibrary.GetEntity("Microsoft.FSharp.Core.Ref`1")
+
+        check "ckwfew0o41" fsharpEntity1.IsExternal false
+        check "ckwfew0o42" fsharpEntity1.IsModule false
+        check "ckwfew0o43" fsharpEntity1.IsValueType false
+        check "ckwfew0o44" fsharpEntity1.LogicalName "Ref`1"
+        check "ckwfew0o44" fsharpEntity1.CompiledName "FSharpRef`1"
+        check "ckwfew0o44" fsharpEntity1.IsAbbreviation false
+        check "ckwfew0o44" (fsharpEntity1.DeclarationLocation.Document.Contains("prim-types.fs")) true
+        check "ckwfew0o44" fsharpEntity1.HasAssemblyCodeRepresentation false
+        check "ckwfew0o44" fsharpEntity1.UnionCases.Count 0
+        check "ckwfew0o44" fsharpEntity1.RecordFields.Count 1
+        check "ckwfew0o44" fsharpEntity1.XmlDocSig "T:Microsoft.FSharp.Core.FSharpRef`1"
+
+
+
+    [<Test>]
+    member this.TraversalTestLookingForBadDocumentation() = 
+
+         for x in fsharpLibrary.Entities do 
+             if x.IsModule then 
+                 printfn "module: Name = %s, QualifiedName = %s" x.LogicalName x.QualifiedName
+                 
+         for x in fsharpLibrary.Entities do 
+             if not x.IsModule && not x.IsAbbreviation && not x.HasAssemblyCodeRepresentation then 
+                 printfn "type: Name = %s, QualifiedName = %s" x.LogicalName x.QualifiedName
+
+         for x in fsharpLibrary.Entities do 
+             if x.HasAssemblyCodeRepresentation then 
+                 printfn "mapped to assembly code: Name = %s" x.LogicalName 
+
+         for x in fsharpLibrary.Entities do 
+             if x.IsAbbreviation then 
+                 printfn "type abbreviation: Name = %s" x.LogicalName 
+
+         for x in fsharpLibrary.Entities do 
+            for v in x.NestedEntities do 
+               printfn "nested entity : Name = %s.%s" x.LogicalName v.LogicalName 
+
+         for x in fsharpLibrary.Entities do 
+            printfn "entity: Name = %s" x.LogicalName 
+            for v in x.MembersOrValues do 
+               printfn "member : Name = %s.%s" x.LogicalName v.CompiledName
+               for ps in v.CurriedParameterGroups do 
+                   for p in ps do 
+                       printfn "       : Parameter %s" p.Name 
+
+         printfn "--------------------- ERRORS----------------------------------"
+
+             //x.IsAbbreviation  || 
+             //x.HasAssemblyCodeRepresentation || 
+             //(x.ReflectionType.GetCustomAttributes(typeof<System.ObsoleteAttribute>,true).Length = 0 && x.ReflectionType.GetCustomAttributes(typeof<OCamlCompatibilityAttribute>,true).Length = 0) 
+
+            //not (v.CompiledName.Contains "_") && 
+            // (v.CompiledName = ".ctor" 
+            // || x.IsAbbreviation  
+            // || x.HasAssemblyCodeRepresentation 
+            // || (let minfos = x.ReflectionType.GetMethods() |> Array.filter (fun m -> m.Name = v.CompiledName) 
+            //     minfos |> Array.exists (fun minfo -> minfo.GetCustomAttributes(typeof<System.ObsoleteAttribute>,true).Length = 0 && minfo.GetCustomAttributes(typeof<OCamlCompatibilityAttribute>,true).Length = 0)))
+         
+         for x in fsharpLibrary.Entities do 
+            let rec loop (x:FSharpEntity) = 
+                if okEntity x then
+                  for x in x.NestedEntities do 
+                     loop x
+                  for v in x.MembersOrValues do 
+                   if okVal (x,v) then 
+                     for ps in v.CurriedParameterGroups do 
+                       for p in ps do 
+                           match p.Name with 
+                           | null -> printfn "member %s.%s : NULL PARAMETER NAME" x.LogicalName v.CompiledName
+                           | _ -> ()
+            loop x
+                          
+
+    [<Test>]
+    member this.ExploreFSharpCore() = explore fsharpLibrary
+
+    [<Test>]
+    member this.ExploreFSharpPowerPack() = explore (FSharpAssembly.FromFile(@"FSharp.PowerPack.dll"))
+    
+    [<Test>]
+    member this.ExploreFSharpPowerPackLinq() = explore (FSharpAssembly.FromFile(@"FSharp.PowerPack.Linq.dll"))
+                    
+    [<Test>]
+    member this.LoadPowerPack() = FSharpAssembly.FromFile(@"FSharp.PowerPack.dll") |> ignore
+
+    [<Test>]
+    member this.LoadPowerPackLinq() =  FSharpAssembly.FromFile(@"FSharp.PowerPack.Linq.dll") |> ignore
+
+    [<Test>]
+    member this.TestMultipleAssemblies() =        
+        let fscore = FSharpAssembly.FSharpLibrary
+        let list = fscore.GetEntity("Microsoft.FSharp.Collections.List`1")
+        let fscore1 = FSharpAssembly.FromAssembly(typedefof<list<_>>.Assembly)
+        let list1 = fscore1.GetEntity("Microsoft.FSharp.Collections.List`1")
+        Assert.IsTrue((list = list1))
+        Assert.IsTrue((fscore = fscore1))
+
+    [<Test>]
+    member this.TestEqualityOnEntities() =        
+        let fscore = FSharpAssembly.FSharpLibrary
+        let list1 = fscore.GetEntity("Microsoft.FSharp.Collections.List`1")
+        let unitE = fscore.GetEntity("Microsoft.FSharp.Core.unit")
+        let list2 = fscore.GetEntity("Microsoft.FSharp.Collections.List`1")
+        assertEquality list1 list2
+        assertInequality list1 unitE
+
+
+        // Union cases
+        for (uc1,uc2) in Seq.zip list1.UnionCases list2.UnionCases do
+            Assert.IsTrue((uc1 = uc2), sprintf "%A <> %A" uc1 uc2)
+            for (f1,f2) in strictZip uc1.Fields uc2.Fields do
+                assertEquality f1 f2
+        assertInequality (list1.UnionCases |> Seq.toArray).[0] (list1.UnionCases |> Seq.toArray).[1]
+        let consE = (list1.UnionCases |> Seq.toArray).[1]
+        assertInequality (consE.Fields |> Seq.toArray).[0]  (consE.Fields |> Seq.toArray).[1]
+
+        // Generic type parameters
+        let event1 = fscore.GetEntity "Microsoft.FSharp.Control.Event`2"
+        let event2 = fscore.GetEntity "Microsoft.FSharp.Control.Event`2"
+        assertEquality event1 event2
+        for (p1,p2) in strictZip event1.GenericParameters event2.GenericParameters do
+            assertEquality p1 p2
+
+        assertInequality (event1.GenericParameters |> Seq.toArray).[0]  (event1.GenericParameters |> Seq.toArray).[1]
+        assertInequality (event1.GenericParameters |> Seq.toArray).[0]  (event2.GenericParameters |> Seq.toArray).[1]
+
+        // parameters
+        let listMap () = 
+            fscore.GetEntity("Microsoft.FSharp.Collections.ListModule").MembersOrValues |> Seq.find (fun m -> m.DisplayName = "map")
+        let map1 = listMap()
+        let map2 = listMap()
+        assertEquality map1 map2
+        for cp1,cp2 in strictZip map1.CurriedParameterGroups map2.CurriedParameterGroups do
+            for p1,p2 in strictZip cp1 cp2 do
+                assertEquality p1 p2
+        let p1 = map1.CurriedParameterGroups |> seqItem 0 |> seqItem 0
+        let p2 = map1.CurriedParameterGroups |> seqItem 1 |> seqItem 0
+        assertInequality p1 p2
+
+        // attributes
+        let map1Attrs = map1.Attributes
+        let map2Attrs = map2.Attributes
+        for a1, a2 in strictZip map1Attrs map2Attrs do
+            assertEquality a1 a2
+
+        let zip =
+            fscore.GetEntity("Microsoft.FSharp.Collections.ListModule").MembersOrValues |> Seq.find (fun m -> m.DisplayName = "zip")
+        assertInequality (zip.Attributes |> seqItem 0) (map1Attrs |> seqItem 0)
+
+
+    [<Test>]
+    member this.TestTypeEquality() =
+        let fscoreEnt = FSharpAssembly.FSharpLibrary.GetEntity
+        let listModule = fscoreEnt "Microsoft.FSharp.Collections.ListModule"
+        Assert.IsNotNull listModule
+        let mapFun = listModule.MembersOrValues |> Seq.find (fun m -> m.DisplayName = "map")
+        let t = mapFun.Type
+        assertEquality t t
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/NORTHWND.MDF b/workyard/linq/FSharp.PowerPack.Unittests/NORTHWND.MDF
new file mode 100644
index 0000000..7ecd78a
Binary files /dev/null and b/workyard/linq/FSharp.PowerPack.Unittests/NORTHWND.MDF differ
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/NORTHWND_log.ldf b/workyard/linq/FSharp.PowerPack.Unittests/NORTHWND_log.ldf
new file mode 100644
index 0000000..bd43629
Binary files /dev/null and b/workyard/linq/FSharp.PowerPack.Unittests/NORTHWND_log.ldf differ
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/NUnitFrameworkShims.fs b/workyard/linq/FSharp.PowerPack.Unittests/NUnitFrameworkShims.fs
new file mode 100644
index 0000000..83b88e2
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/NUnitFrameworkShims.fs
@@ -0,0 +1,79 @@
+namespace NUnit.Framework
+open System
+
+type TestFixtureAttribute() =
+    inherit System.Attribute()
+
+type TestAttribute() =
+    inherit System.Attribute()
+
+type SetUpAttribute() =
+    inherit System.Attribute()
+
+type TestFixtureSetUpAttribute() =
+    inherit System.Attribute()
+
+
+type TearDownAttribute() =
+    inherit System.Attribute()
+
+type TestFixtureTearDownAttribute() =
+    inherit System.Attribute()
+
+type IgnoreAttribute(reason:string) =
+    inherit System.Attribute()
+
+exception AssertionException of string
+
+module private Impl =
+    let rec equals (expected:obj) (actual:obj) = 
+        match expected, actual with 
+        |   (:? Array as a1), (:? Array as a2) ->
+                if a1.Rank > 1 then failwith "Rank > 1 not supported"                
+                if a2.Rank > 1 then false
+                else
+                    let lb = a1.GetLowerBound(0)
+                    let ub = a1.GetUpperBound(0)
+                    if lb <> a2.GetLowerBound(0) || ub <> a2.GetUpperBound(0) then false
+                    else
+                        {lb..ub} |> Seq.forall(fun i -> equals (a1.GetValue(i)) (a2.GetValue(i)))    
+        |   _ ->
+                Object.Equals(expected, actual)
+
+type Assert = 
+    
+
+    static member AreEqual(expected : obj, actual : obj, message : string) =
+        if not (Impl.equals expected actual) then
+            let message = sprintf "%s: Expected %A but got %A" message expected actual
+            AssertionException message |> raise
+
+    static member AreNotEqual(expected : obj, actual : obj, message : string) =
+        if Impl.equals expected actual then
+            let message = sprintf "%s: Expected not %A but got %A" message expected actual
+            AssertionException message |> raise
+
+
+    static member AreEqual(expected : obj, actual : obj) = Assert.AreEqual(expected, actual, "Assertion")
+
+    static member AreNotEqual(expected : obj, actual : obj) = Assert.AreNotEqual(expected, actual, "Assertion")
+
+    static member IsNull(o : obj) = Assert.AreEqual(null, o)
+
+    static member IsTrue(x : bool, message : string) =
+        if not x then
+            AssertionException(message) |> raise
+
+    static member IsTrue(x : bool) = Assert.IsTrue(x, "")
+
+    static member IsFalse(x : bool, message : string) =
+        if x then
+            AssertionException(message) |> raise
+
+    static member IsFalse(x : bool) = Assert.IsFalse(x, "")
+
+    static member Fail(message : string) = AssertionException(message) |> raise
+    
+    static member Fail() = Assert.Fail("") 
+
+    static member Fail(message : string, args : obj[]) = Assert.Fail(String.Format(message,args))
\ No newline at end of file
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/NativeArrayTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/NativeArrayTests.fs
new file mode 100644
index 0000000..9a7daf8
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/NativeArrayTests.fs
@@ -0,0 +1,554 @@
+namespace FSharp.PowerPack.Unittests
+
+open NUnit.Framework
+open System.Collections.Generic
+open System.Runtime.InteropServices
+open System.Diagnostics
+open System
+open System.Windows.Forms
+open System.Drawing
+open Microsoft.FSharp.NativeInterop
+open Microsoft.FSharp.Math
+
+#nowarn "9"
+#nowarn "51"
+
+module PrimitiveBindings = 
+
+    /// LAPACK/BLAS primitive matrix/matrix multiply routine
+    [<DllImport(@"blas.dll",EntryPoint="dgemm_")>]
+    extern void DoubleMatrixMultiply_(char* transa, char* transb, int* m, int* n, int *k,
+                                      double* alpha, double* A, int* lda,double* B, int* ldb,
+                                      double* beta,
+                                      double* C, int* ldc);
+
+    ///  C := alpha*op( A )*op( B ) + beta*C
+    let DoubleMatrixMultiply trans alpha (A: FortranMatrix<double>) (B: FortranMatrix<double>) beta (C: FortranMatrix<double>) = 
+        // Mutable is needed because F# only lets you take pointers to mutable values
+        let mutable trans = trans  // nb. unchanged on exit 
+        let mutable beta = beta 
+        let mutable alpha = alpha 
+        let mutable m = A.NumCols 
+        let mutable n = B.NumRows 
+        let mutable k = A.NumRows 
+        let mutable lda = A.NumCols 
+        // Call the BLAS/LAPACK routine
+        DoubleMatrixMultiply_(&&trans, &&trans, &&m, &&n, &&k, &&alpha, A.Ptr, &&lda, B.Ptr, &&k, &&beta, C.Ptr, &&m)
+
+    /// LAPACK/BLAS primitive matrix/vector multiply routine
+    [<DllImport(@"blas.dll",EntryPoint="dgemv_")>]
+    extern void DoubleMatrixVectorMultiply_(char* trans, int* m, int* n,
+                                            double* alpha, double* A, int* lda,
+                                            double* x, int* incx, double* beta,
+                                            double* y, int* incy);
+
+    let DoubleMatrixVectorMultiply trans alpha (A: FortranMatrix<double>) (B: NativeArray<double>) beta (C: NativeArray<double>) = 
+        let mutable trans = trans
+        let mutable beta = beta 
+        let mutable alpha = alpha 
+        let mutable m = A.NumCols 
+        let mutable n = A.NumRows 
+        let mutable i_one = 1
+        // Call the BLAS/LAPACK routine
+        DoubleMatrixVectorMultiply_(&&trans, &&m, &&n, &&alpha, A.Ptr, &&m, B.Ptr, &&i_one, &&beta, C.Ptr, &&i_one)
+
+
+    [<DllImport(@"lapack.dll", EntryPoint="dgetrf_")>]
+    extern void DoublePLUDecomposition_(int *m, int *n, double *a, int* lda, int *ipiv, int *info);
+
+    let DoublePLUDecomposition (A : FortranMatrix<double>) (ipiv : NativeArray<int>) = 
+        let mutable m = A.NumCols
+        let mutable n = A.NumRows
+        let mutable info = 0
+        let mutable lda = A.NumCols
+        DoublePLUDecomposition_(&&m, &&n, A.Ptr, &&lda, ipiv.Ptr, &&info);
+        match info with 
+        | -1 -> invalid_arg "m"
+        | -2 -> invalid_arg "n"
+        | -3 -> invalid_arg "A"
+        | -4 -> invalid_arg "lda"
+        | -5 -> invalid_arg "ipiv"
+        | -6 -> invalid_arg "info"
+        | 0 -> ()
+        | n -> invalid_arg (sprintf "singular: U(%d,%d) is zero" n n)
+
+
+    [<DllImport(@"lapack.dll", EntryPoint="dgetrs_")>]
+    extern void DoubleSolveAfterPLUDecomposition_(char *trans, int *n, int *nrhs, double *a, int *lda, int *ipiv, double*b, int * ldb, int*info)
+
+    let DoubleSolveAfterPLUDecomposition trans (A : FortranMatrix<double>) (B : FortranMatrix<double>) (ipiv : NativeArray<int>) = 
+        let mutable trans = trans
+        let mutable n = A.NumRows
+        let mutable nrhs = B.NumCols
+        let mutable lda = n
+        let mutable ldb = n
+        let mutable info = 0
+        DoubleSolveAfterPLUDecomposition_(&&trans, &&n, &&nrhs, A.Ptr, &&lda, ipiv.Ptr, B.Ptr, &&ldb, &&info);
+        match info with 
+        | -1 -> invalid_arg "trans"
+        | -2 -> invalid_arg "n"
+        | -3 -> invalid_arg "nrhs"
+        | -4 -> invalid_arg "A"
+        | -5 -> invalid_arg "lda"
+        | -6 -> invalid_arg "ipiv"
+        | -7 -> invalid_arg "B"
+        | -8 -> invalid_arg "ldb"
+        | -9 -> invalid_arg "info"
+        | _ -> ()
+
+    [<DllImport(@"lapack.dll", EntryPoint="dgeev_")>]
+    extern void DoubleComputeEigenValuesAndVectors_(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *wr, double *wi, double *vl, 
+                                                    int *ldvl, double *vr, int *ldvr, double*work, int *lwork, int*info);
+
+    let DoubleComputeEigenValuesAndVectors jobvl jobvr (A : FortranMatrix<double>) (WR : NativeArray<double>) (WI : NativeArray<double>) (VL : FortranMatrix<double>) (VR : FortranMatrix<double>) (workspace : NativeArray<double>) = 
+        let mutable jobvl = jobvl
+        let mutable jobvr = jobvr
+        let mutable lda = A.NumCols
+        let mutable n = A.NumRows
+        let mutable n = A.NumRows
+        let mutable ldvl = VL.NumCols
+        let mutable ldvr = VR.NumCols
+        let mutable lwork = workspace.Length
+        let mutable info = 0
+        DoubleComputeEigenValuesAndVectors_(&&jobvl, &&jobvr, &&n, A.Ptr, &&lda, WR.Ptr, WI.Ptr, VL.Ptr, &&ldvl, VR.Ptr, &&ldvr,workspace.Ptr, &&lwork, &&info);
+        match info with 
+        | -1 -> invalid_arg "jobvl"
+        | -2 -> invalid_arg "jobvr"
+        | -3 -> invalid_arg "n"
+        | -4 -> invalid_arg "A"
+        | -5 -> invalid_arg "lda"
+        | -6 -> invalid_arg "wr"
+        | -7 -> invalid_arg "wi"
+        | -8 -> invalid_arg "vl"
+        | -9 -> invalid_arg "ldvl"
+        | -10 -> invalid_arg "vr"
+        | -11 -> invalid_arg "ldvr"
+        | -12 -> invalid_arg "work"
+        | -13 -> invalid_arg "lwork"
+        | -14 -> invalid_arg "info"
+        | _ -> ()
+
+    let DoubleComputeEigenValuesAndVectorsWorkspaceSize jobvl jobvr (A : FortranMatrix<double>)  = 
+        let mutable jobvl = jobvl
+        let mutable jobvr = jobvr
+        let mutable lda = A.NumCols
+        let mutable n = A.NumRows
+        let mutable ldvl = n
+        let mutable ldvr = n
+        let mutable lwork = -1
+        let mutable workspaceSize = 0
+        let mutable info = 0
+        printf "DoubleComputeEigenValuesAndVectorsWorkspaceSize\n" ;
+        DoubleComputeEigenValuesAndVectors_(&&jobvl, &&jobvr, &&n, A.Ptr, &&lda, A.Ptr, A.Ptr, A.Ptr, &&ldvl, A.Ptr, &&ldvr,NativePtr.ofNativeInt (NativePtr.toNativeInt (&&workspaceSize)), &&lwork, &&info);
+        printf "workspaceSize = %d\n" workspaceSize;
+        match info with 
+        | -1 -> invalid_arg "jobvl"
+        | -2 -> invalid_arg "jobvr"
+        | -3 -> invalid_arg "n"
+        | -4 -> invalid_arg "A"
+        | -5 -> invalid_arg "lda"
+        | -6 -> invalid_arg "wr"
+        | -7 -> invalid_arg "wi"
+        | -8 -> invalid_arg "vl"
+        | -9 -> invalid_arg "ldvl"
+        | -10 -> invalid_arg "vr"
+        | -11 -> invalid_arg "ldvr"
+        | -12 -> invalid_arg "work"
+        | -13 -> invalid_arg "lwork"
+        | -14 -> invalid_arg "info"
+        | _ -> workspaceSize
+
+
+//----------------------------------------------------------------------------
+/// Tutorial Part 3. LAPACK accepts Fortran matrices, though often permits flags 
+/// to view the input matrices a transposed way.  This is a pain. Here we
+/// use some implicit transpose trickery and transpose settings to give 
+/// a view of these operations oeprating over CMatrix values.  Note that no actual
+/// copying of matrix data occurs.
+
+module PrimitiveCMatrixBindings = 
+
+     /// Here we builda  version that operates on row-major data
+    let DoubleMatrixMultiply alpha (A: CMatrix<double>) (B: CMatrix<double>) beta (C: CMatrix<double>) = 
+        Debug.Assert(A.NumCols = B.NumRows);
+        // Lapack is column-major, so we give it the implicitly transposed matrices and reverse their order:
+        // C <- A*B   ~~> C' <- (B'*A')
+        PrimitiveBindings.DoubleMatrixMultiply 'n' alpha B.NativeTranspose A.NativeTranspose beta C.NativeTranspose
+
+    let DoubleMatrixVectorMultiply alpha (A: CMatrix<double>) (B: NativeArray<double>) beta (C: NativeArray<double>) = 
+        Debug.Assert(A.NumCols = B.Length);
+        // Lapack is column-major, so we tell it that A is transposed. The 't' and the A.NativeTranspose effectively cancel.
+        // C <- A*B   ~~> C <- (A''*B)
+        PrimitiveBindings.DoubleMatrixVectorMultiply 't' alpha A.NativeTranspose B beta C
+
+    let DoubleSolveAfterPLUDecomposition (A : CMatrix<double>) (B : FortranMatrix<double>) (ipiv : NativeArray<int>) = 
+        Debug.Assert(A.NumRows = A.NumCols);
+        Debug.Assert(A.NumCols = B.NumRows);
+        Debug.Assert(ipiv.Length = A.NumRows);
+        // Lapack is column-major, so we solve A' X = B.  
+        PrimitiveBindings.DoubleSolveAfterPLUDecomposition 'T' A.NativeTranspose B ipiv
+        
+    let DoubleComputeEigenValues (A: CMatrix<double>) (WR: NativeArray<double>) (WI: NativeArray<double>) (workspace: NativeArray<double>) = 
+        Debug.Assert(A.NumCols = A.NumRows);
+        Debug.Assert(A.NumCols = WR.Length);
+        Debug.Assert(A.NumCols = WI.Length);
+        Debug.Assert(workspace.Length >= max 1 (3*A.NumCols));
+        let dummy = A.NativeTranspose 
+        // Lapack is column-major, but the eigen values of the transpose are the same as the eigen values of A
+        // C <- A*B   ~~> C <- (A''*B)
+        PrimitiveBindings.DoubleComputeEigenValuesAndVectors 'v' 'v' A.NativeTranspose WR WI dummy dummy workspace
+      
+    let DoubleComputeEigenValuesAndVectors (A: CMatrix<double>) (WR: NativeArray<double>) (WI: NativeArray<double>) (VR: FortranMatrix<double>) (workspace: NativeArray<double>) = 
+        Debug.Assert(A.NumCols = A.NumRows);
+        Debug.Assert(A.NumCols = WR.Length);
+        Debug.Assert(A.NumCols = WI.Length);
+        Debug.Assert(workspace.Length >= max 1 (3*A.NumCols));
+        let dummy = A.NativeTranspose 
+        // Lapack is column-major, but the eigen values of the transpose are the same as the eigen values of A
+        // C <- A*B   ~~> C <- (A''*B)
+        PrimitiveBindings.DoubleComputeEigenValuesAndVectors 'n' 'v' A.NativeTranspose WR WI dummy VR workspace
+      
+    let DoubleComputeEigenValuesWorkspace (A: CMatrix<double>) = 
+        Debug.Assert(A.NumCols = A.NumRows);
+        let dummy = A.NativeTranspose 
+        // Lapack is column-major, but the eigen values of the transpose are the same as the eigen values of A
+        // C <- A*B   ~~> C <- (A''*B)
+        PrimitiveBindings.DoubleComputeEigenValuesAndVectorsWorkspaceSize 'n' 'n' A.NativeTranspose 
+        
+
+//----------------------------------------------------------------------------
+/// Tutorial Part 4. To pass F# data structures to C and Fortran you need to
+/// pin the underlying array objects.  This can be done entirely F# code.
+///
+
+module NativeUtilities = 
+    let nativeArray_as_CMatrix_colvec (arr: 'a NativeArray) =
+       new CMatrix<_>(arr.Ptr,arr.Length,1)
+       
+    let nativeArray_as_FortranMatrix_colvec (arr: 'a NativeArray) =
+       new FortranMatrix<_>(arr.Ptr,arr.Length,1)
+       
+    (* Functions to pin and free arrays *)
+    let pinM m = PinnedArray2.of_matrix(m)
+    let pinV v = PinnedArray.of_vector(v)
+    let pinA arr = PinnedArray.of_array(arr)
+    let pinMV m1 v2 = pinM m1,pinV v2
+    let pinVV v1 v2 = pinV v1,pinV v2
+    let pinAA v1 v2 = pinA v1,pinA v2
+    let pinMVV m1 v2 m3 = pinM m1,pinV v2,pinV m3
+    let pinMM m1 m2  = pinM m1,pinM m2
+    let pinMMM m1 m2 m3 = pinM m1,pinM m2,pinM m3
+    let freeM (pA: PinnedArray2<'a>) = pA.Free()
+    let freeV (pA: 'a PinnedArray) = pA.Free()
+    let freeA (pA: 'a PinnedArray) = pA.Free()
+    let freeMV ((pA: PinnedArray2<'a>),(pB : 'a PinnedArray)) = pA.Free(); pB.Free()
+    let freeVV ((pA: 'a PinnedArray),(pB : 'a PinnedArray)) = pA.Free(); pB.Free()
+    let freeAA ((pA: 'a PinnedArray),(pB : 'a PinnedArray)) = pA.Free(); pB.Free()
+    let freeMM ((pA: PinnedArray2<'a>),(pB: PinnedArray2<'a>)) = pA.Free();pB.Free()
+    let freeMMM ((pA: PinnedArray2<'a>),(pB: PinnedArray2<'a>),(pC: PinnedArray2<'a>)) = pA.Free();pB.Free();pC.Free()
+    let freeMVV ((pA: PinnedArray2<'a>),(pB: 'a PinnedArray),(pC: 'a PinnedArray)) = pA.Free();pB.Free();pC.Free()
+
+
+//----------------------------------------------------------------------------
+/// Tutorial Part 5. Higher level-place bindings that operate mutatively over the F#
+/// Matrix type by first pinning the data structures.  Be careful with these operations,
+/// as they will write some results into your input matrices.
+///
+
+module MutableMatrixRoutines = 
+
+    open NativeUtilities
+
+    /// C <- A * B
+    let mulMM (A:matrix) (B:matrix) (C:matrix) = 
+        let (pA,pB,pC) as ptrs = pinMMM A B C
+        try PrimitiveCMatrixBindings.DoubleMatrixMultiply 1.0 pA.NativeArray pB.NativeArray 0.0 pC.NativeArray
+        finally
+            freeMMM ptrs
+
+    /// C <- A * V
+    let mulMV (A:matrix) (B:vector) (C:vector) = 
+        let pA,pB,pC as pin = pinMVV A B C
+        try PrimitiveCMatrixBindings.DoubleMatrixVectorMultiply 1.0 pA.NativeArray pB.NativeArray 0.0 pC.NativeArray
+        finally
+            freeMVV pin
+
+    /// B <- A \ B
+    let solve (A : matrix) (B: vector) (ipiv: int[]) = 
+        let pA = pinM A
+        let pB = pinV B
+        let pPivots = pinA ipiv
+        try 
+          PrimitiveBindings.DoublePLUDecomposition pA.NativeArray.NativeTranspose pPivots.NativeArray;
+          PrimitiveCMatrixBindings.DoubleSolveAfterPLUDecomposition pA.NativeArray (nativeArray_as_FortranMatrix_colvec pB.NativeArray) pPivots.NativeArray
+        finally
+            freeM pA; freeV pB; freeA pPivots
+
+    let computeEigenValues (A : matrix) (WR: double[]) (WI:double[]) (workspace:double[])  = 
+        let pA = pinM A
+        let pWR,pWI as pWRI = pinAA WR WI
+        let pWorkspace = pinA workspace
+        try 
+          PrimitiveCMatrixBindings.DoubleComputeEigenValues pA.NativeArray pWR.NativeArray pWI.NativeArray pWorkspace.NativeArray 
+        finally
+            freeM pA; freeVV pWRI; freeA pWorkspace
+            
+    let computeEigenValuesAndVectors (A : matrix) (WR: double[]) (WI:double[]) (VR: matrix) (workspace:double[])  = 
+        let pA,pVR as pMM = pinMM A VR
+        let pWR,pWI as pWRI = pinAA WR WI
+        let pWorkspace = pinA workspace
+        try 
+          PrimitiveCMatrixBindings.DoubleComputeEigenValuesAndVectors pA.NativeArray pWR.NativeArray pWI.NativeArray pVR.NativeArray.NativeTranspose pWorkspace.NativeArray 
+        finally
+            freeMM pMM; freeVV pWRI; freeA pWorkspace
+            
+
+//----------------------------------------------------------------------------
+// Tutorial Part 6. Higher level bindings that defensively copy their input
+//
+
+module ImmutableMatrixRoutines = 
+
+    open NativeUtilities
+
+    /// Compute A * B
+    let mulMM (A:matrix) (B:matrix) = 
+        let C = Matrix.zero A.NumRows B.NumCols
+        // C <- A * B
+        MutableMatrixRoutines.mulMM A B C;
+        C
+
+    /// Compute A * v
+    let mulMV (A:matrix) (v:vector) = 
+        let C = Vector.zero A.NumRows
+        // C <- A * v
+        MutableMatrixRoutines.mulMV A v C;
+        C
+
+    /// Compute A \ v
+    let solve (A : matrix) (v: vector) = 
+        Debug.Assert(A.NumRows = A.NumCols);
+        let A = Matrix.copy A // workspace (yuck) 
+        let vX = Vector.copy v 
+        let ipiv = Array.zeroCreate A.NumCols 
+        // vX <- A \ v
+        MutableMatrixRoutines.solve A vX ipiv;
+        vX
+
+    (* The underlying LAPACK routine raises an error when trying to estimate the workspace. *)
+    (* Hence I've removed this from the sample just for now. *)
+    
+(*
+    let computeEigenValuesWorkspace (A : matrix)   = 
+        let pA = pinM A
+        try 
+          PrimitiveCMatrixBindings.DoubleComputeEigenValuesWorkspace pA.NativeArray 
+        finally
+            freeM pA
+*)
+            
+    let computeEigenValues (A : matrix)  = 
+        let At = A.Transpose
+        let n = At.NumRows
+        let WR = Array.zeroCreate n
+        let WI = Array.zeroCreate n
+        let workspace = Array.zeroCreate (5 * n (* computeEigenValuesWorkspace At *) ) 
+        MutableMatrixRoutines.computeEigenValues At WR WI workspace;
+        let W = Vector.Generic.init n (fun i -> Complex.mkPolar (WR.[i],WI.[i])) 
+        W
+             
+    let computeEigenValuesAndVectors (A : matrix)  = 
+        let At = A.Transpose
+        let n = At.NumRows
+        let WR = Array.zeroCreate n
+        let WI = Array.zeroCreate n
+        let VR = Matrix.zero n n
+        let workspace = Array.zeroCreate (5 * n (* computeEigenValuesAndVectorsWorkspace A *) ) 
+        MutableMatrixRoutines.computeEigenValuesAndVectors At WR WI VR workspace;
+        let W = Vector.Generic.init n (fun i -> Complex.mkPolar (WR.[i],WI.[i])) 
+        W,VR.Transpose
+
+//----------------------------------------------------------------------------
+// Tutorial Part 7. Reusing primitive bindings on other similarly shapped data structures
+//
+// Here we show that the same NativeArray/CMatrix/FortranMatrix primitive bindings can be used
+// with other data structures where the underlying bits are ultimately stored as shape double[] and double[,],
+// e.g. they can be used directly on arrays, or even on memory allocated C.
+
+module MutableArrayRoutines = 
+    open NativeUtilities
+    let pinA2 arr2 = PinnedArray2.of_array2D(arr2)
+    let pinA2AA m1 v2 m3 = pinA2 m1,pinA v2,pinA m3
+    let freeA2A2A2 ((pA: PinnedArray2<'a>),(pB: PinnedArray2<'a>),(pC: PinnedArray2<'a>)) = pA.Free();pB.Free();pC.Free()
+    let freeA2AA ((pA: PinnedArray2<'a>),(pB: 'a PinnedArray),(pC: 'a PinnedArray)) = pA.Free();pB.Free();pC.Free()
+    let pinA2A2A2 m1 m2 m3 = pinA2 m1,pinA2 m2,pinA2 m3
+    let freeA2 (pA: PinnedArray2<'a>) = pA.Free()
+
+    let mulMM (A: double[,]) (B: double[,]) (C: double[,]) = 
+        let (pA,pB,pC) as ptrs = pinA2A2A2 A B C
+        try PrimitiveCMatrixBindings.DoubleMatrixMultiply 1.0 pA.NativeArray pB.NativeArray 0.0 pC.NativeArray
+        finally
+            freeMMM ptrs
+
+    let mulMV (A: double[,]) (B: double[]) (C: double[]) = 
+        let pA,pB,pC as pin = pinA2AA A B C
+        try PrimitiveCMatrixBindings.DoubleMatrixVectorMultiply 1.0 pA.NativeArray pB.NativeArray 0.0 pC.NativeArray
+        finally
+            freeA2AA pin
+    
+    let solve (A : double[,]) (B: double[]) (ipiv: int[]) = 
+        let pA = pinA2 A
+        let pB = pinA B
+        let pPivots = pinA ipiv
+        try 
+          PrimitiveBindings.DoublePLUDecomposition pA.NativeArray.NativeTranspose pPivots.NativeArray;
+          PrimitiveCMatrixBindings.DoubleSolveAfterPLUDecomposition pA.NativeArray (nativeArray_as_FortranMatrix_colvec pB.NativeArray) pPivots.NativeArray
+        finally
+            freeA2 pA; freeA pB; freeA pPivots
+    
+module ImmutableArrayRoutines = 
+    let mulMM (A:double[,]) (B:double[,]) = 
+        let C = Array2D.zeroCreate (Array2D.length1 A) (Array2D.length2 B)
+        MutableArrayRoutines.mulMM A B C;
+        C
+
+    let mulMV (A:double[,]) (B:double[]) = 
+        let C = Array.zeroCreate (Array2D.length1 A)
+        MutableArrayRoutines.mulMV A B C;
+        C
+    let solve (A : double[,]) (B: double[]) = 
+        Debug.Assert(Array2D.length1 A = Array2D.length2 A);
+        let A = Array2D.init (Array2D.length1 A) (Array2D.length2 A) (fun i j ->  A.[i,j]) 
+        let BX = Array.copy B 
+        let ipiv = Array.zeroCreate (Array2D.length1 A)
+        MutableArrayRoutines.solve A BX ipiv;
+        BX
+
+[<TestFixture>]
+type public NativeArrayTests() =
+  
+    [<Test>]
+    member this.BasicTests1() = 
+
+
+          // Ensure you have LAPACK.dll and BLAS.dll the sample directory or elsewhere
+          // on your path. Here we set the current directory so we can find any local copies
+          // of LAPACK.dll and BLAS.dll.
+          System.Environment.CurrentDirectory <- __SOURCE_DIRECTORY__ 
+
+          // Here are some simple matrix values.
+          let onesM = matrix [ [ 1.0; 1.0];  
+                                [1.0; 1.0] ]
+          let onesA = [| 1.0; 1.0 |]
+          let onesV = vector [ 1.0; 1.0]
+          let onesv = matrix [ [ 1.0] ; 
+                               [ 1.0] ]
+          let twosM = matrix [ [ 2.0; 2.0]; 
+                               [ 2.0; 2.0] ]
+          let twosV = vector [ 2.0; 2.0 ]
+          let twosv = matrix [ [ 2.0] ; 
+                               [ 2.0] ]
+          let iM = matrix [ [ 1.0; 0.0]; 
+                            [ 0.0; 1.0] ]
+
+          let miM = matrix [ [ -1.0; 0.0]; 
+                             [  0.0; -1.0] ]
+
+          matrix [ [ 0.0; 0.0]; 
+                   [ 0.0; 0.0] ]  |> ignore
+
+          Matrix.identity 2  |> ignore
+
+          Matrix.identity 10  |> ignore
+
+          let A = 1
+
+          let show x = printf "%s\n" (sprintf "%A" x)
+          printf " ------------------------\n" 
+
+          let J  = matrix [ [ 2.0; 3.0]; 
+                            [ 4.0; 5.0] ]
+          let J2 = matrix [ [ 2.0; 3.0;4.0]; 
+                            [ 2.0; 3.0;5.0]; 
+                            [ 4.0; 5.0;6.0] ]
+
+          // MATALB notation is M \ v, i.e. solve Mx=v for vector x.  Solving Mx=v
+          // The notation we use here is M $ v
+          let ( $ ) (M : matrix) v = ImmutableMatrixRoutines.solve M v
+          let ( *. ) A B = ImmutableMatrixRoutines.mulMM A B
+          let ( *%. ) A v = ImmutableMatrixRoutines.mulMV A v
+
+          let Random = Matrix.create 200 200 1.0 |> Matrix.randomize
+          let RandomV = Matrix.create 200 1 1.0 |> Matrix.toVector
+
+          let time s f =
+            let sw = new System.Diagnostics.Stopwatch() 
+            sw.Start();
+            let res = f()
+            printf "%s, time: %d\n" s sw.ElapsedMilliseconds;
+            ()
+            
+            
+          time "Random * Random" (fun () -> Random * Random )
+          time "Random *. Random" (fun () -> Random *. Random )
+          time "Random $ Random" (fun () -> Random $ RandomV )
+          time "Random $ Random, check with *" (fun () -> Vector.sum (Random * (Random $ RandomV) - RandomV) |> show )
+          time "Random $ Random, check with *%." (fun () -> Vector.sum (Random *%. (Random $ RandomV) - RandomV) |> show )
+
+          time "computeEigenValues Random" (fun () -> ImmutableMatrixRoutines.computeEigenValues Random)
+
+          ImmutableMatrixRoutines.computeEigenValues (Matrix.identity 2) |> ignore
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (Matrix.identity 2) |> ignore
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (matrix [ [ 3.0 ] ]) |> ignore
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (matrix [ [ 3.0; 0.0 ]; [ 0.0; 3.0] ]) |> ignore
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (matrix [ [ 1.0; 0.0 ]; [ 0.0; -1.0] ]) |> ignore
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (matrix [ [ -1.0; 0.0 ]; [ 0.0; -1.0] ]) |> ignore
+
+          let trans = ref (fun (t:float) -> Matrix.identity 2)
+          let points = ref [ (0.0, 0.0); (1.0,0.0); (1.0,1.0); (0.0,1.0); (0.0,0.0) ]
+
+          let f = new System.Windows.Forms.Form()
+          let paint (e:System.Windows.Forms.PaintEventArgs) = 
+              let t = (System.DateTime.Now.Ticks |> Int64.to_float) / 10000000.0
+              let trans = (!trans) t
+              let of_vec (v:vector) = new Point(f.Width/2 + int (v.[0]*100.0), f.Height/2  - int (v.[1]*100.0)) 
+              let origin = vector [0.0; 0.0]
+              let to_vec (x,y) = vector [x;y]
+              let draw_vec pen v1 v2 = e.Graphics.DrawLine(pen,of_vec v1,of_vec v2);
+              let draw (p1,p2) = draw_vec Pens.Aqua (trans * to_vec p1) (trans * to_vec p2);
+              let es,E = ImmutableMatrixRoutines.computeEigenValuesAndVectors trans.Transpose
+              draw_vec Pens.Red origin (E.Column 0 * es.[0].r)
+              draw_vec Pens.Red origin (E.Column 1 * es.[1].r)
+              !points |> List.fold (fun acc p1 -> match acc with None -> Some p1 | Some p0 -> draw (p0,p1); Some p1) None |> ignore;
+              f.Invalidate()
+          let scaleM n k = Matrix.initDiagonal (Vector.create n k)
+          trans := (fun t -> scaleM 2 (sin t)); f.Invalidate()
+          let rotateM th = matrix [ [ cos th; -sin th ]; [ sin th; cos th ] ]
+          let pi = System.Math.PI
+          trans := (fun t -> rotateM (pi * t)); f.Invalidate()
+          trans := (fun t -> matrix [ [ sin t; 1.0]; [cos (t/1.3); 1.0] ])
+
+          ImmutableMatrixRoutines.computeEigenValuesAndVectors (rotateM 0.23)  |> ignore
+          let M = matrix [ [ 0.5; 1.0]; [0.0; 1.0] ]
+          trans := (fun _ -> M)
+          let es,EM = ImmutableMatrixRoutines.computeEigenValuesAndVectors M.Transpose
+
+          let e0 = es.[1]
+          assert(e0.i = 0.0) 
+          M.Transpose * EM.Column 0  |> ignore
+          M.Transpose * EM.Column 1 * (1.0/es.[1].r)  |> ignore
+          let disp x = sprintf "%A" x
+
+
+          printf " ------------------------\n" 
+          printf " %s $ %s = %s\n" (disp J) (disp onesV) (disp (J $ onesV))
+          printf " ------------------------\n" 
+          onesV  |> show
+          printf " ------------------------\n" 
+          J * (J $ vector [1.0;1.0])  |> show
+          printf " ------------------------\n" 
+          J2 * (J2 $ vector [1.0;2.0;3.0])  |> show
+          printf " ------------------------\n" 
+          printf " DONE\n" 
+
+
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/PermutationTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/PermutationTests.fs
new file mode 100644
index 0000000..372d38e
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/PermutationTests.fs
@@ -0,0 +1,44 @@
+namespace FSharp.PowerPack.Unittests
+
+open Microsoft.FSharp.Math
+open NUnit.Framework
+
+#nowarn "40"
+
+[<TestFixture>]
+type public PermutationTests() =
+    [<Test>]
+    member this.BasicTests() = 
+        let p2 = Permutation.ofArray [| 0;2;1;3 |]
+        do test "cwnewr91" (p2 0 = 0)
+        do test "cwnewr92" (p2 1 = 2)
+        do test "cwnewr93" (p2 2 = 1)
+        do test "cwnewr94" (p2 3 = 3)
+        let p3 = p2 >> p2
+        do test "cwnewr95" (p3 0 = 0)
+        do test "cwnewr96" (p3 1 = 1)
+        do test "cwnewr97" (p3 2 = 2)
+        do test "cwnewr98" (p3 3 = 3)
+        let p4 = Permutation.rotation 4 1
+        do test "cwnewr99" (p4 0 = 1)
+        do test "cwnewr9a" (p4 1 = 2)
+        do test "cwnewr9s" (p4 2 = 3)
+        do test "cwnewr9d" (p4 3 = 0)
+        let p5 = Permutation.rotation 4 -1
+        do test "cwnewr9f" (p5 0 = 3)
+        do test "cwnewr9g" (p5 1 = 0)
+        do test "cwnewr9h" (p5 2 = 1)
+        do test "cwnewr9j" (p5 3 = 2)
+        let p6 = Permutation.swap 2 3
+        do test "cwnewr9k" (p6 0 = 0)
+        do test "cwnewr9l" (p6 1 = 1)
+        do test "cwnewr9z" (p6 2 = 3)
+        do test "cwnewr9x" (p6 3 = 2)
+
+        do test "cwcoinwcq" (Array.permute (Permutation.rotation 4 1) [| 0;1;2;3 |] = [| 3;0;1;2 |])
+        do test "cwcoinwcw" (Array.permute (Permutation.swap 1 2) [| 0;1;2;3 |] = [| 0;2;1;3 |])
+        do test "cwcoinwce" (try let _ = Permutation.ofArray [| 0;0 |] in false with :? System.ArgumentException -> true)
+        do test "cwcoinwcr" (try let _ = Permutation.ofArray [| 1;1 |] in false with :? System.ArgumentException -> true)
+        do test "cwcoinwct" (try let _ = Permutation.ofArray [| 1;3 |] in false with :? System.ArgumentException -> true)
+        ()
+
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/QueryTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/QueryTests.fs
new file mode 100644
index 0000000..af46bc0
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/QueryTests.fs
@@ -0,0 +1,451 @@
+// Copyright (c) Microsoft Corporation 2005-2007.
+// This sample code is provided "as is" without warranty of any kind. 
+// We disclaim all warranties, either express or implied, including the 
+// warranties of merchantability and fitness for a particular purpose. 
+//
+
+namespace FSharp.PowerPack.Unittests
+
+open NUnit.Framework
+open System.IO
+open System.Windows.Forms
+open Microsoft.FSharp.Linq
+open Microsoft.FSharp.Linq.Query
+
+#if ENTITIES 
+open Entities.Northwind
+
+[<AutoOpen>]
+module Database = 
+    let dbPath = __SOURCE_DIRECTORY__ + @"\NORTHWND.MDF"
+    
+    System.IO.File.SetAttributes(dbPath, System.IO.File.GetAttributes dbPath &&& ~~~System.IO.FileAttributes.ReadOnly )
+    let sqlServerInstance = @".\SQLEXPRESS"
+    let connString = @"AttachDBFileName='" + dbPath + "';Server='" + sqlServerInstance + "';user instance=true;Integrated Security=SSPI;Connection Timeout=30" 
+    let entityConnString = "metadata=res://*/Northwind.csdl|res://*/Northwind.ssdl|res://*/Northwind.msl;provider=System.Data.SqlClient;provider connection string=\"" + connString + "\""
+
+    let db = new Entities(entityConnString)
+#else
+open LinqToSql.Northwind
+
+[<AutoOpen>]
+module Database = 
+    let dbPath = __SOURCE_DIRECTORY__ + @"\NORTHWND.MDF"
+    
+    System.IO.File.SetAttributes(dbPath, System.IO.File.GetAttributes dbPath &&& ~~~System.IO.FileAttributes.ReadOnly )
+    let sqlServerInstance = @".\SQLEXPRESS"
+    let connString = @"AttachDBFileName='" + dbPath + "';Server='" + sqlServerInstance + "';user instance=true;Integrated Security=SSPI;Connection Timeout=30" 
+
+    let db = new NorthwindDataContext(connString)
+    do db.Log <- System.Console.Out
+#endif    
+
+[<AutoOpen>]
+module Macros = 
+
+    [<ReflectedDefinition>]
+    let queryCondition (c:Customer) = c.City = "London" 
+            
+    // Check we can use a macro as a subsequence
+    [<ReflectedDefinition>]
+    let subSequence (c:Customer) = seq { for e in db.Employees do if queryCondition  c then yield c }
+
+    // Nullable manipulations
+    [<ReflectedDefinition>]
+    let (=?!) (x : System.Nullable<'a>) (y: 'a) = 
+        x.HasValue && x.Value = y
+
+#if ENTITIES
+[<TestFixture>]
+type public EntitiesQueryTests() =
+#else
+[<TestFixture>]
+type public LinqToSqlQueryTests() =
+#endif
+
+    [<Test>]
+    member this.``Join using nested 'for': With 'String.Concat' call``() = 
+      <@ seq { for p in db.Products do 
+                 for c in db.Categories do
+                   if p.CategoryID.Value = c.CategoryID then
+                     yield System.String.Concat(p.ProductName, c.CategoryName) } @>
+      |> query |> checkContains "ChaiBeverages"
+
+    [<Test>]
+    member this.``Join using nested 'for': With string concatenation``() = 
+      <@ seq { for p in db.Products do 
+                 for c in db.Categories do
+                   if p.CategoryID.Value = c.CategoryID then
+                     yield p.ProductName + " (" + c.CategoryName + ")" } @>
+      |> query |> checkContains "Chai (Beverages)"
+
+    [<Test>]
+    member this.``Nested query: Calling combinators``() = 
+      <@ seq { for c in db.Categories do 
+                 yield db.Products
+                       |> Seq.filter (fun p -> p.CategoryID.Value = c.CategoryID) 
+                       |> Seq.map (fun p -> p.UnitPrice.Value)
+                       |> Seq.average } @>
+      |> query |> Seq.length |> checkEquals 8
+
+    [<Test>]
+    member this.BasicTests1() = 
+
+        check "vesnvew01" (query <@ seq {  for c in db.Customers do if true then yield c.ContactName }  |> Seq.length @>) 91
+        check "vesnvew02" (query <@ seq { for c in db.Customers do if true then yield (c.ContactName,c.Address) } |> Seq.length @>) 91
+        #if ENTITIES
+        // Using arbitrary methods in projection is not supported in LINQ to Entities
+        // (apart from creating tuples & records which is supported explicitly)
+        #else
+        check "vesnvew03" (query <@ seq { for c in db.Customers do yield [c.ContactName] } |> Seq.length @>) 91
+        #endif
+        check "vesnvew04" (query <@ seq { for c in db.Customers do if true then yield [c.ContactName;c.Address] } |> Seq.length @>) 91
+        check "vesnvew05" (query <@ seq { for c in db.Customers do if false then yield c.ContactName } |> Seq.length @>) 0
+        check "vesnvew06" (query <@ seq { for c in db.Customers do if 1 > 2 then yield c.ContactName } |> Seq.length @>) 0
+        check "vesnvew07" (query <@ seq { for c in db.Customers do if 2 > 1 then yield c.ContactName } |> Seq.length @>) 91
+
+        check "vesnvew08" ((query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.take 4 @>  ) |> Seq.length) 4
+        check "vesnvew09" (query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.take 4 |> Seq.length @>  ) 4
+
+        check "vesnvew0q" ((query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.truncate 4 @>  ) |> Seq.length) 4
+        check "vesnvew0w" (query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.truncate 4 |> Seq.length @>  ) 4
+
+        check "vesnvew0e" ((query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.take 4 @>  ) |> Seq.length) 4
+        check "vesnvew0r" (query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.take 4 |> Seq.length @>  ) 4
+
+        check "vesnvew0t" (query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.head @>) "Maria Anders"
+        check "vesnvew0y" (query <@ seq { for c in db.Customers do yield c.ContactName } |> Seq.distinct |> Seq.length @>) 91
+        check "vesnvew0u" (query <@ seq { for c in db.Customers do yield c.City } |> Seq.distinct |> Seq.length @>) 69
+        check "vesnvew0i" (query <@ seq { for c in db.Customers do yield c.CustomerID } |> Seq.distinct |> Seq.length @>) 91
+
+        check "vesnvew0o" ((query <@ seq { for c in db.Customers do yield c.Orders.Count }  @>) |> Seq.averageBy float |> int) 9
+        
+        check "vesnvew0p" ((query <@ seq { for c in db.Customers do yield c.Orders.Count }  @>) |> Seq.filter (fun x -> true) |> Seq.length) 91
+        check "vesnvew0a" ((query <@ seq { for c in db.Customers do yield c.Orders.Count }  @>) |> Seq.filter (fun x -> false) |> Seq.length) 0
+        check "vesnvew0s" ((query <@ seq { for c in db.Customers do yield c }  @>) |> Seq.filter (fun x -> x.City = "London") |> Seq.length) 6
+
+    [<Test>]
+    member this.BasicTests2() = 
+        check "vesnvew0d" ((query <@ db.Customers  @>) |> Seq.length) 91
+        check "vesnvew0f" ((query <@ db.Customers |> Seq.filter (fun x -> true) @>) |> Seq.length) 91
+        check "vesnvew0g" ((query <@ seq { for c in db.Customers do yield c.Orders.Count }  @>) |> Seq.filter (fun x -> false) |> Seq.length) 0
+        check "vesnvew0h" ((query <@ seq { for c in db.Customers do yield c }  @>) |> Seq.filter (fun x -> x.City = "London") |> Seq.length) 6
+
+
+        check "vesnvew0j" ((query <@ let f (c:Customer) = c.City = "London" in seq { for c in db.Customers do if f c then yield c }  @>) |> Seq.length) 6
+
+        check "vesnvew0k" ((query <@ seq { for c in db.Customers do if queryCondition  c then yield c }  @>) |> Seq.length) 6
+
+
+        check "vesnvew0l" ((query <@ seq { for c in db.Customers do yield! subSequence c }  @>) |> Seq.length) 54
+
+
+
+        check "vesnvew0z" (query <@ seq { for c in db.Customers do if c.Address.Contains("Jardim das rosas") then yield c.ContactName } |> Seq.length @>) 1
+
+        check "vesnvew0x" (query <@ seq { for c in db.Customers do if c.Address.Length = 17 then yield c.ContactName } |> Seq.length @>) 6
+
+        check "vesnvew0c" (query <@ seq { for c in db.Customers do for e in db.Employees do yield e.LastName } |> Seq.length @>) 819
+
+        check "vesnvew0v" (query <@ seq { for c in db.Customers do for e in db.Employees do if true then yield (e.LastName,c.ContactName) } @> |> Seq.length)  819
+        check "vesnvew0b" (query <@ seq { for c in db.Customers do if true then for e in db.Employees do yield (e.LastName,c.ContactName) } @> |> Seq.length)  819
+        check "vesnvew0n" (query <@ seq { for c in db.Customers do if c.Country.Length = 6 then for e in db.Employees do yield (e.LastName,c.ContactName) } @> |> Seq.length)  288
+
+    [<Test>]
+    member this.EqualityAndComparison() =        
+        let allEmployees = db.Employees |> Seq.toArray        
+        check "terty01"  (query <@ seq { for c in db.Employees do if c.EmployeeID < 0 then yield c  } @> |> Seq.length) 0
+        check "terty01a" (query <@ seq { for c in db.Employees do if c.EmployeeID > 0 then yield c  } @> |> Seq.length) (allEmployees.Length)
+        check "terty01b" (query <@ seq { for c in db.Employees do if c.EmployeeID = 0 then yield c  } @> |> Seq.length) 0
+        check "terty02" (query <@ seq { for c in db.Customers do if c.CompanyName = "Z"  then yield c  } @> |> Seq.length) 0
+        check "terty03" (query <@ seq { for c in db.Employees do if c.EmployeeID <> allEmployees.[0].EmployeeID  then yield c  } @> |> Seq.length) (allEmployees.Length - 1)
+        let jan1of2010 = System.DateTime(2010,1,1)
+        check "terty04" 
+            (query <@ seq { for c in db.Orders do if c.OrderDate.HasValue && c.OrderDate.Value <= jan1of2010  then yield c  } @> |> Seq.length) 
+            (db.Orders |> Seq.filter(fun o -> o.OrderDate.HasValue) |> Seq.length)
+        let jan1of1900 = System.DateTime(1900,1,1)
+        check "terty05" 
+            (query <@ seq { for c in db.Orders do if c.OrderDate.HasValue && c.OrderDate.Value >= jan1of1900  then yield c  } @> |> Seq.length) 
+            (db.Orders |> Seq.filter(fun o -> o.OrderDate.HasValue) |> Seq.length)
+
+
+    [<Test>]
+    member this.BasicTests3() = 
+        check "vesnvew0m" (query <@ seq { for c in db.Customers do 
+                                             for e in db.Employees do 
+                                                 if c.Address.Contains("Jardim") && 
+                                                    c.Address.Contains("rosas") then 
+                                                       yield (e.LastName,c.ContactName) } @> 
+                                   |> Seq.length) 9
+        
+        check "vesnvew0QQ" (query <@ seq { for c in db.Customers do 
+                                           for e in db.Employees do 
+                                            if c.ContactName = e.LastName then 
+                                             yield c.ContactName } @> 
+                                   |> Seq.length) 0
+
+
+        check "vesnvew0WW" (query <@ seq { for p in db.Products do
+                                            for c in db.Categories do
+                                             for s in db.Suppliers  do
+                                              yield c.CategoryName, p.ProductName, s.CompanyName } 
+                                   |> Seq.length @>) 17864
+
+
+    [<Test>]
+    member this.NullableTests1() = 
+
+        check "vesnvew0EE" (query <@ seq { for p in db.Products do
+                                           for c in db.Categories do
+                                            for s in db.Suppliers  do
+                                              if p.CategoryID =?! c.CategoryID &&
+                                                 p.SupplierID =?! s.SupplierID then 
+                                                yield c.CategoryName, p.ProductName, s.CompanyName } 
+                                   |> Seq.length @>) 77
+
+        check "vesnvew0RR" (query <@ seq { for p in db.Products do
+                                             if p.CategoryID =?! 1 then 
+                                                 yield p.ProductName }  |> Seq.length @>) 12
+        
+    [<Test>]
+    member this.BasicTests4() = 
+
+        // By design: Can't use Seq.groupBy
+        check "vrejkner0TT" (try let _ = query <@ Seq.groupBy (fun (p:Product) -> p.CategoryID) db.Products @> in false with _ -> true) true
+
+        check "vrejkner0YY" (try let _ = query <@ db.Products |> Seq.groupBy (fun p -> p.CategoryID) @> in false with _ -> true) true
+
+
+        check "cnewnc081"  (query <@ Query.groupBy
+                                       (fun (c:Customer) -> c.Address.Length) 
+                                       (seq { for c in db.Customers do yield c }) 
+                                    |> Seq.length @> ) 
+                          22
+
+    [<Test>]
+    member this.BasicTests5() = 
+
+        check "cnewnc082"  (query <@ Seq.sortBy
+                                       (fun (c:Customer) -> c.Address.Length) 
+                                       (seq { for c in db.Customers do yield c }) 
+                                    |> Seq.length @> ) 
+                          91
+
+        check "cnewnc083"  (query <@ Seq.sort (seq { for c in db.Customers do yield c.Address.Length }) 
+                                     |> Seq.length @> ) 
+                          91
+
+
+        check "cnewnc083"  (query <@ seq { for c in db.Customers do yield c.Address.Length }
+                                     |> Seq.sort
+                                     |> Seq.length @> ) 
+                          91
+
+        check "cnewnc094"  (query <@ seq { for c in db.Customers do yield c }
+                                    |> Seq.sortBy (fun c -> c.Address.Length)                                    
+                                    |> Seq.length @> ) 
+                          91
+        check "cnewnc094"  (query <@ Seq.length
+                                       (Seq.sortBy (fun (c:Customer) -> c .Address.Length) 
+                                         (seq { for c in db.Customers do yield c })) @> ) 
+                          91
+
+    [<Test>]
+    member this.BasicTests6() = 
+
+        check "cnewnc085"  (query <@ Seq.exists
+                                       (fun (c:Customer) -> c.Address.Length > 10) 
+                                       (seq { for c in db.Customers do yield c }) @> ) 
+                          true
+
+
+        check "cnewnc086"  (query <@ Seq.forall
+                                       (fun (c:Customer) -> c.Address.Length <= 10) 
+                                       (seq { for c in db.Customers do yield c }) @> ) 
+                          false
+
+        check "cnewnc087"  (query <@ Query.join 
+                                       (seq { for e in db.Employees do yield e }) 
+                                       (seq { for c in db.Customers do yield c }) 
+                                       (fun e -> e.Country) 
+                                       (fun c -> c.Country) 
+                                       (fun e c -> (e,c)) 
+                                    |> Seq.length  @> ) 
+                          93
+
+        check "cnewnc088"  (query <@ seq { for e in db.Employees do  
+                                             for c in db.Customers do 
+                                                 if e.Country = c.Country then 
+                                                     yield (e,c) } 
+                                    |> Seq.length  @> ) 
+                      93
+
+
+    [<Test>]
+    member this.BasicTests7() = 
+        check "cnewnc089"  (query <@ Linq.Query.groupJoin 
+                                       (seq { for c in db.Employees do yield c }) 
+                                       (seq { for c in db.Customers do yield c }) 
+                                       (fun e -> e.Country) 
+                                       (fun c -> c.Country) 
+                                       (fun e cs -> (e,Seq.length cs)) 
+                                    |> Seq.length  @> ) 
+                          9
+
+
+
+        check "we09j" 
+              (query <@ seq { let grouping = db.Products |> Linq.Query.groupBy (fun p -> p.CategoryID)
+                              yield! grouping } |> Seq.length   @>) 8
+
+        check "we09j" 
+              (query <@ seq { let grouping = db.Products |> Linq.Query.groupBy (fun p -> p.CategoryID)
+                              for group in grouping  do
+                                  yield group.Key }  |> Seq.length  @>) 8
+
+        check "we09j" 
+              (query <@ seq { let grouping = db.Products |> Linq.Query.groupBy (fun p -> p.CategoryID)
+                              for group in grouping  do
+                                          let lowest = group |> Linq.Query.minBy (fun x -> x.UnitPrice.Value)
+                                          yield lowest } @> |> Seq.sum) 
+              56.6500M
+          
+    [<Test>]
+    member this.BasicTests8() = 
+        check "we09j" 
+              (query <@ seq { let grouping = db.Products |> Linq.Query.groupBy (fun p -> p.CategoryID)
+                              for group in grouping  do
+                                          let lowest = group |> Seq.minBy (fun x -> x.UnitPrice.GetValueOrDefault())
+                                          let res = seq { for p in group do if p.UnitPrice = lowest.UnitPrice then yield p }
+                                          yield group } |> Seq.length @>) 
+              8
+
+        check "we09j" 
+              (query <@ db.Customers |> Seq.length @>)  91
+        check "we09j" 
+              (query <@ db.Orders |> Seq.length @>) 830
+
+        check "we09j" 
+              (((query <@ seq { for c in db.Order_Details -> c.Discount } |> Seq.sum @> - 121.04f) |> abs) < 0.001f) true
+        check "we09j" 
+              (query <@ seq { for c in db.Order_Details -> c.Discount } |> Seq.sumBy (fun d -> d + 1.0f) @> >= 2276.0f) true
+
+
+(*
+    check "vesnvew0" (query <@ [ for c in db.Customers do yield c.ContactName ] @>)
+          ["Maria Anders"; "Ana Trujillo"; "Antonio Moreno"; "Thomas Hardy";
+           "Christina Berglund"; "Hanna Moos"; "Frédérique Citeaux"; "Martín Sommer";
+           "Laurence Lebihan"; "Elizabeth Lincoln"; "Victoria Ashworth";
+           "Patricio Simpson"; "Francisco Chang"; "Yang Wang"; "Pedro Afonso";
+           "Elizabeth Brown"; "Sven Ottlieb"; "Janine Labrune"; "Ann Devon";
+           "Roland Mendel"; "Aria Cruz"; "Diego Roel"; "Martine Rancé"; "Maria Larsson";
+           "Peter Franken"; "Carine Schmitt"; "Paolo Accorti"; "Lino Rodriguez";
+           "Eduardo Saavedra"; "José Pedro Freyre"; "André Fonseca"; "Howard Snyder";
+           "Manuel Pereira"; "Mario Pontes"; "Carlos Hernández"; "Yoshi Latimer";
+           "Patricia McKenna"; "Helen Bennett"; "Philip Cramer"; "Daniel Tonini";
+           "Annette Roulet"; "Yoshi Tannamuri"; "John Steel"; "Renate Messner";
+           "Jaime Yorres"; "Carlos González"; "Felipe Izquierdo"; "Fran Wilson";
+           "Giovanni Rovelli"; "Catherine Dewey"; "Jean Fresnière"; "Alexander Feuer";
+           "Simon Crowther"; "Yvonne Moncada"; "Rene Phillips"; "Henriette Pfalzheim";
+           "Marie Bertrand"; "Guillermo Fernández"; "Georg Pipps"; "Isabel de Castro";
+           "Bernardo Batista"; "Lúcia Carvalho"; "Horst Kloss"; "Sergio Gutiérrez";
+           "Paula Wilson"; "Maurizio Moroni"; "Janete Limeira"; "Michael Holz";
+           "Alejandra Camino"; "Jonas Bergulfsen"; "Jose Pavarotti"; "Hari Kumar";
+           "Jytte Petersen"; "Dominique Perrier"; "Art Braunschweiger"; "Pascale Cartrain";
+           "Liz Nixon"; "Liu Wong"; "Karin Josephs"; "Miguel Angel Paolino";
+           "Anabela Domingues"; "Helvetius Nagy"; "Palle Ibsen"; "Mary Saveley";
+           "Paul Henriot"; "Rita Müller"; "Pirkko Koskitalo"; "Paula Parente";
+           "Karl Jablonski"; "Matti Karttunen"; "Zbyszek Piestrzeniewicz"]
+           
+    check "vesnvew0" (query <@ [ for c in db.Customers do yield c.Address ] @>)
+         ["Obere Str. 57"; "Avda. de la Constitución 2222"; "Mataderos  2312";
+         "120 Hanover Sq."; "Berguvsvägen  8"; "Forsterstr. 57"; "24, place Kléber";
+         "C/ Araquil, 67"; "12, rue des Bouchers"; "23 Tsawassen Blvd.";
+         "Fauntleroy Circus"; "Cerrito 333"; "Sierras de Granada 9993"; "Hauptstr. 29";
+         "Av. dos Lusíadas, 23"; "Berkeley Gardens 12  Brewery"; "Walserweg 21";
+         "67, rue des Cinquante Otages"; "35 King George"; "Kirchgasse 6";
+         "Rua Orós, 92"; "C/ Moralzarzal, 86"; "184, chaussée de Tournai";
+         "Åkergatan 24"; "Berliner Platz 43"; "54, rue Royale"; "Via Monte Bianco 34";
+         "Jardim das rosas n. 32"; "Rambla de Cataluña, 23"; "C/ Romero, 33";
+         "Av. Brasil, 442"; "2732 Baker Blvd."; "5ª Ave. Los Palos Grandes";
+         "Rua do Paço, 67"; "Carrera 22 con Ave. Carlos Soublette #8-35";
+         "City Center Plaza 516 Main St."; "8 Johnstown Road";
+         "Garden House Crowther Way"; "Maubelstr. 90"; "67, avenue de l'Europe";
+         "1 rue Alsace-Lorraine"; "1900 Oak St."; "12 Orchestra Terrace"; "Magazinweg 7";
+         "87 Polk St. Suite 5"; "Carrera 52 con Ave. Bolívar #65-98 Llano Largo";
+         "Ave. 5 de Mayo Porlamar"; "89 Chiaroscuro Rd."; "Via Ludovico il Moro 22";
+         "Rue Joseph-Bens 532"; "43 rue St. Laurent"; "Heerstr. 22";
+         "South House 300 Queensbridge"; "Ing. Gustavo Moncada 8585 Piso 20-A";
+         "2743 Bering St."; "Mehrheimerstr. 369"; "265, boulevard Charonne";
+         "Calle Dr. Jorge Cash 321"; "Geislweg 14"; "Estrada da saúde n. 58";
+         "Rua da Panificadora, 12"; "Alameda dos Canàrios, 891"; "Taucherstraße 10";
+         "Av. del Libertador 900"; "2817 Milton Dr."; "Strada Provinciale 124";
+         "Av. Copacabana, 267"; "Grenzacherweg 237"; "Gran Vía, 1";
+         "Erling Skakkes gate 78"; "187 Suffolk Ln."; "90 Wadhurst Rd."; "Vinbæltet 34";
+         "25, rue Lauriston"; "P.O. Box 555"; "Boulevard Tirou, 255";
+         "89 Jefferson Way Suite 2"; "55 Grizzly Peak Rd."; "Luisenstr. 48";
+         "Avda. Azteca 123"; "Av. Inês de Castro, 414"; "722 DaVinci Blvd.";
+         "Smagsloget 45"; "2, rue du Commerce"; "59 rue de l'Abbaye";
+         "Adenauerallee 900"; "Torikatu 38"; "Rua do Mercado, 12";
+         "305 - 14th Ave. S. Suite 3B"; "Keskuskatu 45"; "ul. Filtrowa 68"]    
+    
+    check "vesnvew0" (query <@ [ for c in db.Employees do yield c.LastName ] @>)
+       ["Buchanan"; "Callahan"; "Davolio"; "Dodsworth"; "Fuller"; "King"; "Leverling";"Peacock"; "Suyama"]
+
+    check "vesnvew0" (query <@ [ for c in db.Customers do if true then yield c.ContactName ] @>)
+        ["Maria Anders"; "Ana Trujillo"; "Antonio Moreno"; "Thomas Hardy";
+         "Christina Berglund"; "Hanna Moos"; "Frédérique Citeaux"; "Martín Sommer";
+         "Laurence Lebihan"; "Elizabeth Lincoln"; "Victoria Ashworth";
+         "Patricio Simpson"; "Francisco Chang"; "Yang Wang"; "Pedro Afonso";
+         "Elizabeth Brown"; "Sven Ottlieb"; "Janine Labrune"; "Ann Devon";
+         "Roland Mendel"; "Aria Cruz"; "Diego Roel"; "Martine Rancé"; "Maria Larsson";
+         "Peter Franken"; "Carine Schmitt"; "Paolo Accorti"; "Lino Rodriguez";
+         "Eduardo Saavedra"; "José Pedro Freyre"; "André Fonseca"; "Howard Snyder";
+         "Manuel Pereira"; "Mario Pontes"; "Carlos Hernández"; "Yoshi Latimer";
+         "Patricia McKenna"; "Helen Bennett"; "Philip Cramer"; "Daniel Tonini";
+         "Annette Roulet"; "Yoshi Tannamuri"; "John Steel"; "Renate Messner";
+         "Jaime Yorres"; "Carlos González"; "Felipe Izquierdo"; "Fran Wilson";
+         "Giovanni Rovelli"; "Catherine Dewey"; "Jean Fresnière"; "Alexander Feuer";
+         "Simon Crowther"; "Yvonne Moncada"; "Rene Phillips"; "Henriette Pfalzheim";
+         "Marie Bertrand"; "Guillermo Fernández"; "Georg Pipps"; "Isabel de Castro";
+         "Bernardo Batista"; "Lúcia Carvalho"; "Horst Kloss"; "Sergio Gutiérrez";
+         "Paula Wilson"; "Maurizio Moroni"; "Janete Limeira"; "Michael Holz";
+         "Alejandra Camino"; "Jonas Bergulfsen"; "Jose Pavarotti"; "Hari Kumar";
+         "Jytte Petersen"; "Dominique Perrier"; "Art Braunschweiger"; "Pascale Cartrain";
+         "Liz Nixon"; "Liu Wong"; "Karin Josephs"; "Miguel Angel Paolino";
+         "Anabela Domingues"; "Helvetius Nagy"; "Palle Ibsen"; "Mary Saveley";
+         "Paul Henriot"; "Rita Müller"; "Pirkko Koskitalo"; "Paula Parente";
+         "Karl Jablonski"; "Matti Karttunen"; "Zbyszek Piestrzeniewicz"]    
+*)
+
+module LocalType =
+    open System.Linq
+    type Foo() =                
+        let source = [1;2;3;4;5] |> Queryable.AsQueryable
+     
+        let bar() =     
+            <@ seq { for x in source -> x + 1 } @>
+     
+        let bar2() = <@ source @>
+        member this.Bar() = bar()
+
+        member this.Bar2() = bar2()
+
+    [<TestFixture>]
+    type Test4060() =
+        [<Test>]
+        member this.TestLocalField0() =
+            try 
+                (new Foo()).Bar2() |> query |> ignore
+            with
+            | :? System.NotSupportedException -> ()
+            |   _ -> Assert.Fail("Should detect and report this case")
+
+
+        [<Test>]
+        member this.TestLocalField() =
+            try 
+                (new Foo()).Bar() |> query |> ignore
+            with
+            | :? System.NotSupportedException -> ()
+            |   _ -> Assert.Fail("Should detect and report this case")
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/QuotationEvalTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/QuotationEvalTests.fs
new file mode 100644
index 0000000..2e5d831
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/QuotationEvalTests.fs
@@ -0,0 +1,1473 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Linq.QuotationEvaluation
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Quotations.Patterns
+open Microsoft.FSharp.Quotations.DerivedPatterns
+open Microsoft.FSharp.Quotations.ExprShape
+
+open Microsoft.FSharp.Linq.QuotationEvaluation
+open Microsoft.FSharp.Linq.Query
+
+#nowarn "40"
+#nowarn "57"
+#nowarn "67" // This type test or downcast will always hold
+#nowarn "1204"
+
+    
+[<Measure>] type kg
+[<Measure>] type m
+[<Measure>] type s
+[<Measure>] type sqrm = m ^ 2
+type area = float<m ^ 2>
+
+
+[<AutoOpen>]
+module Extensions = 
+    type System.Object with 
+        member x.ExtensionMethod0()  = 3
+        member x.ExtensionMethod1()  = ()
+        member x.ExtensionMethod2(y:int)  = y
+        member x.ExtensionMethod3(y:int)  = ()
+        member x.ExtensionMethod4(y:int,z:int)  = y + z
+        member x.ExtensionMethod5(y:(int*int))  = y 
+        member x.ExtensionProperty1 = 3
+        member x.ExtensionProperty2 with get() = 3
+        member x.ExtensionProperty3 with set(v:int) = ()
+        member x.ExtensionIndexer1 with get(idx:int) = idx
+        member x.ExtensionIndexer2 with set(idx:int) (v:int) = ()
+
+    type System.Int32 with 
+        member x.Int32ExtensionMethod0()  = 3
+        member x.Int32ExtensionMethod1()  = ()
+        member x.Int32ExtensionMethod2(y:int)  = y
+        member x.Int32ExtensionMethod3(y:int)  = ()
+        member x.Int32ExtensionMethod4(y:int,z:int)  = y + z
+        member x.Int32ExtensionMethod5(y:(int*int))  = y 
+        member x.Int32ExtensionProperty1 = 3
+        member x.Int32ExtensionProperty2 with get() = 3
+        member x.Int32ExtensionProperty3 with set(v:int) = ()
+        member x.Int32ExtensionIndexer1 with get(idx:int) = idx
+        member x.Int32ExtensionIndexer2 with set(idx:int) (v:int) = ()
+
+[<AutoOpen>]
+module ModuleDefinitions = 
+    let eval (q: Expr<_>) = 
+        q.ToLinqExpression() |> ignore 
+        q.Compile() |> ignore  
+        q.Eval()
+
+    let x22<[<Measure>] 'a>() = <@ typeof<float<'a>> @> |> eval
+
+    // The following hopefully is an identity function on quotations:
+    let transformIdentity (x: Expr<'T>) : Expr<'T> = 
+        let rec conv x = 
+            match x with
+            | ShapeVar _ -> 
+                x
+            | ShapeLambda (head, body) -> 
+                Expr.Lambda (head, conv body)    
+            | ShapeCombination (head, tail) -> 
+                RebuildShapeCombination (head, List.map conv tail)
+        conv x |> Expr.Cast
+
+    let checkEval nm (q : Expr<'T>) expected = 
+        check nm (eval q) expected
+        check (nm + "(after applying transformIdentity)") (eval (transformIdentity q)) expected
+        check (nm + "(after applying transformIdentity^2)")  (eval (transformIdentity (transformIdentity q))) expected
+
+    let raise x = Operators.raise x
+
+type Customer = { mutable Name:string; Data: int }
+type CustomerG<'a> = { mutable Name:string; Data: 'a }
+exception E0
+exception E1 of string
+type C0() = 
+    member x.P = 1
+type C1(s:string) = 
+    member x.P = s
+
+type Union10 = 
+   | Case1 of string 
+   | Case2
+
+type Union1 = 
+   | Case1 of string 
+
+type Union11 = 
+   | Case1 of string 
+   | Case2 of string
+
+type Union1111 = 
+   | Case1 of string 
+   | Case2 of string
+   | Case3 of string
+   | Dog2 of string
+   | Dog3 of string
+   | Dog4 of string
+   | Dog5 of string
+   | Dog6 of string
+   | Dog7 of string
+   | Dog8 of string
+   | Dog9 of string
+   | DogQ of string
+   | DogW of string
+   | DogE of string
+   | DogR of string
+   | DogT of string
+   | DogY of string
+   | DogU of string
+   | DogI of string
+
+type GUnion10<'a> = Case1 of 'a | Case2
+
+type PointRecord = { field1 : int; field2 : int }
+
+[<TestFixture>]
+type public QuotationEvalTests() =
+  
+    [<Test>]
+    member this.FloatTests() = 
+
+     // set up bindings
+     let x1 = <@ 2.0<kg> + 4.0<kg> @> |> eval
+     let x2 = <@ 2.0<s> - 4.0<s> @> |> eval
+     let x3 = <@ 2.0<m> / 4.0<s> @> |> eval
+     let x3a = <@ 2.0<m> / 4.0<m> @> |> eval
+     let x3b = <@ 1.0 / 4.0<s> @> |> eval
+     let x3c = <@ 1.0<m> / 4.0 @> |> eval
+     let x4 = <@ 2.0<m> * 4.0<s> @> |> eval
+     let x4a = <@ 2.0<m> * 4.0<m> @> |> eval
+     let x4b = <@ 2.0 * 4.0<m> @> |> eval
+     let x4c = <@ 2.0<m> * 4.0 @> |> eval
+     let x5 = <@ 5.0<m> % 3.0<m> @> |> eval
+     let x6 = <@ - (2.0<m>) @> |> eval
+     let x7 = <@ abs (-2.0<m>) @> |> eval
+     let x8 = <@ sqrt (4.0<sqrm>) @> |> eval
+     let x9 = <@ [ 1.0<m> .. 1.0<m> .. 4.0<m> ] @> |> eval
+     let x10 = <@ sign (3.0<m/s>) @> |> eval
+     let x11 = <@ atan2 4.4<s^3> 5.4<s^3> @> |> eval
+     let x11a : float<1> = <@ acos 4.4<1>  @> |> eval
+     let x11b : float<1> = <@ asin 4.4<1>  @> |> eval
+     let x11c : float<1> = <@ atan 4.4<1>  @> |> eval
+     let x11d : float<1> = <@ ceil 4.4<1>  @> |> eval
+     let x11e : float<1> = <@ cos 4.4<1>  @> |> eval
+     let x11f : float<1> = <@ cosh 4.4<1>  @> |> eval
+     let x11g : float<1> = <@ exp 4.4<1>  @> |> eval
+     let x11h : float<1> = <@ floor 4.4<1>  @> |> eval
+     let x11i : float<1> = <@ log 4.4<1>  @> |> eval
+     let x11j : float<1> = <@ log10 4.4<1>  @> |> eval
+     let x11k : float<1> = <@ 4.4<1> ** 3.0<1> @> |> eval
+     //let x11l : float<1> = <@ pown 4.4<1> 3 @> |> eval
+     let x11m : float<1> = <@ round 4.4<1>  @> |> eval
+     let x11n : int = <@ sign 4.4<1>  @> |> eval
+     let x11o : float<1> = <@ sin 4.4<1>  @> |> eval
+     let x11p : float<1> = <@ sinh 4.4<1>  @> |> eval
+     let x11q : float<1> = <@ sqrt 4.4<1>  @> |> eval
+     let x11r : float<1> = <@ tan 4.4<1>  @> |> eval
+     let x11s : float<1> = <@ tanh 4.4<1>  @> |> eval
+     let x12 = <@ Seq.sum [2.0<sqrm>; 3.0<m^2>] @> |> eval
+     let x12a = <@ Seq.sumBy (fun x -> x*x) [(2.0<sqrm> : area); 3.0<m^2>] @> |> eval
+     let x13 = <@ (Seq.average [2.0<sqrm>; 3.0<m^2>]) : area @> |> eval
+     let x13a = <@ Seq.averageBy (fun x -> x*x) [2.0<m^2/m>; 3.0<m>] @> |> eval
+     let x14 = <@ x13 + x13a @> |> eval
+     let x15 = <@ 5.0<m> < 3.0<m> @> |> eval
+     let x16 = <@ 5.0<m> <= 3.0<m> @> |> eval
+     let x17 = <@ 5.0<m> > 3.0<m> @> |> eval
+     let x18 = <@ 5.0<m> >= 3.0<m> @> |> eval
+     let x19 = <@ max 5.0<m> 3.0<m> @> |> eval
+     let x20 = <@ min 5.0<m> 3.0<m> @> |> eval
+     let x21 = <@ typeof<float<m>> @> |> eval
+
+     // check the types and values!
+     test "x1" (x1 = 6.0<kg>)
+     test "x2" (x2 = -2.0<s>)
+     test "x3" (x3 = 0.5<m/s>)
+     test "x3a" (x3a = 0.5)
+     test "x3b" (x3b = 0.25<1/s>)
+     test "x3c" (x3c = 0.25<m>)
+     test "x4" (x4 = 8.0<m s>)
+     test "x4a" (x4a = 8.0<m^2>)
+     test "x4b" (x4b = 8.0<m>)
+     test "x4c" (x4c = 8.0<m>)
+     test "x5" (x5 = 2.0<m>)
+     test "x6" (x6 = -2.0<m>)
+     test "x7" (x7 = 2.0<m>)
+     test "x8" (x8 = 2.0<m>)
+     test "x9" (x9 = [1.0<m>; 2.0<m>; 3.0<m>; 4.0<m>])
+     test "x10" (x10 = 1)
+     test "x12" (x12 = 5.0<m^2>)
+     test "x12a" (x12a = 13.0<m^4>)
+     test "x13" (x13 = 2.5<m^2>)
+     test "x13a" (x13a = 6.5<m^2>)
+     test "x14" (x14 = 9.0<m^2>)
+     test "x15" (x15 = false)
+     test "x16" (x16 = false)
+     test "x17" (x17 = true)
+     test "x18" (x18 = true)
+     test "x19" (x19 = 5.0<m>)
+     test "x20" (x20 = 3.0<m>)
+     test "x21" (x21 = typeof<float>)
+     test "x22" (x22<m>() = typeof<float>)
+      
+
+    [<Test>]
+    member this.Float32Tests() = 
+
+     let y1 = <@ 2.0f<kg> + 4.0f<kg>  @> |> eval
+     let y2 = <@ 2.0f<s> - 4.0f<s>  @> |> eval
+     let y3 = <@ 2.0f<m> / 4.0f<s>  @> |> eval
+     let y3a = <@ 2.0f<m> / 4.0f<m>  @> |> eval
+     let y3b = <@ 1.0f / 4.0f<s>  @> |> eval
+     let y3c = <@ 1.0f<m> / 4.0f  @> |> eval
+     let y4 = <@ 2.0f<m> * 4.0f<s>  @> |> eval
+     let y4a = <@ 2.0f<m> * 4.0f<m>  @> |> eval
+     let y4b = <@ 2.0f * 4.0f<m>  @> |> eval
+     let y4c = <@ 2.0f<m> * 4.0f  @> |> eval
+     let y5 = <@ 5.0f<m> % 3.0f<m>  @> |> eval
+     let y6 = <@ - (2.0f<m>)  @> |> eval
+     let y7 = <@ abs (2.0f<m>)  @> |> eval
+     let y8 = <@ sqrt (4.0f<sqrm>)  @> |> eval
+     let y9 = <@ [ 1.0f<m> .. 1.0f<m> .. 4.0f<m> ]  @> |> eval
+     let y10 = <@ sign (3.0f<m/s>)  @> |> eval
+     let y11 = <@ atan2 4.4f<s^3> 5.4f<s^3>  @> |> eval
+     let x11a : float32<1> = <@ acos 4.4f<1>   @> |> eval
+     let x11b : float32<1> = <@ asin 4.4f<1>   @> |> eval
+     let x11c : float32<1> = <@ atan 4.4f<1>   @> |> eval
+     let x11d : float32<1> = <@ ceil 4.4f<1>   @> |> eval
+     let x11e : float32<1> = <@ cos 4.4f<1>   @> |> eval
+     let x11f : float32<1> = <@ cosh 4.4f<1>   @> |> eval
+     let x11g : float32<1> = <@ exp 4.4f<1>   @> |> eval
+     let x11h : float32<1> = <@ floor 4.4f<1>   @> |> eval
+     let x11i : float32<1> = <@ log 4.4f<1>   @> |> eval
+     let x11j : float32<1> = <@ log10 4.4f<1>   @> |> eval
+     let x11k : float32<1> = <@ 4.4f<1> ** 3.0f<1>  @> |> eval
+     //let x11l : float32<1> = <@ pown 4.4f<1> 3  @> |> eval
+     let x11m : float32<1> = <@ round 4.4f<1>   @> |> eval
+     let x11n : int = <@ sign 4.4f<1>   @> |> eval
+     let x11o : float32<1> = <@ sin 4.4f<1>   @> |> eval
+     let x11p : float32<1> = <@ sinh 4.4f<1>   @> |> eval
+     let x11q : float32<1> = <@ sqrt 4.4f<1>   @> |> eval
+     let x11r : float32<1> = <@ tan 4.4f<1>   @> |> eval
+     let x11s : float32<1> = <@ tanh 4.4f<1>   @> |> eval
+     let y12 = <@ Seq.sum [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+     let y12a = <@ Seq.sumBy (fun y -> y*y) [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+     let y13 = <@ Seq.average [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+     let y13a = <@ Seq.averageBy (fun y -> y*y) [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+
+     // check the types and values!
+     test "y1" (y1 = 6.0f<kg>)
+     test "y2" (y2 = -2.0f<s>)
+     test "y3" (y3 = 0.5f<m/s>)
+     test "y3a" (y3a = 0.5f)
+     test "y3b" (y3b = 0.25f<1/s>)
+     test "y3c" (y3c = 0.25f<m>)
+     test "y4" (y4 = 8.0f<m s>)
+     test "y4a" (y4a = 8.0f<m^2>)
+     test "y4b" (y4b = 8.0f<m>)
+     test "y4c" (y4c = 8.0f<m>)
+     test "y5" (y5 = 2.0f<m>)
+     test "y6" (y6 = -2.0f<m>)
+     test "y7" (y7 = 2.0f<m>)
+     test "y8" (y8 = 2.0f<m>)
+     test "y9" (y9 = [1.0f<m>; 2.0f<m>; 3.0f<m>; 4.0f<m>])
+     test "y10" (y10 = 1)
+     test "y12" (y12 = 5.0f<m^2>)
+     test "y12a" (y12a = 13.0f<m^4>)
+     test "y13" (y13 = 2.5f<m^2>)
+     test "y13a" (y13a = 6.5f<m^4>)
+      
+
+    [<Test>]
+    member this.DecimalTests() = 
+
+     let z1 = <@ 2.0M<kg> + 4.0M<kg>  @> |> eval
+     let z2 = <@ 2.0M<s> - 4.0M<s>  @> |> eval
+     let z3 = <@ 2.0M<m> / 4.0M<s>  @> |> eval
+     let z3a = <@ 2.0M<m> / 4.0M<m>  @> |> eval
+     let z3b = <@ 1.0M / 4.0M<s>  @> |> eval
+     let z3c = <@ 1.0M<m> / 4.0M  @> |> eval
+     let z4 = <@ 2.0M<m> * 4.0M<s>  @> |> eval
+     let z4a = <@ 2.0M<m> * 4.0M<m>  @> |> eval
+     let z4b = <@ 2.0M * 4.0M<m>  @> |> eval
+     let z4c = <@ 2.0M<m> * 4.0M  @> |> eval
+     let z5 = <@ 5.0M<m> % 3.0M<m>  @> |> eval
+     let z6 = <@ - (2.0M<m>)  @> |> eval
+     let z7 = <@ abs (2.0M<m>)  @> |> eval
+    // let z9 = <@ [ 1.0M<m> .. 4.0M<m> ]
+     let z10 = <@ sign (3.0M<m/s>)  @> |> eval
+
+     let x1d : decimal = <@ ceil 4.4M   @> |> eval
+     let x1h : decimal = <@ floor 4.4M   @> |> eval
+     //let x1l : decimal = <@ pown 4.4M 3  @> |> eval
+#if FX_NO_DEFAULT_DECIMAL_ROUND
+#else
+     let x1m : decimal = <@ round 4.4M   @> |> eval
+#endif
+     let x1n : int = <@ sign 4.4M   @> |> eval
+
+     //let x11d : decimal<1> = <@ ceil 4.4M<1> 
+     //let x11h : decimal<1> = <@ floor 4.4M<1> 
+     //let x11m : decimal<1> = <@ round 4.4M<1> 
+     //let x11l : decimal<1> = <@ pown 4.4M<1> 3  @> |> eval
+     let x11n : int = <@ sign 4.4M<1>   @> |> eval
+
+     //let z12 = <@ Seq.sum [2.0M<sqrm>; 3.0M<m^2>]  @> |> eval
+     //let z12a = <@ Seq.sumBy (fun z -> z*z) [2.0M<sqrm>; 3.0M<m^2>]  @> |> eval
+     //let z13 = <@ Seq.average [2.0M<sqrm>; 3.0M<m^2>]  @> |> eval
+     //let z13a = <@ Seq.averageBy (fun z -> z*z) [2.0M<sqrm>; 3.0M<m^2>]  @> |> eval
+
+
+     // check the types and values!
+     test "z1" (z1 = 6.0M<kg>)
+     test "z2" (z2 = -2.0M<s>)
+     test "z3" (z3 = 0.5M<m/s>)
+     test "z3a" (z3a = 0.5M)
+     test "z3b" (z3b = 0.25M<1/s>)
+     test "z3c" (z3c = 0.25M<m>)
+     test "z4" (z4 = 8.0M<m s>)
+     test "z4a" (z4a = 8.0M<m^2>)
+     test "z4b" (z4b = 8.0M<m>)
+     test "z4c" (z4c = 8.0M<m>)
+     test "z5" (z5 = 2.0M<m>)
+     test "z6" (z6 = -2.0M<m>)
+     test "z7" (z7 = 2.0M<m>)
+     test "z10" (z10 = 1)
+     //test "z12" (z12 = 5.0M<m^2>)
+     //test "z12a" (z12a = 13.0M<m^4>)
+     //test "z13" (z13 = 2.5M<m^2>)
+     //test "z13a" (z13a = 6.5M<m^4>)
+
+
+
+    [<Test>]
+    member this.EvaluationTests() = 
+
+        let f () = () 
+
+        checkEval "cwe90wecmp" (<@ f ()  @> ) ()
+
+        checkEval "vlwjvrwe90" (<@ let f (x:int) (y:int) = x + y in f 1 2  @>) 3
+
+        //debug <- true
+
+
+        checkEval "slnvrwe90" (<@ let rec f (x:int) : int = f x in 1  @>) 1
+
+        checkEval "2ver9ewva" (<@ let rec f1 (x:int) : int = f2 x 
+                                  and f2 x = f1 x 
+                                  1  @>) 1
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 x 
+              and f2 x = f3 x 
+              and f3 x = f1 x 
+              1  @>) 
+          1
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = fend (x-1) 
+              and fend x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = f4 (x-1) 
+              and f4 x = fend (x-1) 
+              and fend x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = f4 (x-1) 
+              and f4 x = f5 (x-1) 
+              and f5 x = fend (x-1) 
+              and fend x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = f4 (x-1) 
+              and f4 x = f5 (x-1) 
+              and f5 x = f6 (x-1) 
+              and f6 x = fend (x-1) 
+              and fend x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+        checkEval "2ver9ewvq" 
+          (<@ let rec f1 (x:int) : int = f2 (x-1) 
+              and f2 x = f3 (x-1) 
+              and f3 x = f4 (x-1) 
+              and f4 x = f5 (x-1) 
+              and f5 x = f6 (x-1) 
+              and f6 x = f7 (x-1) 
+              and f7 x = fend (x-1) 
+              and fend x = if x < 0 then -1 else f1 (x-1) 
+              f1 100  @>) 
+          -1
+
+
+
+        checkEval "2ver9ewv1" (<@ let rec f (x:int) : int = x+x in f 2  @>) 4
+
+        eval <@ let rec fib x = if x <= 2 then 1 else fib (x-1) + fib (x-2) in fib 36 @> |> ignore 
+        //(let rec fib x = if x <= 2 then 1 else fib (x-1) + fib (x-2) in fib 36)
+
+        //2.53/0.35
+
+        checkEval "2ver9ewv2" (<@ if true then 1 else 0  @>) 1
+        checkEval "2ver9ewv3" (<@ if false then 1 else 0  @>) 0
+        checkEval "2ver9ewv4" (<@ true && true @>) true
+        checkEval "2ver9ewv5" (<@ true && false @>) false
+        check "2ver9ewv6" (try eval <@ failwith "fail" : int @> with Failure "fail" -> 1 | _ -> 0) 1 
+        check "2ver9ewv7" (try eval <@ true && (failwith "fail") @> with Failure "fail" -> true | _ -> false) true
+        checkEval "2ver9ewv8" (<@ 0x001 &&& 0x100 @>) (0x001 &&& 0x100)
+        checkEval "2ver9ewv9" (<@ 0x001 ||| 0x100 @>) (0x001 ||| 0x100)
+        checkEval "2ver9ewvq" (<@ 0x011 ^^^ 0x110 @>) (0x011 ^^^ 0x110)
+        checkEval "2ver9ewvw" (<@ ~~~0x011 @>) (~~~0x011)
+
+        let _ = 1
+        checkEval "2ver9ewve" (<@ () @>) ()
+        check "2ver9ewvr" (eval <@ (fun x -> x + 1) @> (3)) 4
+        check "2ver9ewvt" (eval <@ (fun (x,y) -> x + 1) @> (3,4)) 4
+        check "2ver9ewvy" (eval <@ (fun (x1,x2,x3) -> x1 + x2 + x3) @> (3,4,5)) (3+4+5)
+        check "2ver9ewvu" (eval <@ (fun (x1,x2,x3,x4) -> x1 + x2 + x3 + x4) @> (3,4,5,6)) (3+4+5+6)
+        check "2ver9ewvi" (eval <@ (fun (x1,x2,x3,x4,x5) -> x1 + x2 + x3 + x4 + x5) @> (3,4,5,6,7)) (3+4+5+6+7)
+        check "2ver9ewvo" (eval <@ (fun (x1,x2,x3,x4,x5,x6) -> x1 + x2 + x3 + x4 + x5 + x6) @> (3,4,5,6,7,8)) (3+4+5+6+7+8)
+        check "2ver9ewvp" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7) -> x1 + x2 + x3 + x4 + x5 + x6 + x7) @> (3,4,5,6,7,8,9)) (3+4+5+6+7+8+9)
+        check "2ver9ewva" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7,x8) -> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8) @> (3,4,5,6,7,8,9,10)) (3+4+5+6+7+8+9+10)
+        check "2ver9ewvs" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7,x8,x9) -> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9) @> (3,4,5,6,7,8,9,10,11)) (3+4+5+6+7+8+9+10+11)
+        check "2ver9ewvd" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) -> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10) @> (3,4,5,6,7,8,9,10,11,12)) (3+4+5+6+7+8+9+10+11+12)
+        check "2ver9ewvf" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11) -> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11) @> (3,4,5,6,7,8,9,10,11,12,13)) (3+4+5+6+7+8+9+10+11+12+13)
+        check "2ver9ewvg" (eval <@ (fun (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12) -> x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12) @> (3,4,5,6,7,8,9,10,11,12,13,14)) (3+4+5+6+7+8+9+10+11+12+13+14)
+
+        checkEval "2ver9ewvh" (<@ while false do ()  @>) ()
+        checkEval "2ver9ewvj" (<@ let rec f (x:int) : int = f x in 1  @>) 1
+
+        checkEval "2ver9ewvk" (<@ 1 + 1 @>) 2
+        checkEval "2ver9ewvl" (<@ 1 > 1 @>) false
+        checkEval "2ver9ewvz" (<@ 1 < 1 @>) false
+        checkEval "2ver9ewvx" (<@ 1 <= 1 @>) true
+        checkEval "2ver9ewvc" (<@ 1 >= 1 @>) true
+        eval <@ System.DateTime.Now @> |> ignore
+        checkEval "2ver9ewvv" (<@ System.Int32.MaxValue @>) System.Int32.MaxValue  // literal field!
+        checkEval "2ver9ewvb" (<@ None  : int option @>) None
+        checkEval "2ver9ewvn" (<@ Some(1)  @>) (Some(1))
+        checkEval "2ver9ewvm" (<@ [] : int list @>) []
+        checkEval "2ver9ewqq" (<@ [1] @>) [1]
+        checkEval "2ver9ewqq" (<@ ["1"] @>) ["1"]
+        checkEval "2ver9ewqq" (<@ ["1";"2"] @>) ["1";"2"]
+        check "2ver9ewww" (eval <@ (fun x -> x + 1) @> 3) 4
+
+        let v = (1,2)
+        checkEval "2ver9ewer" (<@ v @>) (1,2)
+        checkEval "2ver9ewet" (<@ let x = 1 in x @>) 1
+        checkEval "2ver9ewed" (<@ let x = 1+1 in x+x @>) 4
+        let x = ref 0
+        let incrx () = incr x
+
+        checkEval "2ver9ewvec" (<@ !x @>) 0
+        checkEval "2ver9ewev" (<@ incrx() @>) ()
+        checkEval "2ver9eweb" (<@ !x @>) 3  // NOTE: checkEval evaluates the quotation three times :-)
+        checkEval "2ver9ewen" (<@ while !x < 10 do incrx() @>) ()
+        checkEval "2ver9ewem" (<@ !x @>) 10
+
+        check "2ver9ewveq" (try eval <@ raise (new System.Exception("hello")) : bool @> with :? System.Exception -> true | _ -> false) true
+
+        
+        check "2ver9ewrf" (let v2 = (3,4) in eval <@ v2 @>) (3,4)
+        
+        check "2ver9ewrg" (let v2 = (3,4) in eval <@ v2,v2 @>) ((3,4),(3,4))
+
+        checkEval "2ver9ewrt" (<@ (1,2) @>) (1,2)
+        checkEval "2ver9ewvk" (<@ (1,2,3) @>) (1,2,3)
+        checkEval "2ver9ewrh" (<@ (1,2,3,4) @>) (1,2,3,4)
+        checkEval "2ver9ewrj" (<@ (1,2,3,4,5) @>) (1,2,3,4,5)
+        checkEval "2ver9ewrk" (<@ (1,2,3,4,5,6) @>) (1,2,3,4,5,6)
+        checkEval "2ver9ewrl" (<@ (1,2,3,4,5,6,7) @>) (1,2,3,4,5,6,7)
+        checkEval "2ver9ewra" (<@ (1,2,3,4,5,6,7,8) @>) (1,2,3,4,5,6,7,8)
+        checkEval "2ver9ewrs" (<@ (1,2,3,4,5,6,7,8,9) @>) (1,2,3,4,5,6,7,8,9)
+        checkEval "2ver9ewrx" (<@ (1,2,3,4,5,6,7,8,9,10) @>) (1,2,3,4,5,6,7,8,9,10)
+        checkEval "2ver9ewrc" (<@ (1,2,3,4,5,6,7,8,9,10,11) @>) (1,2,3,4,5,6,7,8,9,10,11)
+        checkEval "2ver9ewrv" (<@ (1,2,3,4,5,6,7,8,9,10,11,12) @>) (1,2,3,4,5,6,7,8,9,10,11,12)
+        checkEval "2ver9ewrb" (<@ System.DateTime.Now.DayOfWeek @>) System.DateTime.Now.DayOfWeek
+        checkEval "2ver9ewrn" (<@ Checked.(+) 1 1 @>) 2
+        checkEval "2ver9ewrm" (<@ Checked.(-) 1 1 @>) 0
+        checkEval "2ver9ewrw" (<@ Checked.( * ) 1 1 @>) 1
+        // TODO (let) : let v2 = (3,4) in eval <@ match v2 with (x,y) -> x + y @>
+        // TODO: eval <@ "1" = "2" @>
+
+    [<Test>]
+    member this.NonGenericRecdTests() = 
+        let c1 = { Name="Don"; Data=6 }
+        let c2 = { Name="Peter"; Data=7 }
+        let c3 = { Name="Freddy"; Data=8 }
+        checkEval "2ver9e1rw1" (<@ c1.Name @>) "Don"
+        checkEval "2ver9e2rw2" (<@ c2.Name @>) "Peter"
+        checkEval "2ver9e3rw3" (<@ c2.Data @>) 7
+        checkEval "2ver9e7rw4" (<@ { Name = "Don"; Data = 6 } @>) { Name="Don"; Data=6 }
+        checkEval "2ver9e7rw5" (<@ { Name = "Don"; Data = 6 } @>) { Name="Don"; Data=6 }
+
+    [<Test>]
+    member this.GenericRecdTests() = 
+        let c1 : CustomerG<int> = { Name="Don"; Data=6 }
+        let c2 : CustomerG<int> = { Name="Peter"; Data=7 }
+        let c3 : CustomerG<string> = { Name="Freddy"; Data="8" }
+        checkEval "2ver9e4rw6" (<@ c1.Name @>) "Don"
+        checkEval "2ver9e5rw7" (<@ c2.Name @>) "Peter"
+        checkEval "2ver9e6rw8" (<@ c2.Data @>) 7
+        checkEval "2ver9e7rw9" (<@ c3.Data @>) "8"
+        checkEval "2ver9e7rwQ" (<@ { Name = "Don"; Data = 6 } @>) { Name="Don"; Data=6 }
+        checkEval "2ver9e7rwW" (<@ c1.Name <- "Ali Baba" @>) ()
+        checkEval "2ver9e7rwE" (<@ c1.Name  @>) "Ali Baba"
+
+    [<Test>]
+    member this.ArrayTests() = 
+        checkEval "2ver9e8rwR1" (<@ [| |]  @>) ([| |] : int array)
+        checkEval "2ver9e8rwR2" (<@ [| 0 |]  @>) ([| 0 |] : int array)
+        checkEval "2ver9e8rwR3" (<@ [| 0  |].[0]  @>) 0
+        checkEval "2ver9e8rwR4" (<@ [| 1; 2  |].[0]  @>) 1
+        checkEval "2ver9e8rwR5" (<@ [| 1; 2  |].[1]  @>) 2
+
+    [<Test>]
+    member this.Array2DTests() = 
+        checkEval "2ver9e8rwR6" (<@ (Array2D.init 3 4 (fun i j -> i + j)).[0,0] @>) 0
+        checkEval "2ver9e8rwR7" (<@ (Array2D.init 3 4 (fun i j -> i + j)).[1,2] @>) 3
+        checkEval "2ver9e8rwR8" (<@ (Array2D.init 3 4 (fun i j -> i + j)) |> Array2D.base1 @>) 0
+        checkEval "2ver9e8rwR9" (<@ (Array2D.init 3 4 (fun i j -> i + j)) |> Array2D.base2 @>) 0
+        checkEval "2ver9e8rwRQ" (<@ (Array2D.init 3 4 (fun i j -> i + j)) |> Array2D.length1 @>) 3
+        checkEval "2ver9e8rwRW" (<@ (Array2D.init 3 4 (fun i j -> i + j)) |> Array2D.length2 @>) 4
+
+
+    [<Test>]
+    member this.Array3DTests() = 
+        checkEval "2ver9e8rwRE" (<@ (Array3D.init 3 4 5 (fun i j k -> i + j)).[0,0,0] @>) 0
+        checkEval "2ver9e8rwRR" (<@ (Array3D.init 3 4 5 (fun i j k -> i + j + k)).[1,2,3] @>) 6
+        checkEval "2ver9e8rwRT" (<@ (Array3D.init 3 4 5 (fun i j k -> i + j)) |> Array3D.length1 @>) 3
+        checkEval "2ver9e8rwRY" (<@ (Array3D.init 3 4 5 (fun i j k -> i + j)) |> Array3D.length2 @>) 4
+        checkEval "2ver9e8rwRU" (<@ (Array3D.init 3 4 5 (fun i j k -> i + j)) |> Array3D.length3 @>) 5
+
+    [<Test>]
+    member this.ExceptionTests() = 
+        let c1 = E0
+        let c2 = E1 "1"
+        let c3 = E1 "2"
+        checkEval "2ver9e8rwR" (<@ E0  @>) E0
+        checkEval "2ver9e8rwT" (<@ E1 "1"  @>) (E1 "1")
+        checkEval "2ver9eQrwY" (<@ match c1 with E0 -> 1 | _ -> 2  @>) 1
+        checkEval "2ver9eQrwU" (<@ match c2 with E0 -> 1 | _ -> 2  @>) 2
+        checkEval "2ver9eQrwI" (<@ match c2 with E0 -> 1 | E1 _  -> 2 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwO" (<@ match c2 with E1 _  -> 2 | E0 -> 1 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwP" (<@ match c2 with E1 "1"  -> 2 | E0 -> 1 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwA" (<@ match c2 with E1 "2"  -> 2 | E0 -> 1 | _ -> 3  @>) 3
+        checkEval "2ver9eQrwS" (<@ match c3 with E1 "2"  -> 2 | E0 -> 1 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwD1" (<@ try failwith "" with _ -> 2  @>) 2
+        checkEval "2ver9eQrwD2" (<@ let x = ref 0 in 
+                                    try 
+                                           try failwith "" 
+                                           finally incr x 
+                                    with _ -> !x @>) 1
+        checkEval "2ver9eQrwD3" (<@ let x = ref 0 in 
+                                    (try incr x; incr x
+                                     finally incr x )
+                                    x.Value @>) 3
+        checkEval "2ver9eQrwD4" (<@ try 3 finally () @>) 3
+        checkEval "2ver9eQrwD5" (<@ try () finally () @>) ()
+        checkEval "2ver9eQrwD6" (<@ try () with _ -> () @>) ()
+        checkEval "2ver9eQrwD7" (<@ try raise E0 with E0 -> 2  @>) 2
+        checkEval "2ver9eQrwF" (<@ try raise c1 with E0 -> 2  @>) 2
+        checkEval "2ver9eQrwG" (<@ try raise c2 with E0 -> 2 | E1 "1" -> 3 @>) 3
+        checkEval "2ver9eQrwH" (<@ try raise c2 with E1 "1" -> 3 | E0 -> 2  @>) 3
+
+    [<Test>]
+    member this.TypeTests() = 
+        let c1 = C0()
+        let c2 = C1 "1"
+        let c3 = C1 "2"
+        checkEval "2ver9e8rwJ" (<@ C0().P  @>) 1
+        checkEval "2ver9e8rwK" (<@ C1("1").P  @>)  "1"
+        checkEval "2ver9eQrwL" (<@ match box c1 with :? C0 -> 1 | _ -> 2  @>) 1
+        checkEval "2ver9eQrwZ" (<@ match box c2 with :? C0 -> 1 | _ -> 2  @>) 2
+        checkEval "2ver9eQrwX" (<@ match box c2 with :? C0 -> 1 | :? C1   -> 2 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwC" (<@ match box c2 with :? C1   -> 2 | :? C0 -> 1 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwV" (<@ match box c2 with :? C1  -> 2 | :? C0 -> 1 | _ -> 3  @>) 2
+        checkEval "2ver9eQrwN" (<@ match box c3 with :? C1  as c1 when c1.P = "2"  -> 2 | :? C0 -> 1 | _ -> 3  @>) 2
+
+    [<Test>]
+    member this.NonGenericUnionTests0() = 
+        let c1 = Union10.Case1 "meow"
+        let c2 = Union10.Case2
+        checkEval "2ver9e8rw11" (<@ Union10.Case1 "sss" @>) (Union10.Case1 "sss")
+        checkEval "2ver9e9rw12" (<@ Union10.Case2 @>) Union10.Case2
+        checkEval "2ver9eQrw13" (<@ match c1 with Union10.Case1 _ -> 2 | Union10.Case2 -> 1 @>) 2
+        checkEval "2ver9eWrw14" (<@ match c1 with Union10.Case1 s -> s | Union10.Case2 -> "woof" @>) "meow"
+        checkEval "2ver9eErw15" (<@ match c2 with Union10.Case1 s -> s | Union10.Case2 -> "woof" @>) "woof"
+
+    [<Test>]
+    member this.NonGenericUnionTests1() = 
+        let c1 = Union1.Case1 "meow"
+        checkEval "2ver9e8rw16" (<@ Union1.Case1 "sss" @>) (Union1.Case1 "sss")
+        checkEval "2ver9eQrw17" (<@ match c1 with Union1.Case1 _ -> 2  @>) 2
+        checkEval "2ver9eWrw18" (<@ match c1 with Union1.Case1 s -> s  @>) "meow"
+
+    [<Test>]
+    member this.NonGenericUnionTests2() = 
+        let c1 = Union11.Case1 "meow"
+        let c2 = Union11.Case2 "woof"
+        checkEval "2ver9e8rw19" (<@ Union11.Case1 "sss" @>) (Union11.Case1 "sss")
+        checkEval "2ver9e9rw20" (<@ Union11.Case2 "bowwow" @>) (Union11.Case2 "bowwow")
+        checkEval "2ver9eQrw21" (<@ match c1 with Union11.Case1 _ -> 2 | Union11.Case2  _ -> 1 @>) 2
+        checkEval "2ver9eWrw22" (<@ match c1 with Union11.Case1 s -> s | Union11.Case2 s -> s @>) "meow"
+        checkEval "2ver9eErw23" (<@ match c2 with Union11.Case1 s -> s | Union11.Case2 s -> s @>) "woof"
+
+    [<Test>]
+    member this.NonGenericUnionTests3() = 
+        let c1 = Union1111.Case1 "meow"
+        let c2 = Union1111.Case2 "woof"
+        checkEval "2ver9e8rw24" (<@ Union1111.Case1 "sss" @>) (Union1111.Case1 "sss")
+        checkEval "2ver9e9rw25" (<@ Union1111.Case2 "bowwow" @>) (Union1111.Case2 "bowwow")
+        checkEval "2ver9eQrw26" (<@ match c1 with Union1111.Case1 _ -> 2 | _ -> 1 @>) 2
+        checkEval "2ver9eWrw27" (<@ match c1 with Union1111.Case1 s -> s | _ -> "woof" @>) "meow"
+        checkEval "2ver9eErw28" (<@ match c2 with Union1111.Case1 s -> s | Union1111.Case2 s -> s | _ -> "bark" @>) "woof"
+
+
+    [<Test>]
+    member this.GenericUnionTests() = 
+        let c1 = GUnion10.Case1 "meow"
+        let c2 = GUnion10<string>.Case2
+        checkEval "2ver9e8rw29" (<@ GUnion10.Case1 "sss" @>) (GUnion10.Case1 "sss")
+        checkEval "2ver9e9rw30" (<@ GUnion10.Case2 @>) GUnion10.Case2
+        checkEval "2ver9eQrw31" (<@ match c1 with GUnion10.Case1 _ -> 2 | GUnion10.Case2 -> 1 @>) 2
+        checkEval "2ver9eWrw32" (<@ match c1 with GUnion10.Case1 s -> s | GUnion10.Case2 -> "woof" @>) "meow"
+        checkEval "2ver9eErw33" (<@ match c2 with GUnion10.Case1 s -> s | GUnion10.Case2 -> "woof" @>) "woof"
+
+    [<Test>]
+    member this.InlinedOperationsStillDynamicallyAvailableTests() = 
+
+        checkEval "vroievr093" (<@ LanguagePrimitives.GenericZero<sbyte> @>)  0y
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<int16> @>)  0s
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<int32> @>)  0
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<int64> @>)  0L
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<nativeint> @>)  0n
+        checkEval "vroievr093" (<@ LanguagePrimitives.GenericZero<byte> @>)  0uy
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<uint16> @>)  0us
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<uint32> @>)  0u
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<uint64> @>)  0UL
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<unativeint> @>)  0un
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<float> @>)  0.0
+        checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero<float32> @>)  0.0f
+        checkEval "vroievr092" (<@ LanguagePrimitives.GenericZero<decimal> @>)  0M
+
+
+
+        checkEval "vroievr093" (<@ LanguagePrimitives.GenericOne<sbyte> @>)  1y
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<int16> @>)  1s
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<int32> @>)  1
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<int64> @>)  1L
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<nativeint> @>)  1n
+        checkEval "vroievr193" (<@ LanguagePrimitives.GenericOne<byte> @>)  1uy
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<uint16> @>)  1us
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<uint32> @>)  1u
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<uint64> @>)  1UL
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<unativeint> @>)  1un
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<float> @>)  1.0
+        checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne<float32> @>)  1.0f
+        checkEval "vroievr192" (<@ LanguagePrimitives.GenericOne<decimal> @>)  1M
+
+        check "vroievr0971" (LanguagePrimitives.AdditionDynamic 3y 4y) 7y
+        check "vroievr0972" (LanguagePrimitives.AdditionDynamic 3s 4s) 7s
+        check "vroievr0973" (LanguagePrimitives.AdditionDynamic 3 4) 7
+        check "vroievr0974" (LanguagePrimitives.AdditionDynamic 3L 4L) 7L
+        check "vroievr0975" (LanguagePrimitives.AdditionDynamic 3n 4n) 7n
+        check "vroievr0976" (LanguagePrimitives.AdditionDynamic 3uy 4uy) 7uy
+        check "vroievr0977" (LanguagePrimitives.AdditionDynamic 3us 4us) 7us
+        check "vroievr0978" (LanguagePrimitives.AdditionDynamic 3u 4u) 7u
+        check "vroievr0979" (LanguagePrimitives.AdditionDynamic 3UL 4UL) 7UL
+        check "vroievr0970" (LanguagePrimitives.AdditionDynamic 3un 4un) 7un
+        check "vroievr097q" (LanguagePrimitives.AdditionDynamic 3.0 4.0) 7.0
+        check "vroievr097w" (LanguagePrimitives.AdditionDynamic 3.0f 4.0f) 7.0f
+        check "vroievr097e" (LanguagePrimitives.AdditionDynamic 3.0M 4.0M) 7.0M
+
+        check "vroievr097r" (LanguagePrimitives.CheckedAdditionDynamic 3y 4y) 7y
+        check "vroievr097t" (LanguagePrimitives.CheckedAdditionDynamic 3s 4s) 7s
+        check "vroievr097y" (LanguagePrimitives.CheckedAdditionDynamic 3 4) 7
+        check "vroievr097u" (LanguagePrimitives.CheckedAdditionDynamic 3L 4L) 7L
+        check "vroievr097i" (LanguagePrimitives.CheckedAdditionDynamic 3n 4n) 7n
+        check "vroievr097o" (LanguagePrimitives.CheckedAdditionDynamic 3uy 4uy) 7uy
+        check "vroievr097p" (LanguagePrimitives.CheckedAdditionDynamic 3us 4us) 7us
+        check "vroievr097a" (LanguagePrimitives.CheckedAdditionDynamic 3u 4u) 7u
+        check "vroievr097s" (LanguagePrimitives.CheckedAdditionDynamic 3UL 4UL) 7UL
+        check "vroievr097d" (LanguagePrimitives.CheckedAdditionDynamic 3un 4un) 7un
+        check "vroievr097f" (LanguagePrimitives.CheckedAdditionDynamic 3.0 4.0) 7.0
+        check "vroievr097g" (LanguagePrimitives.CheckedAdditionDynamic 3.0f 4.0f) 7.0f
+        check "vroievr097h" (LanguagePrimitives.CheckedAdditionDynamic 3.0M 4.0M) 7.0M
+
+        check "vroievr0912q" (LanguagePrimitives.MultiplyDynamic 3y 4y) 12y
+        check "vroievr0912w" (LanguagePrimitives.MultiplyDynamic 3s 4s) 12s
+        check "vroievr0912e" (LanguagePrimitives.MultiplyDynamic 3 4) 12
+        check "vroievr0912r" (LanguagePrimitives.MultiplyDynamic 3L 4L) 12L
+        check "vroievr0912t" (LanguagePrimitives.MultiplyDynamic 3n 4n) 12n
+        check "vroievr0912y" (LanguagePrimitives.MultiplyDynamic 3uy 4uy) 12uy
+        check "vroievr0912u" (LanguagePrimitives.MultiplyDynamic 3us 4us) 12us
+        check "vroievr0912i" (LanguagePrimitives.MultiplyDynamic 3u 4u) 12u
+        check "vroievr0912o" (LanguagePrimitives.MultiplyDynamic 3UL 4UL) 12UL
+        check "vroievr0912p" (LanguagePrimitives.MultiplyDynamic 3un 4un) 12un
+        check "vroievr0912a" (LanguagePrimitives.MultiplyDynamic 3.0 4.0) 12.0
+        check "vroievr0912s" (LanguagePrimitives.MultiplyDynamic 3.0f 4.0f) 12.0f
+        check "vroievr0912d" (LanguagePrimitives.MultiplyDynamic 3.0M 4.0M) 12.0M
+
+
+        check "vroievr0912f" (LanguagePrimitives.CheckedMultiplyDynamic 3y 4y) 12y
+        check "vroievr0912g" (LanguagePrimitives.CheckedMultiplyDynamic 3s 4s) 12s
+        check "vroievr0912h" (LanguagePrimitives.CheckedMultiplyDynamic 3 4) 12
+        check "vroievr0912j" (LanguagePrimitives.CheckedMultiplyDynamic 3L 4L) 12L
+        check "vroievr0912k" (LanguagePrimitives.CheckedMultiplyDynamic 3n 4n) 12n
+        check "vroievr0912l" (LanguagePrimitives.CheckedMultiplyDynamic 3uy 4uy) 12uy
+        check "vroievr0912z" (LanguagePrimitives.CheckedMultiplyDynamic 3us 4us) 12us
+        check "vroievr0912x" (LanguagePrimitives.CheckedMultiplyDynamic 3u 4u) 12u
+        check "vroievr0912c" (LanguagePrimitives.CheckedMultiplyDynamic 3UL 4UL) 12UL
+        check "vroievr0912v" (LanguagePrimitives.CheckedMultiplyDynamic 3un 4un) 12un
+        check "vroievr0912b" (LanguagePrimitives.CheckedMultiplyDynamic 3.0 4.0) 12.0
+        check "vroievr0912n" (LanguagePrimitives.CheckedMultiplyDynamic 3.0f 4.0f) 12.0f
+        check "vroievr0912m" (LanguagePrimitives.CheckedMultiplyDynamic 3.0M 4.0M) 12.0M
+
+
+        let iarr = [| 0..1000 |]
+        let ilist = [ 0..1000 ]
+
+        let farr = [| 0.0 .. 1.0 .. 100.0 |]
+        let flist = [ 0.0 .. 1.0 .. 100.0 ]
+
+        Array.average farr |> ignore
+
+        checkEval "vrewoinrv091" (<@ farr.[0] @>) 0.0
+        checkEval "vrewoinrv092" (<@ flist.[0] @>) 0.0
+        checkEval "vrewoinrv093" (<@ iarr.[0] @>) 0
+        checkEval "vrewoinrv094" (<@ ilist.[0] @>) 0
+
+        checkEval "vrewoinrv095" (<@ farr.[0] <- 0.0 @>) ()
+        checkEval "vrewoinrv096" (<@ iarr.[0] <- 0 @>) ()
+
+        checkEval "vrewoinrv097" (<@ farr.[0] <- 1.0 @>) ()
+        checkEval "vrewoinrv098" (<@ iarr.[0] <- 1 @>) ()
+
+        checkEval "vrewoinrv099" (<@ farr.[0] @>) 1.0
+        checkEval "vrewoinrv09q" (<@ iarr.[0] @>) 1
+
+        checkEval "vrewoinrv09w" (<@ farr.[0] <- 0.0 @>) ()
+        checkEval "vrewoinrv09e" (<@ iarr.[0] <- 0 @>) ()
+
+
+        checkEval "vrewoinrv09r" (<@ Array.average farr @>) (Array.average farr)
+        checkEval "vrewoinrv09t" (<@ Array.sum farr @>) (Array.sum farr)
+        checkEval "vrewoinrv09y" (<@ Seq.sum farr @>) (Seq.sum farr)
+        checkEval "vrewoinrv09u" (<@ Seq.average farr @>) (Seq.average farr) 
+        checkEval "vrewoinrv09i" (<@ Seq.average flist @>) (Seq.average flist)
+        checkEval "vrewoinrv09o" (<@ Seq.averageBy (fun x -> x) farr @> ) (Seq.averageBy (fun x -> x) farr )
+        checkEval "vrewoinrv09p" (<@ Seq.averageBy (fun x -> x) flist @>) (Seq.averageBy (fun x -> x) flist )
+        checkEval "vrewoinrv09a" (<@ Seq.averageBy float ilist @>) (Seq.averageBy float ilist)
+        checkEval "vrewoinrv09s" (<@ List.sum flist @>) (List.sum flist)
+        checkEval "vrewoinrv09d" (<@ List.average flist @>) (List.average flist)
+        checkEval "vrewoinrv09f" (<@ List.averageBy float ilist @>) (List.averageBy float ilist)
+
+        checkEval "vrewoinrv09g1" (<@ compare 0 0 = 0 @>) true
+        checkEval "vrewoinrv09g2" (<@ compare 0 1 < 0 @>) true
+        checkEval "vrewoinrv09g3" (<@ compare 1 0 > 0 @>) true
+        checkEval "vrewoinrv09g4" (<@ 0 < 1 @>) true
+        checkEval "vrewoinrv09g5" (<@ 0 <= 1 @>) true
+        checkEval "vrewoinrv09g6" (<@ 1 <= 1 @>) true
+        checkEval "vrewoinrv09g7" (<@ 2 <= 1 @>) false
+        checkEval "vrewoinrv09g8" (<@ 0 > 1 @>) false
+        checkEval "vrewoinrv09g9" (<@ 0 >= 1 @>) false
+        checkEval "vrewoinrv09g0" (<@ 1 >= 1 @>) true
+        checkEval "vrewoinrv09gQ" (<@ 2 >= 1 @>) true
+
+        checkEval "vrewoinrv09gw" (<@ compare 0.0 0.0 = 0 @>) true
+        checkEval "vrewoinrv09ge" (<@ compare 0.0 1.0 < 0 @>) true
+        checkEval "vrewoinrv09gr" (<@ compare 1.0 0.0 > 0 @>) true
+        checkEval "vrewoinrv09gt" (<@ 0.0 < 1.0 @>) true
+        checkEval "vrewoinrv09gy" (<@ 0.0 <= 1.0 @>) true
+        checkEval "vrewoinrv09gu" (<@ 1.0 <= 1.0 @>) true
+        checkEval "vrewoinrv09gi" (<@ 2.0 <= 1.0 @>) false
+        checkEval "vrewoinrv09go" (<@ 0.0 > 1.0 @>) false
+        checkEval "vrewoinrv09gp" (<@ 0.0 >= 1.0 @>) false
+        checkEval "vrewoinrv09ga" (<@ 1.0 >= 1.0 @>) true
+        checkEval "vrewoinrv09gs" (<@ 2.0 >= 1.0 @>) true
+
+        checkEval "vrewoinrv09gd" (<@ compare 0.0f 0.0f = 0 @>) true
+        checkEval "vrewoinrv09gf" (<@ compare 0.0f 1.0f < 0 @>) true
+        checkEval "vrewoinrv09gg" (<@ compare 1.0f 0.0f > 0 @>) true
+        checkEval "vrewoinrv09gh" (<@ 0.0f < 1.0f @>) true
+        checkEval "vrewoinrv09gk" (<@ 0.0f <= 1.0f @>) true
+        checkEval "vrewoinrv09gl" (<@ 1.0f <= 1.0f @>) true
+        checkEval "vrewoinrv09gz" (<@ 2.0f <= 1.0f @>) false
+        checkEval "vrewoinrv09gx" (<@ 0.0f > 1.0f @>) false
+        checkEval "vrewoinrv09gc" (<@ 0.0f >= 1.0f @>) false
+        checkEval "vrewoinrv09gv" (<@ 1.0f >= 1.0f @>) true
+        checkEval "vrewoinrv09gb" (<@ 2.0f >= 1.0f @>) true
+
+        checkEval "vrewoinrv09gn" (<@ compare 0L 0L = 0 @>) true
+        checkEval "vrewoinrv09gm" (<@ compare 0L 1L < 0 @>) true
+        checkEval "vrewoinrv09g11" (<@ compare 1L 0L > 0 @>) true
+        checkEval "vrewoinrv09g12" (<@ 0L < 1L @>) true
+        checkEval "vrewoinrv09g13" (<@ 0L <= 1L @>) true
+        checkEval "vrewoinrv09g14" (<@ 1L <= 1L @>) true
+        checkEval "vrewoinrv09g15" (<@ 2L <= 1L @>) false
+        checkEval "vrewoinrv09g16" (<@ 0L > 1L @>) false
+        checkEval "vrewoinrv09g17" (<@ 0L >= 1L @>) false
+        checkEval "vrewoinrv09g18" (<@ 1L >= 1L @>) true
+        checkEval "vrewoinrv09g19" (<@ 2L >= 1L @>) true
+
+        checkEval "vrewoinrv09g21" (<@ compare 0y 0y = 0 @>) true
+        checkEval "vrewoinrv09g22" (<@ compare 0y 1y < 0 @>) true
+        checkEval "vrewoinrv09g23" (<@ compare 1y 0y > 0 @>) true
+        checkEval "vrewoinrv09g24" (<@ 0y < 1y @>) true
+        checkEval "vrewoinrv09g25" (<@ 0y <= 1y @>) true
+        checkEval "vrewoinrv09g26" (<@ 1y <= 1y @>) true
+        checkEval "vrewoinrv09g27" (<@ 2y <= 1y @>) false
+        checkEval "vrewoinrv09g28" (<@ 0y > 1y @>) false
+        checkEval "vrewoinrv09g29" (<@ 0y >= 1y @>) false
+        checkEval "vrewoinrv09g30" (<@ 1y >= 1y @>) true
+        checkEval "vrewoinrv09g31" (<@ 2y >= 1y @>) true
+
+        checkEval "vrewoinrv09g32" (<@ compare 0M 0M = 0 @>) true
+        checkEval "vrewoinrv09g33" (<@ compare 0M 1M < 0 @>) true
+        checkEval "vrewoinrv09g34" (<@ compare 1M 0M > 0 @>) true
+        checkEval "vrewoinrv09g35" (<@ 0M < 1M @>) true
+        checkEval "vrewoinrv09g36" (<@ 0M <= 1M @>) true
+        checkEval "vrewoinrv09g37" (<@ 1M <= 1M @>) true
+        checkEval "vrewoinrv09g38" (<@ 2M <= 1M @>) false
+        checkEval "vrewoinrv09g39" (<@ 0M > 1M @>) false
+        checkEval "vrewoinrv09g40" (<@ 0M >= 1M @>) false
+        checkEval "vrewoinrv09g41" (<@ 1M >= 1M @>) true
+        checkEval "vrewoinrv09g42" (<@ 2M >= 1M @>) true
+
+        checkEval "vrewoinrv09g43" (<@ compare 0I 0I = 0 @>) true
+        checkEval "vrewoinrv09g44" (<@ compare 0I 1I < 0 @>) true
+        checkEval "vrewoinrv09g45" (<@ compare 1I 0I > 0 @>) true
+        checkEval "vrewoinrv09g46" (<@ 0I < 1I @>) true
+        checkEval "vrewoinrv09g47" (<@ 0I <= 1I @>) true
+        checkEval "vrewoinrv09g48" (<@ 1I <= 1I @>) true
+        checkEval "vrewoinrv09g49" (<@ 2I <= 1I @>) false
+        checkEval "vrewoinrv09g50" (<@ 0I > 1I @>) false
+        checkEval "vrewoinrv09g51" (<@ 0I >= 1I @>) false
+        checkEval "vrewoinrv09g52" (<@ 1I >= 1I @>) true
+        checkEval "vrewoinrv09g53" (<@ 2I >= 1I @>) true
+
+
+        checkEval "vrewoinrv09g" (<@ sin 0.0 @>) (sin 0.0)
+        checkEval "vrewoinrv09h" (<@ sinh 0.0 @>) (sinh 0.0)
+        checkEval "vrewoinrv09j" (<@ cos 0.0 @>) (cos 0.0)
+        checkEval "vrewoinrv09k" (<@ cosh 0.0 @>) (cosh 0.0)
+        checkEval "vrewoinrv09l" (<@ tan 1.0 @>) (tan 1.0)
+        checkEval "vrewoinrv09z" (<@ tanh 1.0 @>) (tanh 1.0)
+        checkEval "vrewoinrv09x" (<@ abs -2.0 @>) (abs -2.0)
+        checkEval "vrewoinrv09c" (<@ ceil 2.0 @>) (ceil 2.0)
+        checkEval "vrewoinrv09v" (<@ sqrt 2.0 @>) (sqrt 2.0)
+        checkEval "vrewoinrv09b" (<@ sign 2.0 @>) (sign 2.0)
+#if FX_NO_TRUNCATE
+#else
+        checkEval "vrewoinrv09n" (<@ truncate 2.3 @>) (truncate 2.3)
+#endif
+        checkEval "vrewoinrv09m" (<@ floor 2.3 @>) (floor 2.3)
+        checkEval "vrewoinrv09Q" (<@ round 2.3 @>) (round 2.3)
+        checkEval "vrewoinrv09W" (<@ log 2.3 @>) (log 2.3)
+        checkEval "vrewoinrv09E" (<@ log10 2.3 @>) (log10 2.3)
+        checkEval "vrewoinrv09R" (<@ exp 2.3 @>) (exp 2.3)
+        checkEval "vrewoinrv09T" (<@ 2.3 ** 2.4 @>) (2.3 ** 2.4)
+
+        checkEval "vrewoinrv09Y" (<@ sin 0.0f @>) (sin 0.0f)
+        checkEval "vrewoinrv09U" (<@ sinh 0.0f @>) (sinh 0.0f)
+        checkEval "vrewoinrv09I" (<@ cos 0.0f @>) (cos 0.0f)
+        checkEval "vrewoinrv09O" (<@ cosh 0.0f @>) (cosh 0.0f)
+        checkEval "vrewoinrv09P" (<@ tan 1.0f @>) (tan 1.0f)
+        checkEval "vrewoinrv09A" (<@ tanh 1.0f @>) (tanh 1.0f)
+        checkEval "vrewoinrv09S" (<@ abs -2.0f @>) (abs -2.0f)
+        checkEval "vrewoinrv09D" (<@ ceil 2.0f @>) (ceil 2.0f)
+        checkEval "vrewoinrv09F" (<@ sqrt 2.0f @>) (sqrt 2.0f)
+        checkEval "vrewoinrv09G" (<@ sign 2.0f @>) (sign 2.0f)
+#if FX_NO_TRUNCATE
+#else
+        checkEval "vrewoinrv09H" (<@ truncate 2.3f @>) (truncate 2.3f)
+#endif
+        checkEval "vrewoinrv09J" (<@ floor 2.3f @>) (floor 2.3f)
+        checkEval "vrewoinrv09K" (<@ round 2.3f @>) (round 2.3f)
+        checkEval "vrewoinrv09L" (<@ log 2.3f @>) (log 2.3f)
+        checkEval "vrewoinrv09Z" (<@ log10 2.3f @>) (log10 2.3f)
+        checkEval "vrewoinrv09X" (<@ exp 2.3f @>) (exp 2.3f)
+        checkEval "vrewoinrv09C" (<@ 2.3f ** 2.4f @>) (2.3f ** 2.4f)
+
+        checkEval "vrewoinrv09V" (<@ ceil 2.0M @>) (ceil 2.0M)
+        checkEval "vrewoinrv09B" (<@ sign 2.0M @>) (sign 2.0M)
+#if FX_NO_TRUNCATE
+#else
+        checkEval "vrewoinrv09N" (<@ truncate 2.3M @>) (truncate 2.3M)
+#endif
+        checkEval "vrewoinrv09M" (<@ floor 2.3M @>) (floor 2.3M)
+
+        checkEval "vrewoinrv09QQ" (<@ sign -2 @>) (sign -2)
+        checkEval "vrewoinrv09WW" (<@ sign -2y @>) (sign -2y)
+        checkEval "vrewoinrv09EE" (<@ sign -2s @>) (sign -2s)
+        checkEval "vrewoinrv09RR" (<@ sign -2L @>) (sign -2L)
+
+        checkEval "vrewoinrv09TT" (<@ [ 0 .. 10 ] @>) [ 0 .. 10 ]
+        checkEval "vrewoinrv09YY" (<@ [ 0y .. 10y ] @>) [ 0y .. 10y ]
+        checkEval "vrewoinrv09UU" (<@ [ 0s .. 10s ] @>) [ 0s .. 10s ]
+        checkEval "vrewoinrv09II" (<@ [ 0L .. 10L ] @>) [ 0L .. 10L ]
+        checkEval "vrewoinrv09OO" (<@ [ 0u .. 10u ] @>) [ 0u .. 10u ]
+        checkEval "vrewoinrv09PP" (<@ [ 0uy .. 10uy ] @>) [ 0uy .. 10uy ]
+        checkEval "vrewoinrv09AA" (<@ [ 0us .. 10us ] @>) [ 0us .. 10us ]
+        checkEval "vrewoinrv09SS" (<@ [ 0UL .. 10UL ] @>) [ 0UL .. 10UL ]
+        
+        // op_Range dynamic disptach
+        checkEval "vrewoinrv09DD" (<@ [ 0N .. 10N ] @>) [ 0N .. 10N ]
+
+#if FX_NO_DEFAULT_DECIMAL_ROUND
+#else        
+        // Round dynamic dispatch on Decimal
+        checkEval "vrewoinrv09FF" (<@ round 2.3M @>) (round 2.3M)
+#endif
+
+        // Measure stuff:
+        checkEval "vrewoinrv09GG" (<@ atan2 3.0 4.0 @>) (atan2 3.0 4.0 )
+        
+        checkEval "vrewoinrv09HH" (<@ 1.0<kg> @>) (1.0<kg>)
+
+        // Measure stuff:
+        checkEval "vrewoinrv09JJ" (<@ 1.0<kg> + 2.0<kg> @>) (3.0<kg>)
+
+
+        eval <@ Array.average [| 0.0 .. 1.0 .. 10000.0 |] @> |> ignore 
+
+    [<Test>]
+    member this.LanguagePrimitiveCastingUnitsOfMeasure() = 
+
+        checkEval "castingunits1" (<@ 2.5 |> LanguagePrimitives.FloatWithMeasure<m> |> float @>) 2.5
+        checkEval "castingunits2" (<@ 2.5f |> LanguagePrimitives.Float32WithMeasure<m> |> float32 @>) 2.5f
+        checkEval "castingunits3" (<@ 2.0m |> LanguagePrimitives.DecimalWithMeasure<m> |> decimal @>) 2.0M
+        checkEval "castingunits4" (<@ 2 |> LanguagePrimitives.Int32WithMeasure<m> |> int @>) 2
+        checkEval "castingunits5" (<@ 2L |> LanguagePrimitives.Int64WithMeasure<m> |> int64 @>) 2L
+        checkEval "castingunits6" (<@ 2s |> LanguagePrimitives.Int16WithMeasure<m> |> int16 @>) 2s
+        checkEval "castingunits7" (<@ 2y |> LanguagePrimitives.SByteWithMeasure<m> |> sbyte @>) 2y
+
+    [<Test>]
+    member this.QuotationTests() = 
+        let (|Seq|_|) = function SpecificCall <@ seq @>(_, [_],[e]) -> Some e | _ -> None
+        let (|Append|_|) = function SpecificCall <@ Seq.append @>(_, [_],[e1;e2]) -> Some (e1,e2) | _ -> None
+        let (|Delay|_|) = function SpecificCall <@ Seq.delay @>(_, [_],[Lambda(_,e)]) -> Some e | _ -> None
+        let (|FinalFor|_|) = function SpecificCall <@ Seq.map @>(_, [_;_],[Lambda(v,e);sq]) -> Some (v,sq,e) | _ -> None
+        let (|OuterFor|_|) = function SpecificCall <@ Seq.collect @>(_, [_;_;_],[Lambda(v,e);sq]) -> Some (v,sq,e) | _ -> None
+        let (|Yield|_|) = function SpecificCall <@ Seq.singleton @>(_, [_],[e]) -> Some (e) | _ -> None
+        let (|While|_|) = function SpecificCall <@ Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.EnumerateWhile @>(_, [_],[e1;e2]) -> Some (e1,e2) | _ -> None
+        let (|TryFinally|_|) = function SpecificCall <@ Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.EnumerateThenFinally @>(_, [_],[e1;e2]) -> Some (e1,e2) | _ -> None
+        let (|Using|_|) = function SpecificCall <@ Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.EnumerateUsing @>(_, _,[e1;Lambda(v1,e2)]) -> Some (v1,e1,e2) | _ -> None
+        let (|Empty|_|) = function SpecificCall <@ Seq.empty @>(_,_,_) -> Some () | _ -> None
+        test "vrenjkr90kj1" 
+           (match <@ seq { for x in [1] -> x } @> with 
+            | Seq(Delay(FinalFor(v,Coerce(sq,_),res))) when sq = <@@ [1] @@> && res = Expr.Var(v) -> true
+            | Seq(Delay(FinalFor(v,sq,res))) -> printfn "v = %A, res = %A, sq = %A" v res sq; false
+            | Seq(Delay(sq)) -> printfn "Seq(Delay(_)), tm = %A" sq; false
+            | Seq(sq) -> printfn "Seq(_), tm = %A" sq; false 
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj2" 
+           (match <@ seq { for x in [1] do yield x } @> with 
+            | Seq(Delay(FinalFor(v,Coerce(sq,_),res))) when sq = <@@ [1] @@> && res = Expr.Var(v) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj3" 
+           (match <@ seq { for x in [1] do for y in [2] do yield x } @> with 
+            | Seq(Delay(OuterFor(v1,Coerce(sq1,_),FinalFor(v2,Coerce(sq2,_),res)))) when sq1 = <@@ [1] @@> && sq2 = <@@ [2] @@> && res = Expr.Var(v1) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj4" 
+           (match <@ seq { if true then yield 1 else yield 2 } @> with 
+            | Seq(Delay(IfThenElse(_,Yield(Int32(1)),Yield(Int32(2))))) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj5" 
+           (match <@ seq { for x in [1] do if true then yield x else yield 2 } @> with 
+            | Seq(Delay(OuterFor(vx,Coerce(sq,_),IfThenElse(_,Yield(res),Yield(Int32(2)))))) when sq = <@@ [1] @@>  && res = Expr.Var(vx) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj6" 
+           (match <@ seq { yield 1; yield 2 } @> with 
+            | Seq(Delay(Append(Yield(Int32(1)),Delay(Yield(Int32(2)))))) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj7" 
+           (match <@ seq { while true do yield 1 } @> with 
+            | Seq(Delay(While(Lambda(_,Bool(true)),Delay(Yield(Int32(1)))))) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj8" 
+           (match <@ seq { while true do yield 1 } @> with 
+            | Seq(Delay(While(Lambda(_,Bool(true)),Delay(Yield(Int32(1)))))) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj9" 
+           (match <@ seq { try yield 1 finally () } @> with 
+            | Seq(Delay(TryFinally(Delay(Yield(Int32(1))), Lambda(_,Unit)))) -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kj9" 
+           (match <@ seq { use ie = failwith "" in yield! Seq.empty } @> with 
+            | Seq(Delay(Using(v1,e1,Empty))) when v1.Name = "ie" -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kjA" 
+           (match <@ (3 :> obj) @> with 
+            | Coerce(Int32(3),ty) when ty = typeof<obj> -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kjB" 
+           (match <@ ("3" :> obj) @> with 
+            | Coerce(String("3"),ty) when ty = typeof<obj> -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+        test "vrenjkr90kjC" 
+           (match <@ ("3" :> System.IComparable) @> with 
+            | Coerce(String("3"),ty) when ty = typeof<System.IComparable> -> true
+            | sq -> printfn "tm = %A" sq; false) 
+
+(*
+    test "vrenjkr90kjD" 
+       (match <@ (new obj() :?> System.IComparable) @> with 
+        | Coerce(NewObject(_),ty) when ty = typeof<System.IComparable> -> true
+        | sq -> printfn "tm = %A" sq; false) 
+
+    test "vrenjkr90kjE" 
+       (match <@ (new obj() :?> obj) @> with 
+        | NewObject(_) -> true
+        | sq -> printfn "tm = %A" sq; false) 
+*)
+
+
+    [<Test>]
+    member this.LargerAutomaticDiferentiationTest_FSharp_1_0_Bug_3498() = 
+
+          let q = 
+              <@ (fun (x1:double) -> 
+                     let fwd6 = 
+                         let y3 = x1 * x1
+                         (y3, (fun yb4 -> yb4 * 2.0 * x1))
+                     let rev5 = snd fwd6
+                     let w0 = fst fwd6
+
+                     let fwd14 = 
+                         let y11 = w0 + 1.0
+                         (y11, (fun yb12 -> yb12 * 1.0))
+                     let rev13 = snd fwd14
+                     let y8 = fst fwd14
+                     (y8, (fun y8b10 -> 
+                                let w0b2 = 0.0 
+                                let x1b1 = 0.0 
+                                let dxs15 = rev13 y8b10 
+                                let w0b2 = w0b2 + dxs15 
+                                let dxs7 = rev5 w0b2 
+                                let x1b1 = x1b1 + dxs7 
+                                x1b1))) @>
+
+          let r,rd = (q.Eval()) 4.0
+          test "vrknlwerwe90" (r = 17.0)
+          test "cew90jkml0rv" (rd 0.1 = 0.8)
+
+    [<Test>]
+    member this.FunkyMethodRepresentations() = 
+        // The IsSome and IsNone properties are represented as static methods because
+        // option uses 'null' as a representation
+        checkEval "clkedw0" (<@ let x : int option = None in x.IsSome @>) false
+        checkEval "clkedw1" (<@ let x : int option = None in x.IsNone @>) true
+        checkEval "clkedw2" (<@ let x : int option = Some 1 in x.Value @>) 1
+        //checkEval "clkedw3" (<@ let x : int option = Some 1 in x.ToString() @> |> eval  ) "Some(1)"
+
+    [<Test>]
+    member this.Extensions() = 
+
+        let v = new obj()
+        checkEval "ecnowe0" (<@ v.ExtensionMethod0() @>)  3
+        checkEval "ecnowe1" (<@ v.ExtensionMethod1() @>)  ()
+        checkEval "ecnowe2" (<@ v.ExtensionMethod2(3) @>) 3
+        checkEval "ecnowe3" (<@ v.ExtensionMethod3(3) @>)  ()
+        checkEval "ecnowe4" (<@ v.ExtensionMethod4(3,4) @>)  7
+        checkEval "ecnowe5" (<@ v.ExtensionMethod5(3,4) @>)  (3,4)
+        checkEval "ecnowe6" (<@ v.ExtensionProperty1 @>) 3
+        checkEval "ecnowe7" (<@ v.ExtensionProperty2 @>) 3
+        checkEval "ecnowe8" (<@ v.ExtensionProperty3 <- 4 @>)  ()
+        checkEval "ecnowe9" (<@ v.ExtensionIndexer1(3) @>) 3
+        checkEval "ecnowea" (<@ v.ExtensionIndexer2(3) <- 4 @>)  ()
+
+        check "ecnoweb" (eval (<@ v.ExtensionMethod0 @>) ()) 3 
+        check "ecnowec" (eval (<@ v.ExtensionMethod1 @>) ()) ()
+        check "ecnowed" (eval (<@ v.ExtensionMethod2 @>) 3) 3
+        check "ecnowee" (eval (<@ v.ExtensionMethod3 @>) 3) ()
+        check "ecnowef" (eval (<@ v.ExtensionMethod4 @>) (3,4)) 7
+        check "ecnoweg" (eval (<@ v.ExtensionMethod5 @>) (3,4)) (3,4)
+
+        let v2 = 3
+        let mutable v2b = 3
+        checkEval "ecnweh0" (<@ v2.ExtensionMethod0() @>) 3
+        checkEval "ecnweh1" (<@ v2.ExtensionMethod1() @>) ()
+        checkEval "ecnweh2" (<@ v2.ExtensionMethod2(3) @>) 3
+        checkEval "ecnweh3" (<@ v2.ExtensionMethod3(3) @>) ()
+        checkEval "ecnweh4" (<@ v2.ExtensionMethod4(3,4) @>) 7
+        checkEval "ecnweh5" (<@ v2.ExtensionMethod5(3,4) @>) (3,4)
+        checkEval "ecnweh6" (<@ v2.ExtensionProperty1 @>) 3
+        checkEval "ecnweh7" (<@ v2.ExtensionProperty2 @>) 3
+        checkEval "ecnweh8" (<@ v2b.ExtensionProperty3 <- 4 @>)  ()
+        checkEval "ecnweh9" (<@ v2.ExtensionIndexer1(3) @>) 3
+        checkEval "ecnweha" (<@ v2b.ExtensionIndexer2(3) <- 4 @>)  ()
+[<TestFixture>]
+type QuotationOfComparisonTest() =
+    let testComparisonOnEqualValues v1 =
+        <@ v1 = v1 @>.Eval() |> Assert.IsTrue
+        <@ v1 <> v1 @>.Eval() |> Assert.IsFalse
+        <@ v1 < v1 @>.Eval() |> Assert.IsFalse
+        <@ v1 > v1 @>.Eval() |> Assert.IsFalse
+        <@ v1 <= v1 @>.Eval() |> Assert.IsTrue
+        <@ v1 >= v1 @>.Eval() |> Assert.IsTrue
+
+    let testComparisonOnOrderedValues v1 v2 =
+        <@ v1 = v2 @>.Eval() |> Assert.IsFalse
+        <@ v1 <> v2 @>.Eval() |> Assert.IsTrue
+        <@ v1 < v2 @>.Eval() |> Assert.IsTrue
+        <@ v1 > v2 @>.Eval() |> Assert.IsFalse
+        <@ v1 <= v2 @>.Eval() |> Assert.IsTrue
+        <@ v1 >= v2 @>.Eval() |> Assert.IsFalse
+
+    
+    [<Test>]
+    member this.TestRecordEquality() =
+        let value1 = { field1 = 1; field2 = 1; }
+        testComparisonOnEqualValues value1
+
+    [<Test>]
+    member this.TestRecordInequality() =
+        let value1 = { field1 = 1; field2 = 1; }
+        let value2 = { field1 = 1; field2 = 2; }
+        testComparisonOnOrderedValues value1 value2
+
+    [<Test>]
+    member this.TestStringEquality() =
+        let value1 = "ABC"
+        testComparisonOnEqualValues value1
+
+    [<Test>]
+    member this.TestStringInequality() =
+        let value1 = "ABC"
+        let value2 = "ABD"
+        testComparisonOnOrderedValues value1 value2
+
+    [<Test>]
+    member this.TestValueTypeEquality() =
+        let value1 = 1
+        testComparisonOnEqualValues value1
+
+    [<Test>]
+    member this.TestValueTypeInequality() =
+        let value1 = 1
+        let value2 = 2
+        testComparisonOnOrderedValues value1 value2
+
+    [<Test>]
+    member this.TestUnionEquality() =
+        let value1 = Union1111.Case1 "ABC"
+        testComparisonOnEqualValues value1
+
+    [<Test>]
+    member this.TestUnionInequality() =
+        let value1 = Union1111.Case1 "ABC"
+        let value2 = Union1111.Case1 "XYZ"
+        testComparisonOnOrderedValues value1 value2
+
+
+module QuotationCompilation =
+    let eval (q: Expr<_>) = 
+        q.ToLinqExpression() |> ignore 
+        q.Compile() |> ignore  
+        q.Eval()
+        
+    // This tried to use non-existent 'Action' delegate with 5 type arguments
+    let q =
+        <@  (fun () -> 
+                let a = ref 0
+                let b = 0
+                let c = 0
+                let d = 0
+                let e = 0
+                a := b + c + d + e ) @>
+    check "qceva0" ((eval q) ()) ()
+
+
+
+
+    
+module IQueryableTests =
+    
+    type Customer = { mutable Name:string; Data: int; Cost:float; Sizes: int list }
+    let c1 = { Name="Don"; Data=6; Cost=6.2; Sizes=[1;2;3;4] }
+    let c2 = { Name="Peter"; Data=7; Cost=4.2; Sizes=[10;20;30;40] }
+    let c3 = { Name="Freddy"; Data=8; Cost=9.2; Sizes=[11;12;13;14] }
+    let c4 = { Name="Freddi"; Data=8; Cost=1.0; Sizes=[21;22;23;24] }
+    
+    let data = [c1;c2;c3;c4]
+    let db = System.Linq.Queryable.AsQueryable<Customer>(data |> List.toSeq)
+
+    printfn "db = %A" (Reflection.FSharpType.GetRecordFields (typeof<Customer>, System.Reflection.BindingFlags.Public ||| System.Reflection.BindingFlags.NonPublic))
+    let q1 = <@ seq { for i in db -> i.Name } @>
+    let q2 = <@ c1.Name @>
+    printfn "q2 = %A" q2
+    
+    printfn "db = %A" db.Expression
+
+    let checkCommuteSeq s q =
+        check s (query q |> Seq.toList) (q.Eval() |> Seq.toList)
+
+    let checkCommuteVal s q =
+        check s (query q) (q.Eval())
+
+    let q = <@ System.DateTime.Now - System.DateTime.Now @>
+    q.Eval() |> ignore
+    
+    checkCommuteSeq "cnewnc01" <@ db @>
+    //debug <- true
+    checkCommuteSeq "cnewnc02" <@ seq { for i in db -> i }  @>
+    checkCommuteSeq "cnewnc03" <@ seq { for i in db -> i.Name }  @>
+    checkCommuteSeq "cnewnc04" <@ [ for i in db -> i.Name ]  @>
+    checkCommuteSeq "cnewnc05" <@ [ for i in db do yield i.Name ]  @>
+    checkCommuteSeq "cnewnc06" <@ [ for i in db do 
+                                      for j in db do 
+                                          yield (i.Name,j.Name) ] @>
+
+    checkCommuteSeq "cnewnc07" <@ [ for i in db do 
+                                      for j in db do 
+                                          if i.Data = j.Data then 
+                                              yield (i.Data,i.Name,j.Name) ] @>
+
+    checkCommuteSeq "cnewnc08"  <@ [ for i in db do 
+                                      if i.Data = 8 then 
+                                          for j in db do 
+                                              if i.Data = j.Data then 
+                                                  yield (i.Data,i.Name,j.Name) ] @>
+
+    checkCommuteSeq "cnewnc08"  <@ [ for i in db do 
+                                      match i.Data with 
+                                      | 8 -> 
+                                          for j in db do 
+                                              if i.Data = j.Data then 
+                                                  yield (i.Data,i.Name,j.Name) 
+                                      | _ -> 
+                                          () ] @>
+
+
+
+    // EXPECT PASS
+    checkCommuteSeq "cnewnc08"  <@  seq { for i in db do for j in db do yield (i.Data) }  @>
+    checkCommuteSeq "cnewnc08"  <@  db |> Seq.take 3 @>
+    checkCommuteVal "cnewnc08"  <@  db |> Seq.take 3 |> Seq.length @>
+    checkCommuteVal "cnewnc08"  <@  Seq.length (seq { for i in db do for j in db do yield (i.Data) })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.length (seq { for i in db do for j in db do yield (i.Data) })   @> 
+    checkCommuteVal "cnewnc08"  <@  (seq { for i in db do for j in db do yield (i.Data) })  |> Seq.length  @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.max (seq { for i in db do for j in db do yield (i.Data) })   @> 
+    checkCommuteVal "cnewnc08"  <@  seq { for i in db do for j in db do yield (i.Data) } |> Seq.max   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.min (seq { for i in db do for j in db do yield (i.Data) })   @> 
+    checkCommuteVal "cnewnc08"  <@  seq { for i in db do for j in db do yield (i.Data) } |> Seq.min  @> 
+    checkCommuteSeq "cnewnc08"  <@ Seq.distinct (seq { for i in db do for j in db do yield i }) @>
+    checkCommuteSeq "cnewnc08"  <@ seq { for i in db do for j in db do yield i } |> Seq.distinct @>
+    checkCommuteVal "cnewnc08"  <@  Seq.max (seq { for i in db do for j in db do yield float i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.max (seq { for i in db do for j in db do yield float32 i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.max (seq { for i in db do for j in db do yield decimal i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.min (seq { for i in db do for j in db do yield float i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.min (seq { for i in db do for j in db do yield float32 i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.min (seq { for i in db do for j in db do yield decimal i.Data })   @> 
+    checkCommuteVal "cnewnc08"  <@  Seq.average (seq { for i in db do for j in db do yield i.Cost })   @> 
+    checkCommuteVal "cnewnc08"  <@   (seq { for i in db do for j in db do yield i.Cost })  |> Seq.average @> 
+
+    checkCommuteSeq "cnewnc08"  (<@ Microsoft.FSharp.Linq.Query.groupBy
+                                        (fun x -> x) 
+                                        (seq { for i in db do yield i.Data })  |> Seq.map Seq.toList |> Seq.toList @> ) 
+
+
+    checkCommuteSeq "cnewnc08"  (<@ Microsoft.FSharp.Linq.Query.join 
+                                        (seq { for i in db do yield i.Data }) 
+                                        (seq { for i in db do yield i.Data })  
+                                        (fun x -> x) 
+                                        (fun x -> x) 
+                                        (fun x y -> x + y) @> ) 
+
+    checkCommuteSeq "cnewnc08"  (<@ Microsoft.FSharp.Linq.Query.groupJoin 
+                                        (seq { for i in db do yield i.Data }) 
+                                        (seq { for i in db do yield i.Data }) 
+                                        (fun x -> x) 
+                                        (fun x -> x) 
+                                        (fun x y -> x + Seq.length y)  @> ) 
+
+    check "cnewnc08"  (query <@  Seq.average (seq { for i in db do for j in db do yield (i.Cost) })   @>  - 5.15 <= 0.0000001) true
+
+    // By design: no 'distinctBy', "maxBy", "minBy", "groupBy" support in queries
+    check "lcvkneio" (try let _ = query <@ Seq.distinctBy (fun x -> x) (seq { for i in db do for j in db do yield i })  @> in  false with _ -> true) true
+    check "lcvkneio" (try let _ = query <@ Seq.maxBy (fun x -> x) (seq { for i in db do for j in db do yield i })  @> in  false with _ -> true) true
+    check "lcvkneio" (try let _ = query <@ Seq.minBy (fun x -> x) (seq { for i in db do for j in db do yield i })  @> in  false with _ -> true) true
+    check "lcvkneio" (try let _ = query <@ Seq.groupBy (fun x -> x) (seq { for i in db do for j in db do yield i })  @> in  false with _ -> true) true
+
+module CheckedTests = 
+    open Microsoft.FSharp.Core.Operators.Checked
+          
+    [<TestFixture>]
+    type public QuotationEvalCheckedTests() =
+      
+        [<Test>]
+        member this.FloatCheckedTests() = 
+
+         // set up bindings
+         let x1 = <@ 2.0<kg> + 4.0<kg>  @> |> eval
+         let x2 = <@ 2.0<s> - 4.0<s>  @> |> eval
+         let x3 = <@ 2.0<m> / 4.0<s>  @> |> eval
+         let x3a = <@ 2.0<m> / 4.0<m>  @> |> eval
+         let x3b = <@ 1.0 / 4.0<s>  @> |> eval
+         let x3c = <@ 1.0<m> / 4.0  @> |> eval
+         let x4 = <@ 2.0<m> * 4.0<s>  @> |> eval
+         let x4a = <@ 2.0<m> * 4.0<m>  @> |> eval
+         let x4b = <@ 2.0 * 4.0<m>  @> |> eval
+         let x4c = <@ 2.0<m> * 4.0  @> |> eval
+         let x5 = <@ 5.0<m> % 3.0<m>  @> |> eval
+         let x6 = <@ - (2.0<m>)  @> |> eval
+         let x7 = <@ abs (-2.0<m>)  @> |> eval
+         let x8 = <@ sqrt (4.0<sqrm>)  @> |> eval
+         let x9 = <@ [ 1.0<m> .. 1.0<m> .. 4.0<m> ]  @> |> eval
+         let x10 = <@ sign (3.0<m/s>)  @> |> eval
+         let x11 = <@ atan2 4.4<s^3> 5.4<s^3>  @> |> eval
+         let x12 = <@ Seq.sum [2.0<sqrm>; 3.0<m^2>]  @> |> eval
+         let x12a = <@ Seq.sumBy (fun x -> x*x) [(2.0<sqrm> : area); 3.0<m^2>]  @> |> eval
+         let x13 = <@ (Seq.average [2.0<sqrm>; 3.0<m^2>]) : area  @> |> eval
+         let x13a = <@ Seq.averageBy (fun x -> x*x) [2.0<m^2/m>; 3.0<m>]  @> |> eval
+         let x14 = <@ x13 + x13a  @> |> eval
+
+         // check the types and values!
+         test "x1" (x1 = 6.0<kg>)
+         test "x2" (x2 = -2.0<s>)
+         test "x3" (x3 = 0.5<m/s>)
+         test "x3a" (x3a = 0.5)
+         test "x3b" (x3b = 0.25<1/s>)
+         test "x3c" (x3c = 0.25<m>)
+         test "x4" (x4 = 8.0<m s>)
+         test "x4a" (x4a = 8.0<m^2>)
+         test "x4b" (x4b = 8.0<m>)
+         test "x4c" (x4c = 8.0<m>)
+         test "x5" (x5 = 2.0<m>)
+         test "x6" (x6 = -2.0<m>)
+         test "x7" (x7 = 2.0<m>)
+         test "x8" (x8 = 2.0<m>)
+         test "x9" (x9 = [1.0<m>; 2.0<m>; 3.0<m>; 4.0<m>])
+         test "x10" (x10 = 1)
+         test "x12" (x12 = 5.0<m^2>)
+         test "x12a" (x12a = 13.0<m^4>)
+         test "x13" (x13 = 2.5<m^2>)
+         test "x13a" (x13a = 6.5<m^2>)
+          
+
+        [<Test>]
+        member this.Float32CheckedTests() = 
+
+
+         let y1 = <@ 2.0f<kg> + 4.0f<kg>  @> |> eval
+         let y2 = <@ 2.0f<s> - 4.0f<s>  @> |> eval
+         let y3 = <@ 2.0f<m> / 4.0f<s>  @> |> eval
+         let y3a = <@ 2.0f<m> / 4.0f<m>  @> |> eval
+         let y3b = <@ 1.0f / 4.0f<s>  @> |> eval
+         let y3c = <@ 1.0f<m> / 4.0f  @> |> eval
+         let y4 = <@ 2.0f<m> * 4.0f<s>  @> |> eval
+         let y4a = <@ 2.0f<m> * 4.0f<m>  @> |> eval
+         let y4b = <@ 2.0f * 4.0f<m>  @> |> eval
+         let y4c = <@ 2.0f<m> * 4.0f  @> |> eval
+         let y5 = <@ 5.0f<m> % 3.0f<m>  @> |> eval
+         let y6 = <@ - (2.0f<m>)  @> |> eval
+         let y7 = <@ abs (2.0f<m>)  @> |> eval
+         let y8 = <@ sqrt (4.0f<sqrm>)  @> |> eval
+         let y9 = <@ [ 1.0f<m> .. 1.0f<m> .. 4.0f<m> ]  @> |> eval
+         let y10 = <@ sign (3.0f<m/s>)  @> |> eval
+         let y11 = <@ atan2 4.4f<s^3> 5.4f<s^3>  @> |> eval
+         let y12 = <@ Seq.sum [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+         let y12a = <@ Seq.sumBy (fun y -> y*y) [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+         let y13 = <@ Seq.average [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+         let y13a = <@ Seq.averageBy (fun y -> y*y) [2.0f<sqrm>; 3.0f<m^2>]  @> |> eval
+
+         // check the types and values!
+         test "y1" (y1 = 6.0f<kg>)
+         test "y2" (y2 = -2.0f<s>)
+         test "y3" (y3 = 0.5f<m/s>)
+         test "y3a" (y3a = 0.5f)
+         test "y3b" (y3b = 0.25f<1/s>)
+         test "y3c" (y3c = 0.25f<m>)
+         test "y4" (y4 = 8.0f<m s>)
+         test "y4a" (y4a = 8.0f<m^2>)
+         test "y4b" (y4b = 8.0f<m>)
+         test "y4c" (y4c = 8.0f<m>)
+         test "y5" (y5 = 2.0f<m>)
+         test "y6" (y6 = -2.0f<m>)
+         test "y7" (y7 = 2.0f<m>)
+         test "y8" (y8 = 2.0f<m>)
+         test "y9" (y9 = [1.0f<m>; 2.0f<m>; 3.0f<m>; 4.0f<m>])
+         test "y10" (y10 = 1)
+         test "y12" (y12 = 5.0f<m^2>)
+         test "y12a" (y12a = 13.0f<m^4>)
+         test "y13" (y13 = 2.5f<m^2>)
+         test "y13a" (y13a = 6.5f<m^4>)
+          
+
+        [<Test>]
+        member this.DecimalCheckedTests() = 
+
+         let z1 = <@ 2.0M<kg> + 4.0M<kg>  @> |> eval
+         let z2 = <@ 2.0M<s> - 4.0M<s>  @> |> eval
+         let z3 = <@ 2.0M<m> / 4.0M<s>  @> |> eval
+         let z3a = <@ 2.0M<m> / 4.0M<m>  @> |> eval
+         let z3b = <@ 1.0M / 4.0M<s>  @> |> eval
+         let z3c = <@ 1.0M<m> / 4.0M  @> |> eval
+         let z4 = <@ 2.0M<m> * 4.0M<s>  @> |> eval
+         let z4a = <@ 2.0M<m> * 4.0M<m>  @> |> eval
+         let z4b = <@ 2.0M * 4.0M<m>  @> |> eval
+         let z4c = <@ 2.0M<m> * 4.0M  @> |> eval
+         let z5 = <@ 5.0M<m> % 3.0M<m>  @> |> eval
+         let z6 = <@ - (2.0M<m>)  @> |> eval
+         let z7 = <@ abs (2.0M<m>)  @> |> eval
+        // let z9 = <@ [ 1.0M<m> .. 4.0M<m> ]
+         let z10 = <@ sign (3.0M<m/s>)  @> |> eval
+
+
+         // check the types and values!
+         test "z1" (z1 = 6.0M<kg>)
+         test "z2" (z2 = -2.0M<s>)
+         test "z3" (z3 = 0.5M<m/s>)
+         test "z3a" (z3a = 0.5M)
+         test "z3b" (z3b = 0.25M<1/s>)
+         test "z3c" (z3c = 0.25M<m>)
+         test "z4" (z4 = 8.0M<m s>)
+         test "z4a" (z4a = 8.0M<m^2>)
+         test "z4b" (z4b = 8.0M<m>)
+         test "z4c" (z4c = 8.0M<m>)
+         test "z5" (z5 = 2.0M<m>)
+         test "z6" (z6 = -2.0M<m>)
+         test "z7" (z7 = 2.0M<m>)
+         test "z10" (z10 = 1)
+          
+ 
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/SetMapTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/SetMapTests.fs
new file mode 100644
index 0000000..b1affdf
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/SetMapTests.fs
@@ -0,0 +1,245 @@
+namespace FSharp.PowerPack.Unittests
+
+open NUnit.Framework
+open System.Collections.Generic
+
+#nowarn "40"
+
+type ComparerA() = 
+  interface IComparer<int> with
+     override __.Compare(x,y) = compare (unbox<int> x) (unbox<int> y)
+
+type ComparerB() = 
+  interface IComparer<int> with
+     override __.Compare(x,y) = compare (unbox<int> y) (unbox<int> x)
+
+[<TestFixture>]
+type public MapFunctorTests() =
+  
+    let Z5Map = Map.Make(fun (x:int) (y:int) -> compare (x mod 5) (y mod 5))
+    let z5MapEqRange n m x = 
+
+      for i = n to m do 
+        test "ew9wef" ((Z5Map.find i x / 100) mod 5 = i mod 5);
+      done;
+      for i = n to m do 
+        test "ew9wef" (match Z5Map.tryfind i x with Some n -> (n/100) % 5 = i % 5 | None -> failwith "test failed");
+      done
+
+
+    [<Test>]
+    member this.BasicTests_z5test39342() = 
+          let x = Z5Map.empty 
+          let x = Z5Map.add 1 100 x
+          let x = Z5Map.add 2 200 x
+          let x = Z5Map.add 3 300 x
+          let x = Z5Map.add 4 400 x
+          let x = Z5Map.add 5 500 x
+          let x = Z5Map.add 6 600 x
+          let x = Z5Map.add 7 700 x
+          let x = Z5Map.add 8 800 x
+          let x = Z5Map.add 9 900 x
+          let x = Z5Map.add 10 1000 x
+          let x = Z5Map.add 11 1100 x
+          let x = Z5Map.add 12 1200 x
+          let x = Z5Map.add 13 1300 x
+          let x = Z5Map.add 14 1400 x
+          let x = Z5Map.add 15 1500 x
+          z5MapEqRange 1 15 x 
+
+    [<Test>]
+    member this.BasicTests_z5test39343() = 
+          let x = Z5Map.empty 
+          let x = Z5Map.add 15 1500 x
+          let x = Z5Map.add 14 1400 x
+          let x = Z5Map.add 13 1300 x
+          let x = Z5Map.add 12 1200 x
+          let x = Z5Map.add 11 1100 x
+          let x = Z5Map.add 10 1000 x
+          let x = Z5Map.add 9 900 x
+          let x = Z5Map.add 8 800 x
+          let x = Z5Map.add 7 700 x
+          let x = Z5Map.add 6 600 x
+          let x = Z5Map.add 5 500 x
+          let x = Z5Map.add 4 400 x
+          let x = Z5Map.add 3 300 x
+          let x = Z5Map.add 2 200 x
+          let x = Z5Map.add 1 100 x
+          z5MapEqRange 1 15 x 
+
+    [<Test>]
+    member this.BasicTests_z5test39344() = 
+          let x = Z5Map.empty 
+          let x = Z5Map.add 4 400 x
+          z5MapEqRange 4 4 x 
+
+
+    [<Test>]
+    member this.BasicTests_z5test39345() = 
+        let x = Z5Map.empty 
+        let x = Z5Map.add 4 400 x
+        let x = Z5Map.add 4 400 x
+        z5MapEqRange 4 4 x 
+
+
+    [<Test>]
+    member this.BasicTests_z5test39346() = 
+        let x = Z5Map.empty 
+        let x = Z5Map.add 4 400 x
+        let x = Z5Map.remove 4 x
+        z5MapEqRange 4 3 x 
+
+
+    [<Test>]
+    member this.BasicTests_z5test39347() = 
+        let x = Z5Map.empty 
+        let x = Z5Map.add 1 100 x
+        let x = Z5Map.add 2 200 x
+        let x = Z5Map.add 3 300 x
+        let x = Z5Map.add 4 400 x
+        let x = Z5Map.add 5 500 x
+        let x = Z5Map.remove 0 x
+        let x = Z5Map.remove 2 x
+        let x = Z5Map.remove 1 x
+        z5MapEqRange 3 4 x 
+
+    [<Test>]
+    member this.BasicTests_Comparer() = 
+        check "4i4cnio1" (Z5Map.empty.Comparer.Compare (2,7)) 0
+        check "4i4cnio2" (Z5Map.empty.Comparer.Compare (2,3)) -1
+        check "4i4cnio3" (Z5Map.empty.Comparer.Compare (2,8)) -1
+        check "4i4cnio4" (Z5Map.empty.Comparer.Compare (3,2)) 1
+        check "4i4cnio5" (Z5Map.empty.Comparer.Compare (8,2)) 1
+
+    [<Test>]
+    member this.Repro4884() = 
+        (* #r "FSharp.PowerPack" *)
+        let m0 = Tagged.Map<int,int,Comparer<int>>.Empty(Comparer.Default)
+        let m1 = Tagged.Map<int,int,Comparer<int>>.Empty(Comparer.Default)
+        let mres = m0 > m1
+        do check "set of sets comparison" false mres
+
+type intSet = int Tagged.Set
+type intSetSet = intSet Tagged.Set
+
+[<TestFixture>]
+type public SetFunctorTests() =
+  
+    let Z3Set = Set.Make(fun (x:int) (y:int) -> compare (x mod 3) (y mod 3))
+
+    [<Test>]
+    member this.BasicTests1() = 
+
+        do check "set comparison" 0 (Z3Set.compare Z3Set.empty Z3Set.empty)
+        do check "set comparison" 0   (Z3Set.compare (Z3Set.add 1 Z3Set.empty) (Z3Set.add 1 Z3Set.empty))
+        do check "set comparison" 0   (Z3Set.compare (Z3Set.add 3 Z3Set.empty) (Z3Set.add 0 Z3Set.empty))
+        do check "set comparison" 0   (Z3Set.compare (Z3Set.add 1 (Z3Set.add 2 Z3Set.empty)) (Z3Set.add 2 (Z3Set.add 1 Z3Set.empty)))
+        do check "set comparison" 0   (Z3Set.compare (Z3Set.add 1 (Z3Set.add 2 (Z3Set.add 3 Z3Set.empty))) (Z3Set.add 3 (Z3Set.add 2 (Z3Set.add 1 Z3Set.empty))))
+        do check "set comparison" 0   (Z3Set.compare (Z3Set.add 1 (Z3Set.add 2 (Z3Set.add 0 Z3Set.empty))) (Z3Set.add 3 (Z3Set.add 2 (Z3Set.add 1 Z3Set.empty))))
+           
+           
+        do check "set comparison" false (0 = Z3Set.compare Z3Set.empty (Z3Set.add 1 Z3Set.empty))
+        do check "set comparison" false  (0 = Z3Set.compare (Z3Set.add 1 Z3Set.empty) (Z3Set.add 2 Z3Set.empty))
+        do check "set comparison" false  (0 = Z3Set.compare (Z3Set.add 0 (Z3Set.add 1 Z3Set.empty)) (Z3Set.add 2 (Z3Set.add 1 Z3Set.empty)))
+        do check "set comparison" false  (0 = Z3Set.compare (Z3Set.add 1 (Z3Set.add 0 (Z3Set.add 1 Z3Set.empty))) (Z3Set.add 5 (Z3Set.add 4 (Z3Set.add 3 Z3Set.empty))))
+
+
+        let Z3SetSet = Set.Make(Z3Set.compare)
+
+        let one = Z3Set.add 0 Z3Set.empty
+        let two = Z3Set.add 1 one
+        let three = Z3Set.add 2 two
+
+        do check "set of sets comparison" 0 (Z3SetSet.compare Z3SetSet.empty Z3SetSet.empty)
+        do check "set of sets comparison" 0   (Z3SetSet.compare (Z3SetSet.add one Z3SetSet.empty) (Z3SetSet.add one Z3SetSet.empty))
+        do check "set of sets comparison" 0   (Z3SetSet.compare (Z3SetSet.add one (Z3SetSet.add two Z3SetSet.empty)) (Z3SetSet.add two (Z3SetSet.add one Z3SetSet.empty)))
+        do check "set of sets comparison" 0   (Z3SetSet.compare (Z3SetSet.add one (Z3SetSet.add two (Z3SetSet.add three Z3SetSet.empty))) (Z3SetSet.add three (Z3SetSet.add two (Z3SetSet.add one Z3SetSet.empty))))
+           
+        do check "set of sets comparison" false (0 = Z3SetSet.compare Z3SetSet.empty (Z3SetSet.add one Z3SetSet.empty))
+        do check "set of sets comparison" false  (0 = Z3SetSet.compare (Z3SetSet.add one Z3SetSet.empty) (Z3SetSet.add two Z3SetSet.empty))
+        do check "set of sets comparison" false  (0 = Z3SetSet.compare (Z3SetSet.add one (Z3SetSet.add two Z3SetSet.empty)) (Z3SetSet.add three (Z3SetSet.add one Z3SetSet.empty)))
+
+        let checkReflexive f x y = (f x y = - f y x)
+        do check "set of sets comparison" true (checkReflexive Z3SetSet.compare Z3SetSet.empty (Z3SetSet.add one Z3SetSet.empty))
+        do check "set of sets comparison" true (checkReflexive Z3SetSet.compare (Z3SetSet.add one Z3SetSet.empty) (Z3SetSet.add two Z3SetSet.empty))
+        do check "set of sets comparison" true (checkReflexive Z3SetSet.compare (Z3SetSet.add one (Z3SetSet.add two Z3SetSet.empty)) (Z3SetSet.add three (Z3SetSet.add one Z3SetSet.empty)))
+
+    member this.BasicTests_Comparer() = 
+        check "4i4cnio1" (Z3Set.empty.Comparer.Compare (2,5)) 0
+        check "4i4cnio2" (Z3Set.empty.Comparer.Compare (0,1)) -1
+        check "4i4cnio3" (Z3Set.empty.Comparer.Compare (0,4)) -1
+        check "4i4cnio4" (Z3Set.empty.Comparer.Compare (1,0)) 1
+        check "4i4cnio5" (Z3Set.empty.Comparer.Compare (4,0)) 1
+
+    [<Test>]
+    member this.Repro4884() = 
+        let s0 = Tagged.Set<int,Comparer<int>>.Empty(Comparer.Default)
+        let s1 = Tagged.Set<int,Comparer<int>>.Empty(Comparer.Default)
+        let sres = s0 > s1
+        do  System.Console.WriteLine("Regression 4884")
+        do check "set of sets comparison" false sres
+
+
+    [<Test>]
+    // Bug 4883: TaggedCollections should override Equals()
+    member this.Repro4883() = 
+        let compA = ComparerA()
+        let nA1  = Tagged.Map<int,int,ComparerA>.Empty(compA)
+        let nA2  = Tagged.Map<int,int,ComparerA>.Empty(compA)
+             
+        let mA1  = Tagged.Map<int,int,ComparerA>.Empty(ComparerA())
+        let mA2  = Tagged.Map<int,int,ComparerA>.Empty(ComparerA())
+        let mA1x = mA1.Add(1,1)
+        let mA2x = mA2.Add(1,1)
+        let mB1  = Tagged.Map<int,int,ComparerB>.Empty(ComparerB())
+        let mB2  = Tagged.Map<int,int,ComparerB>.Empty(ComparerB())
+        let mB1x = mB1.Add(1,1)
+        let mB2x = mB2.Add(1,1)
+
+        (*let check str x y = if x=y then printf "-OK-: %s\n" str else printf "FAIL: %s\n" str*)
+             
+        do  check "Bug4883.map.A1  = A1"   (mA1  = mA1)            true   (* empty     / empty     and identical *)
+        do  check "Bug4883.map.A1  = A2"   (mA1  = mA2)            true   (* empty     / empty     and non-identical *)
+        do  check "Bug4883.map.A1  = A1x"  (mA1  = mA1x)           false  (* empty     / non-empty *)
+        do  check "Bug4883.map.A1x = A1x"  (mA1x = mA1x)           true   (* non-empty / non-empty and identical *)
+        do  check "Bug4883.map.A1x = A2x"  (mA1x = mA2x)           true   (* non-empty / non-empty and non-identical *)
+
+        do  check "Bug4883.map.A1  eq A1"  (mA1.Equals(box mA1))   true
+        do  check "Bug4883.map.A1  eq A2"  (mA1.Equals(box mA2))   true
+        do  check "Bug4883.map.A1  eq A1x" (mA1.Equals(box mA1x))  false
+        do  check "Bug4883.map.A1x eq A1x" (mA1x.Equals(box mA1x)) true
+        do  check "Bug4883.map.A1x eq A2x" (mA1x.Equals(box mA2x)) true
+
+        do  check "Bug4883.map.A1  eq B1"  (mA1.Equals(box mB1))   false  (* empty     / empty     and different comparers *)
+        do  check "Bug4883.map.A1  eq B1x" (mA1.Equals(box mB1))   false  (* empty     / non-empty and different comparers *)
+        do  check "Bug4883.map.A1x eq B1x" (mA1x.Equals(box mB1))  false  (* non-empty / empty     and different comparers *)
+        do  check "Bug4883.map.A1x eq B1x" (mA1x.Equals(box mB1x)) false  (* non-empty / non-empty and different comparers *)
+
+        let sA1  = Tagged.Set<int,ComparerA>.Empty(ComparerA())
+        let sA2  = Tagged.Set<int,ComparerA>.Empty(ComparerA())
+        let sA1x = sA1.Add(1)
+        let sA2x = sA2.Add(1)
+        let sB1  = Tagged.Set<int,ComparerB>.Empty(ComparerB())
+        let sB2  = Tagged.Set<int,ComparerB>.Empty(ComparerB())
+        let sB1x = sB1.Add(1)
+        let sB2x = sB2.Add(1)       
+
+        do  check "Bug4883.map.A1  = A1"   (sA1  = sA1)            true   (* empty     / empty     and identical *)
+        do  check "Bug4883.map.A1  = A2"   (sA1  = sA2)            true   (* empty     / empty     and non-identical *)
+        do  check "Bug4883.map.A1  = A1x"  (sA1  = sA1x)           false  (* empty     / non-empty *)
+        do  check "Bug4883.map.A1x = A1x"  (sA1x = sA1x)           true   (* non-empty / non-empty and identical *)
+        do  check "Bug4883.map.A1x = A2x"  (sA1x = sA2x)           true   (* non-empty / non-empty and non-identical *)
+
+        do  check "Bug4883.map.A1  eq A1"  (sA1.Equals(box sA1))   true
+        do  check "Bug4883.map.A1  eq A2"  (sA1.Equals(box sA2))   true
+        do  check "Bug4883.map.A1  eq A1x" (sA1.Equals(box sA1x))  false
+        do  check "Bug4883.map.A1x eq A1x" (sA1x.Equals(box sA1x)) true
+        do  check "Bug4883.map.A1x eq A2x" (sA1x.Equals(box sA2x)) true
+
+        do  check "Bug4883.map.A1  eq B1"  (sA1.Equals(box sB1))   false  (* empty     / empty     and different comparers *)
+        do  check "Bug4883.map.A1  eq B1x" (sA1.Equals(box sB1))   false  (* empty     / non-empty and different comparers *)
+        do  check "Bug4883.map.A1x eq B1x" (sA1x.Equals(box sB1))  false  (* non-empty / empty     and different comparers *)
+        do  check "Bug4883.map.A1x eq B1x" (sA1x.Equals(box sB1x)) false  (* non-empty / non-empty and different comparers *)
+
+        do  System.Console.WriteLine("Regression 4883")
+
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/StructuredFormatTests.fs b/workyard/linq/FSharp.PowerPack.Unittests/StructuredFormatTests.fs
new file mode 100644
index 0000000..e21a751
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/StructuredFormatTests.fs
@@ -0,0 +1,11 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open Microsoft.FSharp.Quotations
+open Microsoft.FSharp.Linq.QuotationEvaluation
+open Microsoft.FSharp.Text.StructuredFormat
+
+module StructuredFormat_MiscBitsAndPiecesToCompiler = 
+    let opts = { FormatOptions.Default with 
+                   PrintWidth=30; 
+                   ShowIEnumerable=true;
+                   ShowProperties=true }
diff --git a/workyard/linq/FSharp.PowerPack.Unittests/Utilities.fs b/workyard/linq/FSharp.PowerPack.Unittests/Utilities.fs
new file mode 100644
index 0000000..4e6d559
--- /dev/null
+++ b/workyard/linq/FSharp.PowerPack.Unittests/Utilities.fs
@@ -0,0 +1,129 @@
+namespace FSharp.PowerPack.Unittests
+open NUnit.Framework
+open System
+open System.Collections.Generic
+
+[<AutoOpen>]
+module Utilities = 
+    let test msg b = Assert.IsTrue(b, "MiniTest '" + msg + "'")
+    let logMessage msg = 
+        System.Console.WriteLine("LOG:" + msg)
+//        System.Diagnostics.Trace.WriteLine("LOG:" + msg)
+    let check msg v1 v2 = test msg (v1 = v2)
+    let checkEquals expected actual = 
+      Assert.AreSame(expected, actual) |> ignore
+    let checkContains v items = 
+      items |> Seq.exists ((=) v) |> Assert.IsTrue
+    let reportFailure msg = Assert.Fail msg
+    let numActiveEnumerators = ref 0
+    let throws f = try f() |> ignore; false with e -> true
+
+    let countEnumeratorsAndCheckedDisposedAtMostOnceAtEnd (seq: seq<'a>) =
+       let enumerator() = 
+                 numActiveEnumerators := !numActiveEnumerators + 1;
+                 let disposed = ref false in
+                 let endReached = ref false in
+                 let ie = seq.GetEnumerator() in
+                 { new System.Collections.Generic.IEnumerator<'a> with 
+                      member x.Current =
+                          test "rvlrve0" (not !endReached);
+                          test "rvlrve1" (not !disposed);
+                          ie.Current
+                      member x.Dispose() = 
+                          test "rvlrve2" !endReached;
+                          test "rvlrve4" (not !disposed);
+                          numActiveEnumerators := !numActiveEnumerators - 1;
+                          disposed := true;
+                          ie.Dispose() 
+                   interface System.Collections.IEnumerator with 
+                      member x.MoveNext() = 
+                          test "rvlrve0" (not !endReached);
+                          test "rvlrve3" (not !disposed);
+                          endReached := not (ie.MoveNext());
+                          not !endReached
+                      member x.Current = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          box ie.Current
+                      member x.Reset() = 
+                          ie.Reset()
+                   } in
+
+       { new seq<'a> with 
+             member x.GetEnumerator() =  enumerator() 
+         interface System.Collections.IEnumerable with 
+             member x.GetEnumerator() =  (enumerator() :> _) }
+
+    let countEnumeratorsAndCheckedDisposedAtMostOnce (seq: seq<'a>) =
+       let enumerator() = 
+                 let disposed = ref false in
+                 let endReached = ref false in
+                 let ie = seq.GetEnumerator() in
+                 numActiveEnumerators := !numActiveEnumerators + 1;
+                 { new System.Collections.Generic.IEnumerator<'a> with 
+                      member x.Current =
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          ie.Current
+                      member x.Dispose() = 
+                          test "qrvlrve4" (not !disposed);
+                          numActiveEnumerators := !numActiveEnumerators - 1;
+                          disposed := true;
+                          ie.Dispose() 
+                   interface System.Collections.IEnumerator with 
+                      member x.MoveNext() = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve3" (not !disposed);
+                          endReached := not (ie.MoveNext());
+                          not !endReached
+                      member x.Current = 
+                          test "qrvlrve0" (not !endReached);
+                          test "qrvlrve1" (not !disposed);
+                          box ie.Current
+                      member x.Reset() = 
+                          ie.Reset()
+                   } in
+
+       { new seq<'a> with 
+             member x.GetEnumerator() =  enumerator() 
+         interface System.Collections.IEnumerable with 
+             member x.GetEnumerator() =  (enumerator() :> _) }
+
+    // Verifies two sequences are equal (same length, equiv elements)
+    let verifySeqsEqual seq1 seq2 =
+        if Seq.length seq1 <> Seq.length seq2 then Assert.Fail()
+        
+        let zippedElements = Seq.zip seq1 seq2
+        if zippedElements |> Seq.forall (fun (a, b) -> a = b) 
+        then ()
+        else Assert.Fail()
+        
+    /// Check that the lamda throws an exception of the given type. Otherwise
+    /// calls Assert.Fail()
+    let private checkThrowsExn<'a when 'a :> exn> (f : unit -> unit) =
+        let funcThrowsAsExpected =
+            try
+                let _ = f ()
+                false // Did not throw!
+            with
+            | :? 'a
+                -> true   // Thew null ref, OK
+            | _ -> false  // Did now throw a null ref exception!
+        if funcThrowsAsExpected
+        then ()
+        else Assert.Fail()
+
+    // Illegitimate exceptions. Once we've scrubbed the library, we should add an
+    // attribute to flag these exception's usage as a bug.
+    let checkThrowsNullRefException      f = checkThrowsExn<NullReferenceException>   f
+    let checkThrowsIndexOutRangException f = checkThrowsExn<IndexOutOfRangeException> f
+
+    // Legit exceptions
+    let checkThrowsNotSupportedException f = checkThrowsExn<NotSupportedException>    f
+    let checkThrowsArgumentException     f = checkThrowsExn<ArgumentException>        f
+    let checkThrowsArgumentNullException f = checkThrowsExn<ArgumentNullException>    f
+    let checkThrowsKeyNotFoundException  f = checkThrowsExn<KeyNotFoundException>     f
+    let checkThrowsDivideByZeroException f = checkThrowsExn<DivideByZeroException>    f
+    let checkThrowsInvalidOperationExn   f = checkThrowsExn<InvalidOperationException> f
+
+       
\ No newline at end of file
diff --git a/workyard/linq/FSharpPowerPackSource.Settings.targets b/workyard/linq/FSharpPowerPackSource.Settings.targets
new file mode 100644
index 0000000..5ae1e9e
--- /dev/null
+++ b/workyard/linq/FSharpPowerPackSource.Settings.targets
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <PropertyGroup>
+    <!-- Standard defaults for configuration and platform  -->
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+  </PropertyGroup>
+  <PropertyGroup>
+    <!-- Standard defaults for warning level -->
+    <WarningLevel Condition=" '$(WarningLevel)' == '' ">3</WarningLevel>
+  </PropertyGroup>
+  <!-- Standard interpretations of Debug and Release configurations -->
+  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <DebugType Condition=" '$(DebugType)' == '' ">full</DebugType>
+    <Optimize Condition=" '$(Optimize)' == '' ">false</Optimize>
+    <DefineConstants Condition=" '$(DefineConstants)' == '' ">DEBUG;TRACE</DefineConstants>
+    <ErrorReport Condition=" '$(ErrorReport)' == '' ">prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+    <DebugType Condition=" '$(DebugType)' == '' ">pdbonly</DebugType>
+    <Optimize Condition=" '$(Optimize)' == '' ">true</Optimize>
+    <DefineConstants Condition=" '$(DefineConstants)' == '' ">TRACE</DefineConstants>
+    <ErrorReport Condition=" '$(ErrorReport)' == '' ">prompt</ErrorReport>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/workyard/linq/FSharpPowerPackSource.targets b/workyard/linq/FSharpPowerPackSource.targets
new file mode 100644
index 0000000..c8129db
--- /dev/null
+++ b/workyard/linq/FSharpPowerPackSource.targets
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(TargetFramework)' == 'Silverlight'">
+    <SilverlightVersion Condition="'$(SilverlightVersion)' == ''">v3.0</SilverlightVersion>
+  </PropertyGroup>
+  <PropertyGroup>
+    <LkgVersion>1.9.7.7</LkgVersion>
+    <FsLexUnicode>true</FsLexUnicode>
+    <OutputPath Condition="'$(TargetFramework)' == ''">$(FSharpPowerPackSourcesRoot)\..\$(Configuration)\bin</OutputPath>
+    <OutputPath Condition="'$(TargetFramework)' == 'Silverlight'">$(FSharpPowerPackSourcesRoot)\..\$(TargetFramework)\$(SilverlightVersion)\$(Configuration)\bin</OutputPath>
+    <IntermediateOutputPath Condition="'$(TargetFramework)' == ''">obj\$(Configuration)</IntermediateOutputPath>    
+    <IntermediateOutputPath Condition="'$(TargetFramework)' == 'Silverlight'">obj\$(TargetFramework)\$(SilverlightVersion)\$(Configuration)</IntermediateOutputPath>
+    <FsLexToolPath>$(FSharpPowerPackSourcesRoot)\..\lkg\FSharp.PowerPack-$(LkgVersion)\bin</FsLexToolPath>
+    <FsLexToolExe>fslex.exe</FsLexToolExe>
+    <FsYaccToolPath>$(FSharpPowerPackSourcesRoot)\..\lkg\FSharp.PowerPack-$(LkgVersion)\bin</FsYaccToolPath>
+    <FsYaccToolExe>fsyacc.exe</FsYaccToolExe>
+    
+  </PropertyGroup>
+
+  <!-- Selecting the correct key pair -->
+
+  <PropertyGroup Condition=" '$(TargetFramework)' != 'Silverlight' AND '$(StrongName)' != 'false'">
+    <OtherFlags Condition="Exists('$(FSharpPowerPackSourcesRoot)\fs.snk')">/keyfile:$(FSharpPowerPackSourcesRoot)\fs.snk $(OtherFlags)</OtherFlags>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(TargetFramework)' == 'Silverlight'  ">  
+    <OtherFlags Condition="Exists('$(FSharpPowerPackSourcesRoot)\fsSilverlight.snk') AND '$(StrongName)' != 'false'">/keyfile:$(FSharpPowerPackSourcesRoot)\fsSilverlight.snk $(OtherFlags)</OtherFlags>
+    <DefineConstants>$(DefineConstants);SILVERLIGHT;FX_NO_COMMAND_LINE_ARGS;FX_NO_CULTURE_INFO_ARGS;FX_NO_FILE_OPTIONS;FX_NO_FILESTREAM_ISASYNC;FX_NO_UTF32ENCODING;FX_NO_EXIT;FX_NO_DEFAULT_DEPENDENCY_TYPE;FX_NO_TO_LOWER_INVARIANT;FX_NO_DOUBLE_BIT_CONVERTER;FX_NO_TRUNCATE;FX_NO_ENVIRONMENT;FX_NO_PROCESS_START;FX_NO_PROCESS_DIAGNOSTICS;FX_NO_APP_DOMAINS;FX_NO_DEFAULT_ENCODING;FX_NO_NONBLOCK_IO;FX_NO_BINARY_SERIALIZATION;FX_NO_ASCII_ENCODING;FX_NO_FILEWRITEALL;FX_NO_WINDOWSFORMS;FX_NO_DEFAU [...]
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Reference Condition="'$(TargetFramework)' == ''" Include="FSharp.Core" />
+    <Reference Condition="'$(TargetFramework)' == 'Silverlight' AND '$(SilverlightVersion)' == 'v4.0'" Include="System.Core" />
+    <Reference Condition="'$(TargetFramework)' == 'Silverlight'" Include="$(MSBuildExtensionsPath32)\..\Microsoft F#\Silverlight\Libraries\Client\$(SilverlightVersion)\FSharp.Core.dll"/>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/workyard/linq/assemblyinfo.Common.fs b/workyard/linq/assemblyinfo.Common.fs
new file mode 100644
index 0000000..e9b666a
--- /dev/null
+++ b/workyard/linq/assemblyinfo.Common.fs
@@ -0,0 +1,4 @@
+namespace Microsoft.FSharp
+[<assembly:System.Reflection.AssemblyVersion("2.0.0.1")>]
+[<assembly:System.Reflection.AssemblyFileVersion("2.0.0.1")>]
+do()
diff --git a/workyard/math-provider/lapack/FSharp.PowerPack.Math.Providers.fsproj b/workyard/math-provider/lapack/FSharp.PowerPack.Math.Providers.fsproj
new file mode 100755
index 0000000..a7aa92e
--- /dev/null
+++ b/workyard/math-provider/lapack/FSharp.PowerPack.Math.Providers.fsproj
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpPowerPackSourcesRoot>..\..\..</FSharpPowerPackSourcesRoot>
+  </PropertyGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.Settings.targets"/>
+  <PropertyGroup>
+    <OutputType>Library</OutputType>
+    <SchemaVersion>2.0</SchemaVersion>
+    <AllowCrossTargeting>true</AllowCrossTargeting>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <DocumentationFile>FSharp.PowerPack.Math.Providers.xml</DocumentationFile>
+    <NoWarn>$(NoWarn);58;62</NoWarn>
+  </PropertyGroup>
+  <!-- These dummy entries are needed for F# Beta2 -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Compile Include="service.fsi" />
+    <Compile Include="service.fs" />
+    <Compile Include="lapack_base.fs" />
+    <Compile Include="lapack_service_mkl.fsi" />
+    <Compile Include="lapack_service_mkl.fs" />
+    <Compile Include="lapack_service_netlib.fsi" />
+    <Compile Include="lapack_service_netlib.fs" />
+    <Compile Include="linear_algebra_service.fs" />
+    <Compile Include="linear_algebra_managed.fs" />
+    <Compile Include="linear_algebra.fsi" />
+    <Compile Include="linear_algebra.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <ProjectReference Include="..\..\FSharp.PowerPack.fsproj"  >
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.PowerPack</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(FSharpPowerPackSourcesRoot)\FSharpPowerPackSource.targets"/>
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')"  />
+</Project>
diff --git a/workyard/math-provider/lapack/build.bat b/workyard/math-provider/lapack/build.bat
new file mode 100755
index 0000000..9aab8bc
--- /dev/null
+++ b/workyard/math-provider/lapack/build.bat
@@ -0,0 +1,6 @@
+rem obsolete, pending delete
+rem call regen.bat
+rem ..\..\..\..\..\bin\fsc -a -o bin/FSharp.Math.LAPack.dll lapack_base.fs lapack.fsi lapack.fs lapack_service_mkl.fsi lapack_service_mkl.fs lapack_service_netlib.fsi lapack_service_netlib.fs
+
+
+
diff --git a/workyard/math-provider/lapack/code_generator.fs b/workyard/math-provider/lapack/code_generator.fs
new file mode 100755
index 0000000..78720dd
--- /dev/null
+++ b/workyard/math-provider/lapack/code_generator.fs
@@ -0,0 +1,611 @@
+// CONTENTS-INDEX-REGEXP = FROM>^.?.?! <TO
+//----------------------------------------------------------------------------
+//CONTENTS-START-LINE: HERE=2 SEP=2
+// 24.    argument specification
+// 48.    generator
+// 335.   specifications
+// 457.   specifications list
+// 482.   generate netlib and MKL bindings
+//CONTENTS-END-LINE:
+//----------------------------------------------------------------------------
+
+#nowarn "51"
+
+open System
+open System.Runtime.InteropServices
+open Microsoft.FSharp.NativeInterop
+open Microsoft.FSharp.Math
+
+// Developed by Can Erten.
+// (c) Microsoft Corporation 2005-2009.
+
+//----------------------------------------------------------------------------
+//! argument specification
+//----------------------------------------------------------------------------
+
+type Arg =
+  // The first string is always the name of the argument.
+  | Dim    of string                            // "m"
+  | Matrix of string * string * string          // "a","m","k"
+  | Vector of string * string                   // "v","k"
+  | HW     of string * string                   // "lda","k"          -- HW meaning HardWired
+  | Array  of string * string                   // ipiv,n             -- also local workspace
+  | Array2 of string * string * string          // worko, "m", "n"    -- 2 dimension array with length m and n
+  | Out    of Arg
+  | In     of Arg
+  | InOut  of Arg
+  | Info   of string                            // "info"
+  | UserDefined of string                       // "joleft" -> it will have its own data type
+  | Trans  of string * string option            // "transId", (None, 'n' or (Some "a", 't' and no need to fix up matrix "a"))
+  | Work   of  Arg * string        // "var NAME   ARRAY - SIZE....  // TYPE!!!!"
+  // double *work, int *lwork,
+
+let mapLeafArg f = function Out arg -> f arg | InOut arg -> f arg | arg -> f arg
+
+
+//----------------------------------------------------------------------------
+//! generator
+//----------------------------------------------------------------------------
+
+open System.Collections.Generic
+open System.IO
+
+let mutable sw = null : StreamWriter
+let printf fmt = fprintf (sw :> TextWriter) fmt
+let start path = sw <- new StreamWriter(path:string); Printf.printf "Writing %s\n" path
+let stop()  = sw.Close()
+
+// let printf fmt = Printf.printf fmt
+
+let genFormal arg = 
+  let inputMatcher p = 
+    match p with 
+             | UserDefined(a) -> sprintf "(%s)"  a
+             | Matrix (a,m,n) -> sprintf "(%s:matrix)" a
+             | Vector (v,m)   -> sprintf "(%s:vector)" v
+             | Array (a,b)    -> sprintf "(%s)" a
+             | _ -> assert (false)  
+  match arg with
+    | In p1    -> Some (inputMatcher p1)
+    | InOut p1 -> Some (inputMatcher p1)
+    | _        -> None
+  //////////////////////////////////////////////
+  
+// This is overkill:
+let genInputCopies arg = 
+    let fixInput arg = 
+        match arg with 
+        | Matrix (a,_,_)  -> printf "  let %s = Matrix.copy %s\n" a a
+        | Vector(a,_)     -> printf "  let %s = Vector.copy %s\n" a a
+        | Array(a,_)      -> printf "  let %s = Array.copy %s\n" a a
+        | Array2(a,_,_)   -> printf "  let %s = Array2D.Copy %s\n" a a
+        | UserDefined (_) -> ()
+        | _ -> assert false
+    match arg with
+    | In a  | InOut a -> fixInput a
+    | _ -> () 
+  
+let rec genDimension f (knownDims:Dictionary<string,int>) arg =
+  let isExprNotId (str:string) = str.Contains(" ") // e.g. dgels function has a "max m n" dimension
+  let setDimension d (expr,exprDescription) =
+    if isExprNotId d then
+      // Some dimensions are related to other (prior) dims by formula. Assert it.
+      printf "  NativeUtilities.assertDimensions \"%s\" (\"%s\",\"%s\") (%s,%s);\n" f d exprDescription d expr
+      //printf "  assert(%s = %s);\n" d expr
+    else
+      if knownDims.ContainsKey(d) then
+        printf "  NativeUtilities.assertDimensions \"%s\" (\"%s\",\"%s\") (%s,%s);\n" f d exprDescription d expr
+        //printf "  assert(%s = %s);\n" d expr
+      else
+        printf "  let %s = %s in\n" d expr
+        knownDims.[d] <- 1
+  match arg with
+  | Dim n                      -> ()
+  | Matrix (a,m,n)             -> setDimension m (sprintf "NativeUtilities.matrixDim1 %s" a,sprintf "Dim1(%s)" a);
+                                  setDimension n (sprintf "NativeUtilities.matrixDim2 %s" a,sprintf "Dim2(%s)" a);
+  | Vector (v,m)               -> setDimension m (sprintf "NativeUtilities.vectorDim  %s" v,sprintf "Dim(%s)"  v);
+  | HW _                       -> ()
+  | Trans _                    -> ()
+  | Out _                      -> ()
+  | InOut p                    -> genDimension f knownDims p
+  | In p                       -> genDimension f knownDims p
+  | _ -> ()
+  
+let rec genAllocResult arg = 
+  match arg with
+  | Matrix (a,m,n)      -> printf "  let %s = Matrix.zero (%s) (%s)\n" a m n
+  | Array (ip, n)       -> printf "  let %s = Array.zeroCreate  (%s)\n" ip n
+  | Array2(work, ld, n) -> printf "  let %s = Array2D.zeroCreate (%s) (%s)\n" work ld n
+  | Vector (v,m)        -> printf "  let %s = Vector.zero (%s)\n"    v m
+  | Work (p,_)              -> genAllocResult p
+  | Out p -> genAllocResult p
+  | _ -> ()
+ 
+let preFixups args = 
+  // Matrices that must be transposed prior to calling.
+  let selectTransArgs  = function Trans (tv,Some a) -> Some a | _ -> None
+  let selectMatrixArgs = mapLeafArg (function Matrix (a,m,n) | In(Matrix (a,m,n)) | InOut(Matrix (a,m,n)) -> Some a |  _ -> None)
+  let matrices  = List.choose  selectMatrixArgs args |> Set.ofList
+  let transArgs = List.choose selectTransArgs  args |> Set.ofList
+  Set.diff matrices transArgs
+
+let postFixups args = 
+  // Matrices that must be transposed prior to calling.
+  let selectTransArgs = function Trans (tv,Some a) -> Some a | _ -> None
+  let selectMatrixOut = function Out (Matrix (a,m,n)) -> Some a | InOut (Matrix (a,m,n)) -> Some a | _ -> None
+  let matricesOut = List.choose selectMatrixOut args |> Set.ofList
+  let transArgs    = List.choose selectTransArgs args |> Set.ofList
+  Set.diff matricesOut transArgs
+
+let rec genTransposeFixup fixups arg = 
+  match arg with
+    | Matrix(a,m,n) when Set.contains a fixups -> printf "  let %s = Matrix.transpose %s\n" a a
+    | Out arg -> genTransposeFixup fixups arg
+    | InOut arg -> genTransposeFixup fixups arg
+    | In arg -> genTransposeFixup fixups arg
+    | _ -> ()
+
+let rec genActualDef arg = 
+  match arg with
+  | Dim n                  -> printf "  let mutable arg_%s = %s\n" n n
+  | Matrix (a,m,n)         -> printf "  let arg_%s = NativeUtilities.pinM %s\n" a a
+  | Vector (v,m)           -> printf "  let arg_%s = NativeUtilities.pinV %s\n" v v
+  | Array(a,i)             -> printf "  let arg_%s = NativeUtilities.pinA %s\n" a a
+  | Array2(a,m,n)          -> printf "  let arg_%s = NativeUtilities.pinA2 %s\n" a a
+  | Trans (tv,opt)         -> printf "  let mutable arg_%s = '%s'\n" tv (if opt.IsSome then "t" else "n")
+  | UserDefined(s)         -> printf "  let mutable arg_%s = %s\n" s s
+  | HW (n,x)               -> printf "  let mutable arg_%s = %s\n" n x
+  | Info(n)                -> printf "  let mutable arg_%s = 0\n" n
+  
+  | Work (p,_)             -> genActualDef p  
+  | Out p                  -> genActualDef p
+  | InOut p                -> genActualDef p
+  | In p                   -> genActualDef p
+  
+let rec genActualArg arg = 
+  match arg with
+  | Dim n                  -> sprintf "&&arg_%s" n
+  | Matrix (a,m,n)         -> sprintf "arg_%s.Ptr" a
+  | Vector (v,m)           -> sprintf "arg_%s.Ptr" v
+  | Array (a,i)            -> sprintf "arg_%s.Ptr" a
+  | Array2 (a,i,p)         -> sprintf "arg_%s.Ptr" a
+  | HW (n,x)               -> sprintf "&&arg_%s" n
+  | Trans (tv,x)           -> sprintf "&&arg_%s" tv
+  | Info (m)               -> sprintf "&&arg_%s" m
+  | UserDefined(s)         -> sprintf "&&arg_%s" s
+  
+  | Work (p,_) -> genActualArg p
+  | Out p -> genActualArg p
+  | InOut p ->  genActualArg p
+  | In  p   ->  genActualArg p
+
+let genWorkWorkaround f spec moduleName=
+    //find work args  Array(a,i)     ->      printf    "    NativeUtilities.freeA arg_%s\n" a
+    let selectWorkArrayName  = function Work (Array (aName,_),typ) -> Some(aName,typ) | _ -> None
+    let selectWorkHWSizeName = function Work (HW (sizeName,_),_) -> Some(sizeName) | _ -> None
+    
+    
+    let woNameList = List.choose selectWorkArrayName spec
+    let woSizeList = List.choose selectWorkHWSizeName spec
+    
+  
+    assert (woNameList.Length = woSizeList.Length)
+    
+    if woNameList.Length >0 then
+        // filteri
+ 
+        // Note: not tail recursive
+        let findall_i f xs =
+            let rec aux i xs = match xs with [] -> [] | y::ys -> if f i y then i :: aux (i+1) ys else aux (i+1) ys  
+            aux 0 xs
+                
+        let sizeIndexList = findall_i (fun i x -> match x with | Work((HW _),_) -> true | _ -> false) spec
+        printf "  // ask for work array size\n"
+        printf "  try\n";
+        printf "    %s.%s(%s)\n" moduleName f (String.Join(",", Array.ofList (List.map genActualArg spec)));
+        printf "  finally\n";
+        
+        // freeing all!!! start from here
+        
+        List.iter (fun x ->  printf "    NativeUtilities.freeA arg_%s\n" (fst x)) woNameList
+
+        printf "  if arg_info = 0  "
+        // this is returns +1 value be careful!!! it#s modified..
+        List.iter (fun (x : int) -> printf " or arg_info=(-%s) " ((x+1).ToString())) sizeIndexList
+        printf "then\n"
+        
+        List.iter2
+           (fun s n -> 
+                match (snd n) with
+                | "f" -> printf "    arg_%s <- int32 %s.[0]\n" s (fst n)
+                | "i" -> printf "    arg_%s <-  %s.[0]\n" s (fst n)
+                | _ -> assert(false) ) woSizeList woNameList
+        
+        printf "  else assert(false)\n"
+        
+        
+        List.iter2
+           (fun n s -> 
+                match (snd n) with
+                | "f" -> printf "  let arg_%s = NativeUtilities.pinA (Array.zeroCreate arg_%s : float[])\n" (fst n) s
+                | "i" -> printf "  let arg_%s = NativeUtilities.pinA (Array.zeroCreate arg_%s : int[])\n" (fst n) s
+                | _ -> assert(false) )   woNameList woSizeList 
+
+let  genInfo f spec = 
+    let rec genInfoHandle i arg = 
+        let argPrint i arg = printf "   | -%-2d -> invalid_arg \"%s: %s (argument %d)\"\n" (i+1) f arg (i+1)
+        match arg with
+        | Dim n               -> argPrint i n
+        | Matrix (a,_,_)      -> argPrint i a
+        | Vector (v,_)        -> argPrint i v
+        | Array (a,_)         -> argPrint i a
+        | Array2 (a,_,_)      -> argPrint i a
+        | HW (n,x)            -> argPrint i n
+        | Trans (tv,x)        -> argPrint i tv
+        | Info (m)            -> argPrint i m
+        | UserDefined(s)      -> argPrint i s
+        
+        | Work (p,_)          -> genInfoHandle i p
+        | Out p               -> genInfoHandle i p
+        | InOut p             -> genInfoHandle i p
+        | In p                -> genInfoHandle i p
+      // if info exist
+    //let info = try Some (List.find(fun x -> match x with  | Info _ -> true;  | _ -> false ) spec)
+      //         with Not_found -> None
+               
+    //let info2 = List.tryFind (fun x -> match x with | Info _ -> true | _ -> false) spec
+    let info = List.tryFind (function Info _ -> true | _ -> false) spec
+      
+    if (info.IsSome) then     
+      let name = match info.Value with | Info(s) -> s | _ -> assert(false)
+      printf "  match arg_%s with\n" name
+      List.iteri genInfoHandle spec
+      printf "   | 0   -> ()\n" 
+      printf "   | n   -> failwith (sprintf \"%s : returned %%d. The computation failed.\" n)\n" f
+    ()
+
+let rec genActualDispose arg = 
+  match arg with
+  | Dim n                -> ()
+  | Matrix (a,m,n)       -> printf "    NativeUtilities.freeM arg_%s\n" a
+  | Vector (v,m)         -> printf "    NativeUtilities.freeV arg_%s\n" v
+  | Array(a,i)           -> printf "    NativeUtilities.freeA arg_%s\n" a
+  | Array2(a,i,j)        -> printf "    NativeUtilities.freeA2 arg_%s\n" a
+  | HW (n,x)             -> ()
+  | Trans (tv,x)         -> ()
+  | Info _ -> ()
+  | UserDefined(s) -> ()
+  | Work (p,_) -> genActualDispose p
+  | InOut p -> genActualDispose p
+  | Out p -> genActualDispose p
+  | In p   -> genActualDispose p
+  
+let genResult arg = 
+  match arg with
+  | Out (Matrix (a,m,n)) -> Some (sprintf "%s" a)
+  | Out (Vector (v,m))   -> Some (sprintf "%s" v)
+  | Out (Array (a,_))    -> Some (sprintf "%s" a)
+  | Out (Array2 (a,_,_)) -> Some (sprintf "%s" a)
+  | Out (HW(a,_))        -> Some (sprintf "arg_%s" a)
+  | InOut (Matrix (a,m,n)) -> Some (sprintf "%s" a)
+  | InOut (Vector (v,m))   -> Some (sprintf "%s" v)
+  | InOut (Array (a,_))    -> Some (sprintf "%s" a)
+  | InOut (Array2 (a,_,_)) -> Some (sprintf "%s" a)
+  | Out _ -> assert false
+  | InOut _ -> assert false
+  | _ -> None
+
+let genFunction (f,spec) moduleName= 
+  printf "\n";
+  let args = List.choose genFormal spec
+  printf " member this.%s(%s) = \n" f (String.Join(",",Array.ofList args))
+  
+  printf "  // input copies\n";
+  List.iter genInputCopies spec
+  
+  printf "  // dimensions\n";
+  let knownDims = new System.Collections.Generic.Dictionary<_,_>()
+  List.iter (genDimension f knownDims) spec;
+  printf "  // allocate results\n";
+  List.iter genAllocResult spec;
+  printf "  // transpose\n";
+  List.iter (genTransposeFixup (preFixups spec)) spec
+  printf "  // setup actuals\n";
+  List.iter genActualDef spec;
+  
+   // work call if work exist
+  genWorkWorkaround f spec moduleName
+  /////////////////
+  printf "  // call function\n"
+  printf "  try\n";
+  printf "    %s.%s(%s)\n" moduleName f (String.Join(",", Array.ofList (List.map genActualArg spec)));
+  printf "  finally\n";
+  List.iter genActualDispose spec;
+
+  printf "  // INFO\n"
+  genInfo f spec
+  
+  printf "  // fixups\n";
+  List.iter (genTransposeFixup (postFixups spec)) spec   
+  printf "  // result tuple\n";
+  printf "  %s\n" (String.Join(",", Array.ofList (List.choose genResult spec)));
+  printf "\n";
+
+
+//----------------------------------------------------------------------------
+//! specifications
+//----------------------------------------------------------------------------
+    
+let sl = "Lapack"
+let sb = "Blas"
+
+let fspec_dgemm =
+  "Matrix-Matrix Multiplication", sb, "dgemm_",
+  [Trans ("transa",Some "a");Trans ("transb",Some "b");Dim "m";Dim "n";Dim "k";
+   HW ("alpha","1.0");In (Matrix("a","m","k"));HW ("ldk","k");In (Matrix("b","k","n"));
+   HW ("ldn","n");HW ("beta","1.0");Out (Matrix("c","m","n"));HW ("ldm","m")]
+
+let fspec_dgesv =
+  "Solve", sl ,"dgesv_" ,
+  [Dim "n"; Dim "NRHS"; InOut (Matrix("a","n","n")); HW("lda","max 1 n");Out (Array("ipiv", "n")); 
+   InOut (Matrix("b", "n", "NRHS")); HW("ldb","max 1 n"); Info "info"  ]       
+
+let fspec_dtrsv =
+  "Solve dtrsv", sb ,"dtrsv_" ,
+  [In (UserDefined("uplo")); 
+   Trans ("transa",Some "a");
+   HW ("diag","'N'");
+   Dim "n";
+   In (Matrix("a","n","n")); HW("lda","max 1 n");   
+   InOut (Vector("x", "n")); HW("incx","1"); ]       
+
+let fspec_dtrsm =
+  "Solve dtrsm", sb ,"dtrsm_" ,
+  [HW ("side","'L'");
+   In (UserDefined("uplo")); 
+   Trans ("transa",Some "a");
+   HW ("diag","'N'");
+   Dim "m";
+   Dim "n";
+   HW ("alpha","1.0");   
+   In    (Matrix("a","m","k")); HW("lda","m"); // assumes side=L
+   InOut (Matrix("b","m","n")); HW("ldb","m"); // assumes side=L
+  ]       
+
+// work is problematic with lapack, intel's OK
+let fspec_dgglse =
+  "Solve LSE using GRQ", sl, "dgglse_",
+  [Dim "m"; Dim "n"; Dim "p"; InOut (Matrix("a","m","n")); HW("lda","max 1 m"); In (Matrix("b","p","n"));
+   HW("ldb","max 1 p"); InOut (Vector("c","m")); In(Vector("d","p")); Out (Array("x","n"));
+   Work (Array("work","1"),"f"); Work (HW("lwork","-1"),"i"); Info "info" ]
+             
+let fspec_dgeev =
+  "EigenValue Non-Symetrix" , sl , "dgeev_",
+  [HW("jobvl","'N'");In(UserDefined("jobvr")); //In (HW("jobvl"));In (UserDefined("jobvr"))  ;
+   Dim "n";  In (Matrix("a","n","n")) ;     HW("lda","n"); 
+   Out (Array("wr","n"));Out (Array ("wi","n"));
+   Array2("vl","n","n");    (HW("ldvl","n")); 
+   Out (Array2("vr","n","n"));   (HW("ldvr","n")); 
+   Array("work","(4*n)"); HW("lwork","(4*n)");
+   Info("info")]
+                            
+let fspec_dposv =
+  "Solve Cholesky", sl,  "dposv_",
+  [HW("uplo","'U'"); Dim "n"; Dim "nrhs"; InOut (Matrix("a","n","n")); HW("lda","max 1 n"); InOut(Matrix("b","n","nrhs"));
+   HW("ldb","max 1 n");Info "info" ]     
+                        
+let fspec_dgels =
+  "Solve Upper" , sl, "dgels_",
+  [Trans ("transa",None) ; Dim "m"; Dim "n"; Dim "nrhs";
+   InOut  (Matrix("a","m","n"));               HW("lda","max 1 m") ;InOut  (Matrix ("b","(max m n)", "nrhs"));
+   HW("ldb","max m (max 1 n)") ; Work (Array("work","1"),"f"); Work (HW("lwork","-1"),"i");Info("info")]
+   
+       
+let fspec_dsyev =
+  "Eigen Value of Symetric Matrix",sl, "dsyev_",
+  [In (UserDefined("jobz")); In (UserDefined("uplo")); Dim "n"; InOut (Matrix("a","n","n")); HW("lda","max 1 n");
+   Out (Array("w","n")); Work (Array("work","1"),"f"); Work (HW("lwork", "-1"),"i"); Info ("info")]
+
+let fspec_dsyevd =
+  "Eigen Value of Symetric Matrix - Divide and Conquer",sl, "dsyevd_",
+  [In (UserDefined("jobz")); In (UserDefined("uplo")); Dim "n"; InOut (Matrix("a","n","n")); HW("lda","max 1 n");
+   Out (Array("w","n")); Work (Array("work","1"),"f");    Work (HW("lwork", "-1"),"i");
+   Work (Array("iwork","1"),"i"); Work (HW("liwork", "-1"),"i");Info ("info") ]
+
+let fspec_dgesvd =
+  "Singular Value Decomposition", sl,"dgesvd_",
+  [HW("jobu","'A'"); HW("jobvt","'A'"); Dim "m"; Dim "n";
+   In (Matrix ("a","m","n")); HW("lda","max 1 m");
+   Out (Array("s","min m n"));
+   Out (Matrix("u","m","min m n"));  HW("ldu","m"); 
+   Out (Matrix("vt","n","n"));       HW("ldvt","n");
+   Work (Array("work","1"),"f"); 
+   Work (HW("lwork", "-1"),"i");
+   Info ("info") ]
+
+let fspec_dgesdd =
+  "Singular Value Decomposition Divide- Conquer", sl, "dgesdd_",
+  [HW("JOBZ","'A'");  Dim "m"; Dim "n"; 
+   In (Matrix ("a","m","n")); HW("lda","max 1 m");
+   Out (Array("s","min m n"));
+   Out (Matrix("u" ,"m","m")); HW("ldu" ,"m");
+   Out (Matrix("vt","n","n")); HW("ldvt","n");
+   Work (Array("work","1"),"f");
+   Work (HW("lwork", "-1"),"i");
+   Array("iwork","8*(min m n)");  
+   Info ("info") ]
+
+let fspec_dsygv_ =
+  "Single Value Decomposition for Symetric Matrices", sl, "dsygv_",
+  [HW("itype","1");HW("JOBZ","'V'");HW("uplo","'U'");Dim "n"; InOut (Matrix ("a","n","n"));HW("lda","max 1 n");InOut (Matrix ("b","n","n"));
+   HW("ldb","max 1 n"); Out(Array("w","n")); Work (Array("work","1"),"f"); Work (HW("lwork", "-1"),"i");Info ("info") ]
+ 
+let fspec_dsygvd_ =
+  "Single Value Decomposition for Symetric Matrices Divide and Conquer", sl,"dsygvd_",
+  [HW("itype","1");HW("JOBZ","'V'");HW("uplo","'U'");Dim "n"; InOut (Matrix ("a","n","n"));HW("lda","max 1 n");InOut (Matrix ("b","n","n"));
+   HW("ldb","max 1 n"); Out(Array("w","n")); Work (Array("work","1"),"f"); Work (HW("lwork", "-1"),"i"); Work (Array("iwork","1"),"i"); Work (HW("liwork", "-1"),"i");Info ("info") ]
+ 
+let fspec_dgesvx_ =
+  "LU factorization to compute the solution to a real  system of linear equations ", sl, "dgesvx_",
+  [HW("fact","'E'");Trans ("transx",None);Dim "n";Dim "nrhs";InOut (Matrix ("a","n","n"));HW("lda","max 1 n");
+   Out (Matrix("af","n","n"));HW("ldaf","max 1 n");Out (Array("ipiv", "n")); Out (HW("equed","'n'")); Out (Array("r","n"));
+   Out (Array("c","n")); InOut (Matrix ("b","n","nrhs"));HW("ldb","max 1 n"); Out( Matrix("x","n","nrhs")); HW("ldx","max 1 n"); 
+   Out (HW("rcond","0.0")); Out (Array("ferr","nrhs")); Out (Array("berr","nrhs")); Array ("work", "4*n"); Array("iwork","n");Info ("info")]
+
+let fspec_dposvx_ =
+  "Cholesky Factorisation - Expert", sl , "dposvx_",
+  [HW("fact","'E'"); HW("uplo","'U'");Dim "n";Dim "nrhs";InOut (Matrix ("a","n","n"));HW("lda","max 1 n"); 
+   Out (Matrix("af","n","n"));HW("ldaf","max 1 n");Out (HW("equed","'n'"));  Out (Array("s","n"));
+   InOut (Matrix ("b","n","nrhs"));HW("ldb","max 1 n"); Out( Matrix("x","n","nrhs")); HW("ldx","max 1 n"); 
+   Out (HW("rcond","0.0")); Out (Array("ferr","nrhs")); Out (Array("berr","nrhs")); Array ("work", "3*n"); Array("iwork","n");Info ("info")]
+
+let fspec_dpotrf =
+  "Cholesky factorisation of a real symmetric positive definite matrix" , sl, "dpotrf_",
+  [In(UserDefined("uplo")); Dim "n"; InOut (Matrix("a", "n","n")); HW ("lda", "max 1 n"); Info ("info")]                                            
+
+let fspec_dgetrf =
+  "LU factorisation of general matrix using partial pivoting and row interchanges" , sl, "dgetrf_",
+  [ Dim "m"; Dim "n"; InOut (Matrix("a", "m","n")); HW ("lda", "max 1 m"); Out (Array("ipiv","min m n")); Info ("info")]                                            
+
+let fspec_dgeqrf_=
+  "QR Factorisation", sl, "dgeqrf_",
+  [ Dim "m"; Dim "n" ;InOut (Matrix ("a", "m","n")) ;HW ("lda", "max 1 m");Out (Array("tau", "min m n"));
+    Work (Array("work","1"),"f"); Work (HW("lwork", "-1"),"i"); Info ("info")]
+
+/// Do not use trans argument here.           
+let fspec_dgemv_ =
+  "Matrix Vector Multiplication", sb,"dgemv_" ,
+  [Trans("trans",None);Dim "m";Dim "n";HW ("alpha","1.0");In (Matrix("a", "m","n"));HW("lda","max 1 m");
+   In (Vector("x", "n"));
+   HW("incx","1"); HW ("beta","1.0"); Out (Vector("y", "m")); HW("incx","1")] 
+
+// dggev_( char *jobvl, char *jobvr, int *n, double *a, int *lda, double *b, int *ldb, 
+//double *alphar, double *alphai,double *beta,double *vl,int *ldvl,double *vr,int *ldvr,double *work, int *lwork,int *info);                            
+let fspec_dggev =
+  "EigenValues and Eigen Vectors for nonsymetruc matrices", sl, "dggev_", 
+  [HW("jobvl","'N'"); HW("jobvr", "'V'");  Dim "n" ;InOut (Matrix ("a", "n","n")); HW ("lda", "max 1 n");InOut (Matrix ("b", "n","n"));
+   HW ("ldb", "max 1 n"); Out (Array("alphar","n"));Out (Array("alphai","n")); Out (Array("beta","n"));
+   Array2("vl","n","n");    (HW("ldvl","n")); 
+   Out (Array2("vr","n","n"));   (HW("ldvr","n")); 
+   Array("work","(8*n)"); HW("lwork","(8*n)");
+   Info("info")]
+
+
+//----------------------------------------------------------------------------
+//! specifications list
+//----------------------------------------------------------------------------
+
+let fspecs = [fspec_dgemm;
+              fspec_dgesv;
+              fspec_dtrsv;
+              fspec_dtrsm;
+              fspec_dgglse;
+              fspec_dgeev;
+              fspec_dposv;
+              fspec_dgels;
+              fspec_dsyev;
+              fspec_dsyevd;
+              fspec_dgesvd;
+              fspec_dgesdd;
+              fspec_dsygv_;
+              fspec_dsygvd_;
+              fspec_dgesvx_;
+              fspec_dposvx_;
+              fspec_dpotrf;
+              fspec_dgetrf;
+              fspec_dgeqrf_;
+              fspec_dgemv_;
+              fspec_dggev;
+             ]
+
+
+//----------------------------------------------------------------------------
+//! generate netlib and MKL bindings
+//----------------------------------------------------------------------------
+
+let produceCode moduleName (comments,(library),funcName,spec) = 
+    printf "\n///%s" comments
+    genFunction (funcName,spec) moduleName
+    
+    
+let generateFile filename providerId blasDLLName lapackDLLName hyphen notices =  
+    let hyphenS = "[_]"
+    let hyphenReplace = if hyphen then "_" else ""
+    let quoted s = "\"" ^ s ^ "\""
+
+    let className  = sprintf "Lapack%sService" providerId
+    let moduleName = sprintf "Lapack%sStubs"   providerId
+    
+    let blasdllX    = "[BLASDLL]"
+    let lapackdllX  = "[LAPACKDLL]"
+    let moduleNameX = "[MODULENAME]"
+    let noticeX     = "[NOTICE]"
+
+    let notice = String.Join("\n", Array.ofList (List.map (fun s -> "/// " ^ s) notices))
+    
+    start (filename)
+    printfn "namespace Microsoft.FSharp.Math.Bindings.Internals"
+    printfn "#nowarn \"51\""
+    printfn "open Microsoft.FSharp.Math"
+    printfn "open Microsoft.FSharp.Math.Bindings.Internals"
+    
+    let templateFile = File.ReadAllText("lapack_service_template.fs")
+    printf "%s" (templateFile.Replace(blasdllX,blasDLLName)
+                             .Replace(lapackdllX,lapackDLLName)
+                             .Replace(moduleNameX,moduleName)
+                             .Replace(hyphenS,hyphenReplace)
+                             .Replace(noticeX,notice)
+                )
+    printfn "/// Internal provider of Lapack functionality, not for direct user usage."
+    printfn "type %s() = class" className
+    printfn " interface ILapack with "
+    List.iter (produceCode moduleName) fspecs
+    printfn " end"
+    printfn "end"
+    printfn "module Lapack%s = begin" providerId
+    printfn " let %sProvider = new Microsoft.FSharp.Math.Experimental.Provider<_>(%s,[|%s;%s|],fun () -> new %s() :> ILapack)"
+      providerId
+      (quoted providerId)
+      (quoted blasDLLName) (quoted lapackDLLName)
+      className
+    printfn "end"
+    stop()
+    start (filename ^ "i") 
+    printfn "namespace Microsoft.FSharp.Math.Bindings.Internals"       
+    printfn "module Lapack%s =" providerId
+    printfn "  val %sProvider : Microsoft.FSharp.Math.Experimental.Provider<Microsoft.FSharp.Math.Bindings.Internals.ILapack>" providerId
+    printfn "module %s = begin end" moduleName    
+    stop()
+
+let noticesMLK = ["Warning:";
+                  "IMPORTANT WARNING NOTICE:";
+                  "INTEL MATH KERNEL LIBRARY 9.1 FOR WINDOWS DOES NOT BELONG TO MICROSOFT - IT IS THIRD PARTY TECHNOLOGY.";
+                  "IT IS CLEARED ONLY FOR USE BY A SPECIFIC MSR RESEARCH TEAM.";
+                  "DO NOT USE IT UNTIL YOU HAVE CLEARED ITS USE FOR YOUR PROJECT WITH YOUR LEGAL CONTACT.";
+                  "";
+                  "The following stubs bind directly to Intel MKL functionality.";
+                  "You should not use them without:";
+                  "a) Intel MKL developer licenses.";
+                  "b) Seeking local legal approval.";
+                 ]    
+
+do
+  let filename   = "lapack_service_netlib.fs"
+  let providerId = "Netlib"
+  let blasdll    = "blas.dll"
+  let lapackdll  = "lapack.dll"
+  let typeHyphen = true  // true = underscore suffix 
+  let notices    = ["Notice: This file generates bindings for netlib.org BLAS/LAPACK DLLs"] 
+  generateFile filename providerId blasdll lapackdll typeHyphen notices
+
+do
+  let filename   = "lapack_service_mkl.fs"
+  let providerId = "MKL"
+  let blasdll    = "mkl_def.dll"
+  let lapackdll  = "mkl_lapack.dll"
+  let typeHyphen = false // false = no underscore suffix
+  let notices    = noticesMLK
+  generateFile filename providerId blasdll lapackdll typeHyphen notices
+
+
+(* scratch *)
diff --git a/workyard/math-provider/lapack/lapack_base.fs b/workyard/math-provider/lapack/lapack_base.fs
new file mode 100755
index 0000000..94ab338
--- /dev/null
+++ b/workyard/math-provider/lapack/lapack_base.fs
@@ -0,0 +1,131 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Math.Bindings.Internals
+#nowarn "51"
+
+open System
+open System.Runtime.InteropServices
+open Microsoft.FSharp.NativeInterop
+open Microsoft.FSharp.Math
+
+///This is an internal interface and not for user usage.
+///It exposes a specialised subset of BLAS/LAPACK functionality.
+///This functionality is used by us to build the exposed APIs.
+///It is those exposed APIs that should be used.
+type ILapack = interface
+    //Matrix-Matrix Multiplication
+    abstract dgemm_ : Math.matrix * Math.matrix -> Math.matrix
+
+    //Matrix-Vector Multiplication
+    abstract dgemv_ : Math.matrix * Math.vector -> Math.vector
+
+    //Solve (linear equations)
+    abstract dgesv_ : Math.matrix * Math.matrix -> Math.matrix * int array * Math.matrix
+
+    //Solve symmetric positive definite matrix (linear equations)
+    abstract dposv_ : Math.matrix * Math.matrix -> Math.matrix * Math.matrix
+
+    //Solve triangular (linear equations)
+    abstract dtrsv_ : char * Math.matrix * Math.vector -> Math.vector
+
+    //Solve triangular (linear equations)
+    abstract dtrsm_ : char * Math.matrix * Math.matrix -> Math.matrix
+
+    //Solve (linear equations) using LU factorization
+    abstract dgesvx_ :
+      Math.matrix * Math.matrix ->
+      Math.matrix * Math.matrix * int array * char * double array * double array *
+      Math.matrix * Math.matrix * float * double array * double array
+
+    //Eigen Value Non-Symmetric
+    abstract dgeev_ : char * Math.matrix -> double array * double array * double [,]    
+
+    //Eigen Value of Symmetric Matrix
+    abstract dsyev_ : char * char * Math.matrix -> Math.matrix * double array
+
+    //Eigen Value of Symmetric Matrix - Divide and Conquer
+    abstract dsyevd_ : char * char * Math.matrix -> Math.matrix * double array
+
+    //Eigen Value for a pair of general matrices
+    abstract dggev_ :
+      Math.matrix * Math.matrix ->
+      Math.matrix * Math.matrix * double array * double array * double array *
+      double [,]
+
+    //Solve least-squares/min-norm.
+    //Note the dimension requirements on second input to match second output.
+    abstract dgels_ : Math.matrix * Math.matrix -> Math.matrix * Math.matrix
+
+    //Solve least-squares/min-norm (with linear equality constraint)
+    abstract dgglse_ :
+      Math.matrix * Math.matrix * Math.vector * Math.vector ->
+      Math.matrix * Math.vector * double array
+
+    //Singular Value Decomposition
+    abstract dgesvd_ :
+      Math.matrix -> double array * Math.matrix * Math.matrix
+
+    //Singular Value Decomposition Divide- Conquer
+    abstract dgesdd_ : Math.matrix -> double array * Math.matrix * Math.matrix
+
+    //Single Value Decomposition for Symmetric Matrices
+    abstract dsygv_ :
+      Math.matrix * Math.matrix -> Math.matrix * Math.matrix * double array
+
+    //Single Value Decomposition for Symetric Matrices Divide and Conquer
+    abstract dsygvd_ :
+      Math.matrix * Math.matrix -> Math.matrix * Math.matrix * double array
+
+    //Cholesky Factorisation
+    abstract dpotrf_ : char * Math.matrix -> Math.matrix
+    
+    abstract dgetrf_ : matrix -> matrix * int[]
+
+    //Cholesky Factorisation - Expert
+    abstract dposvx_ :
+      Math.matrix * Math.matrix ->
+      Math.matrix * Math.matrix * char * double array * Math.matrix * Math.matrix *
+      float * double array * double array
+
+    //QR Factorisation
+    abstract dgeqrf_ : Math.matrix -> Math.matrix * double array
+
+end
+
+
+module NativeUtilities = begin
+    let nativeArray_as_CMatrix_colvec (arr: 'T NativeArray) = new CMatrix<_>(arr.Ptr,arr.Length,1)
+    let nativeArray_as_FortranMatrix_colvec (arr: 'T NativeArray) = new FortranMatrix<_>(arr.Ptr,arr.Length,1)
+    let pinM m = PinnedArray2.of_matrix(m)
+    let pinV v = PinnedArray.of_vector(v)
+    let pinA arr = PinnedArray.of_array(arr)
+    
+    let pinA2 arr = PinnedArray2.of_array2D(arr)
+    
+    let pinMV m1 v2 = pinM m1,pinV v2
+    let pinVV v1 v2 = pinV v1,pinV v2
+    let pinAA v1 v2 = pinA v1,pinA v2
+    let pinMVV m1 v2 m3 = pinM m1,pinV v2,pinV m3
+    let pinMM m1 m2  = pinM m1,pinM m2
+    let pinMMM m1 m2 m3 = pinM m1,pinM m2,pinM m3
+    let freeM (pA: PinnedArray2<'T>) = pA.Free()
+    let freeV (pA: PinnedArray<'T>) = pA.Free()
+    let freeA (pA: PinnedArray<'T>) = pA.Free()
+    
+    let freeA2 a = freeM a
+    
+    let freeMV (pA: PinnedArray2<'T>,pB : PinnedArray<'T>) = pA.Free(); pB.Free()
+    let freeVV (pA: PinnedArray<'T>,pB : PinnedArray<'T>) = pA.Free(); pB.Free()
+    let freeAA (pA: PinnedArray<'T>,pB : PinnedArray<'T>) = pA.Free(); pB.Free()
+    let freeMM (pA: PinnedArray2<'T>,(pB: PinnedArray2<'T>)) = pA.Free();pB.Free()
+    let freeMMM (pA: PinnedArray2<'T>,(pB: PinnedArray2<'T>),(pC: PinnedArray2<'T>)) = pA.Free();pB.Free();pC.Free()
+    let freeMVV (pA: PinnedArray2<'T>,(pB: PinnedArray<'T>),(pC: PinnedArray<'T>)) = pA.Free();pB.Free();pC.Free()
+    
+    let matrixDims (m:Matrix<_>) = m.NumRows, m.NumCols
+    let matrixDim1 (m:Matrix<_>) = m.NumRows
+    let matrixDim2 (m:Matrix<_>) = m.NumCols
+    let vectorDim  (v:Vector<_>) = v.Length
+    
+    let assertDimensions functionName (aName,bName) (a,b) =
+      if a=b then () else
+      failwith (sprintf "Require %s = %s, but %s = %d and %s = %d in %s" aName bName aName a bName b functionName)
+end
diff --git a/workyard/math-provider/lapack/lapack_service.fs b/workyard/math-provider/lapack/lapack_service.fs
new file mode 100755
index 0000000..ce5339a
--- /dev/null
+++ b/workyard/math-provider/lapack/lapack_service.fs
@@ -0,0 +1,5 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Math.Experimental
+// Code abstracted and moved to service.fs.
+// This file will either be removed, or ILapack move here, splitting up from native utilities.
+
diff --git a/workyard/math-provider/lapack/lapack_service_mkl.fs b/workyard/math-provider/lapack/lapack_service_mkl.fs
new file mode 100755
index 0000000..23e2779
--- /dev/null
+++ b/workyard/math-provider/lapack/lapack_service_mkl.fs
@@ -0,0 +1,1354 @@
+namespace Microsoft.FSharp.Math.Bindings.Internals
+#nowarn "51"
+open Microsoft.FSharp.Math
+open Microsoft.FSharp.Math.Bindings.Internals
+/// Warning:
+/// IMPORTANT WARNING NOTICE:
+/// INTEL MATH KERNEL LIBRARY 9.1 FOR WINDOWS DOES NOT BELONG TO MICROSOFT - IT IS THIRD PARTY TECHNOLOGY.
+/// IT IS CLEARED ONLY FOR USE BY A SPECIFIC MSR RESEARCH TEAM.
+/// DO NOT USE IT UNTIL YOU HAVE CLEARED ITS USE FOR YOUR PROJECT WITH YOUR LEGAL CONTACT.
+/// 
+/// The following stubs bind directly to Intel MKL functionality.
+/// You should not use them without:
+/// a) Intel MKL developer licenses.
+/// b) Seeking local legal approval.
+module LapackMKLStubs = begin
+  [<System.Runtime.InteropServices.DllImport(@"mkl_def.dll",EntryPoint="dgemm")>]
+  extern void dgemm_(char *transa, char *transb, int *m, int *n, int *k, double *alpha, double *a, int *lda, double *b, int *ldb, double *beta, double *c, int *ldc);
+
+  [<System.Runtime.InteropServices.DllImport(@"mkl_def.dll",EntryPoint="dtrsv")>]
+  extern void dtrsv_(char *uplo,char *trans,char *diag,int *n,double *a,int *lda,double *x,int *incx);
+
+  [<System.Runtime.InteropServices.DllImport(@"mkl_def.dll",EntryPoint="dtrsm")>]
+  extern void dtrsm_(char *side,char *uplo,char *trans,char *diag,int *m,int *n,double *alpha,double *a,int *lda,double *b,int *ldb);   
+   
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dgesv")>]
+  extern void dgesv_(int *n, int *nrhs, double *a, int *lda, int *ipiv, double *b, int *ldb, int *info);
+
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dgeev")>]
+  extern void dgeev_(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *wr, double *wi, double *vl, int *ldvl, double *vr, int *ldvr, double *work, int *lwork, int *info);
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dposv")>]
+  extern void dposv_(char *uplo, int *n, int *nrhs, double *a, int *lda, double *b, int *ldb, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dgels")>]
+  extern void dgels_(char *trans, int *m,int *n, int *nrhs, double *a, int *lda, double *b, int *ldb, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dgglse")>]
+  extern void dgglse_(int *m, int *n, int *p, double *a, int *lda, double *b, int *ldb, double *c, double *d, double *x, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dsyev")>]
+  extern void dsyev_(char *jobz, char *uplo, int *n, double *a,int *lda, double *w, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dsyevd")>]
+  extern void dsyevd_(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *iwork, int *liwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dgesvd")>]
+  extern void dgesvd_(char *jobu, char *jobvt, int  *m, int *n, double *a, int *lda, double *s, double *u, int *ldu, double *vt, int *ldvt, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dgesdd")>]
+  extern void dgesdd_(char *JOBZ, int  *m, int *n, double *a, int *lda, double *s, double *u, int *ldu, double *vt, int *ldvt, double *work, int *lwork,int *iwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dsygv")>]
+  extern void dsygv_(int *itype, char *jobz, char *uplo, int *n, double *a, int *lda, double *b, int *ldb, double *w, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dsygvd")>]     
+  extern void dsygvd_(int *itype, char *jobz, char *uplo, int *n, double *a, int *lda, double *b, int *ldb, double *w, double *work, int *lwork,int *iwork, int *liwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dggev")>]     
+  extern void dggev_( char *jobvl, char *jobvr, int *n, double *a, int *lda, double *b, int *ldb, double *alphar, double *alphai,double *beta,double *vl,int *ldvl,double *vr,int *ldvr,double *work, int *lwork,int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dgesvx")>]     
+  extern void dgesvx_(char *fact, char *trans, int *n, int *nrhs, double *a, int *lda, double *af, int *ldaf, int *ipiv, char *equed, double *r, double *c, double *b, int *ldb, double *x, int *ldx, double *rcond, double *ferr, double *berr, double *work, int *iwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dposvx")>]     
+  extern void  dposvx_(char *fact, char *uplo, int *n, int *nrhs, double *a, int *lda, double *af, int *ldaf, char *equed, double *s, double *b, int *ldb, double *x, int *ldx, double *rcond, double  *ferr, double *berr, double *work, int *iwork, int *info);
+
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dpotrf")>]     
+  extern void  dpotrf_(char *uplo, int *n, double *a, int *lda, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dgetrf")>]     
+  extern void  dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_lapack.dll",EntryPoint="dgeqrf")>]     
+  extern void dgeqrf_(int  *m, int *n, double *a, int *lda, double *tau, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"mkl_def.dll",EntryPoint="dgemv")>]
+  extern void dgemv_(char* trans, int* m, int* n,double* alpha, double* A, int* lda,double* x, int* incx, double* beta,double* y, int* incy);
+  
+end
+/// Internal provider of Lapack functionality, not for direct user usage.
+type LapackMKLService() = class
+ interface ILapack with 
+///Matrix-Matrix Multiplication
+ member this.dgemm_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let k = NativeUtilities.matrixDim2 a in
+  NativeUtilities.assertDimensions "dgemm_" ("k","Dim1(b)") (k,NativeUtilities.matrixDim1 b);
+  let n = NativeUtilities.matrixDim2 b in
+  // allocate results
+  let c = Matrix.zero (m) (n)
+  // transpose
+  let c = Matrix.transpose c
+  // setup actuals
+  let mutable arg_transa = 't'
+  let mutable arg_transb = 't'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let mutable arg_k = k
+  let mutable arg_alpha = 1.0
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_ldk = k
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldn = n
+  let mutable arg_beta = 1.0
+  let arg_c = NativeUtilities.pinM c
+  let mutable arg_ldm = m
+  // call function
+  try
+    LapackMKLStubs.dgemm_(&&arg_transa,&&arg_transb,&&arg_m,&&arg_n,&&arg_k,&&arg_alpha,arg_a.Ptr,&&arg_ldk,arg_b.Ptr,&&arg_ldn,&&arg_beta,arg_c.Ptr,&&arg_ldm)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeM arg_c
+  // INFO
+  // fixups
+  let c = Matrix.transpose c
+  // result tuple
+  c
+
+
+///Solve
+ member this.dgesv_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dgesv_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dgesv_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  let NRHS = NativeUtilities.matrixDim2 b in
+  // allocate results
+  let ipiv = Array.zeroCreate  (n)
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_n = n
+  let mutable arg_NRHS = NRHS
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_ipiv = NativeUtilities.pinA ipiv
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackMKLStubs.dgesv_(&&arg_n,&&arg_NRHS,arg_a.Ptr,&&arg_lda,arg_ipiv.Ptr,arg_b.Ptr,&&arg_ldb,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_ipiv
+    NativeUtilities.freeM arg_b
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgesv_: n (argument 1)"
+   | -2  -> invalid_arg "dgesv_: NRHS (argument 2)"
+   | -3  -> invalid_arg "dgesv_: a (argument 3)"
+   | -4  -> invalid_arg "dgesv_: lda (argument 4)"
+   | -5  -> invalid_arg "dgesv_: ipiv (argument 5)"
+   | -6  -> invalid_arg "dgesv_: b (argument 6)"
+   | -7  -> invalid_arg "dgesv_: ldb (argument 7)"
+   | -8  -> invalid_arg "dgesv_: info (argument 8)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgesv_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,ipiv,b
+
+
+///Solve dtrsv
+ member this.dtrsv_((uplo),(a:matrix),(x:vector)) = 
+  // input copies
+  let a = Matrix.copy a
+  let x = Vector.copy x
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dtrsv_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dtrsv_" ("n","Dim(x)") (n,NativeUtilities.vectorDim  x);
+  // allocate results
+  // transpose
+  // setup actuals
+  let mutable arg_uplo = uplo
+  let mutable arg_transa = 't'
+  let mutable arg_diag = 'N'
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_x = NativeUtilities.pinV x
+  let mutable arg_incx = 1
+  // call function
+  try
+    LapackMKLStubs.dtrsv_(&&arg_uplo,&&arg_transa,&&arg_diag,&&arg_n,arg_a.Ptr,&&arg_lda,arg_x.Ptr,&&arg_incx)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeV arg_x
+  // INFO
+  // fixups
+  // result tuple
+  x
+
+
+///Solve dtrsm
+ member this.dtrsm_((uplo),(a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let k = NativeUtilities.matrixDim2 a in
+  NativeUtilities.assertDimensions "dtrsm_" ("m","Dim1(b)") (m,NativeUtilities.matrixDim1 b);
+  let n = NativeUtilities.matrixDim2 b in
+  // allocate results
+  // transpose
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_side = 'L'
+  let mutable arg_uplo = uplo
+  let mutable arg_transa = 't'
+  let mutable arg_diag = 'N'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let mutable arg_alpha = 1.0
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = m
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = m
+  // call function
+  try
+    LapackMKLStubs.dtrsm_(&&arg_side,&&arg_uplo,&&arg_transa,&&arg_diag,&&arg_m,&&arg_n,&&arg_alpha,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+  // INFO
+  // fixups
+  let b = Matrix.transpose b
+  // result tuple
+  b
+
+
+///Solve LSE using GRQ
+ member this.dgglse_((a:matrix),(b:matrix),(c:vector),(d:vector)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  let c = Vector.copy c
+  let d = Vector.copy d
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  let p = NativeUtilities.matrixDim1 b in
+  NativeUtilities.assertDimensions "dgglse_" ("n","Dim2(b)") (n,NativeUtilities.matrixDim2 b);
+  NativeUtilities.assertDimensions "dgglse_" ("m","Dim(c)") (m,NativeUtilities.vectorDim  c);
+  NativeUtilities.assertDimensions "dgglse_" ("p","Dim(d)") (p,NativeUtilities.vectorDim  d);
+  // allocate results
+  let x = Array.zeroCreate  (n)
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let mutable arg_p = p
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 p
+  let arg_c = NativeUtilities.pinV c
+  let arg_d = NativeUtilities.pinV d
+  let arg_x = NativeUtilities.pinA x
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackMKLStubs.dgglse_(&&arg_m,&&arg_n,&&arg_p,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_c.Ptr,arg_d.Ptr,arg_x.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-12) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackMKLStubs.dgglse_(&&arg_m,&&arg_n,&&arg_p,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_c.Ptr,arg_d.Ptr,arg_x.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeV arg_c
+    NativeUtilities.freeV arg_d
+    NativeUtilities.freeA arg_x
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgglse_: m (argument 1)"
+   | -2  -> invalid_arg "dgglse_: n (argument 2)"
+   | -3  -> invalid_arg "dgglse_: p (argument 3)"
+   | -4  -> invalid_arg "dgglse_: a (argument 4)"
+   | -5  -> invalid_arg "dgglse_: lda (argument 5)"
+   | -6  -> invalid_arg "dgglse_: b (argument 6)"
+   | -7  -> invalid_arg "dgglse_: ldb (argument 7)"
+   | -8  -> invalid_arg "dgglse_: c (argument 8)"
+   | -9  -> invalid_arg "dgglse_: d (argument 9)"
+   | -10 -> invalid_arg "dgglse_: x (argument 10)"
+   | -11 -> invalid_arg "dgglse_: work (argument 11)"
+   | -12 -> invalid_arg "dgglse_: lwork (argument 12)"
+   | -13 -> invalid_arg "dgglse_: info (argument 13)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgglse_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a,c,x
+
+
+///EigenValue Non-Symetrix
+ member this.dgeev_((jobvr),(a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dgeev_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  // allocate results
+  let wr = Array.zeroCreate  (n)
+  let wi = Array.zeroCreate  (n)
+  let vl = Array2D.zeroCreate (n) (n)
+  let vr = Array2D.zeroCreate (n) (n)
+  let work = Array.zeroCreate  ((4*n))
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_jobvl = 'N'
+  let mutable arg_jobvr = jobvr
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = n
+  let arg_wr = NativeUtilities.pinA wr
+  let arg_wi = NativeUtilities.pinA wi
+  let arg_vl = NativeUtilities.pinA2 vl
+  let mutable arg_ldvl = n
+  let arg_vr = NativeUtilities.pinA2 vr
+  let mutable arg_ldvr = n
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = (4*n)
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackMKLStubs.dgeev_(&&arg_jobvl,&&arg_jobvr,&&arg_n,arg_a.Ptr,&&arg_lda,arg_wr.Ptr,arg_wi.Ptr,arg_vl.Ptr,&&arg_ldvl,arg_vr.Ptr,&&arg_ldvr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_wr
+    NativeUtilities.freeA arg_wi
+    NativeUtilities.freeA2 arg_vl
+    NativeUtilities.freeA2 arg_vr
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgeev_: jobvl (argument 1)"
+   | -2  -> invalid_arg "dgeev_: jobvr (argument 2)"
+   | -3  -> invalid_arg "dgeev_: n (argument 3)"
+   | -4  -> invalid_arg "dgeev_: a (argument 4)"
+   | -5  -> invalid_arg "dgeev_: lda (argument 5)"
+   | -6  -> invalid_arg "dgeev_: wr (argument 6)"
+   | -7  -> invalid_arg "dgeev_: wi (argument 7)"
+   | -8  -> invalid_arg "dgeev_: vl (argument 8)"
+   | -9  -> invalid_arg "dgeev_: ldvl (argument 9)"
+   | -10 -> invalid_arg "dgeev_: vr (argument 10)"
+   | -11 -> invalid_arg "dgeev_: ldvr (argument 11)"
+   | -12 -> invalid_arg "dgeev_: work (argument 12)"
+   | -13 -> invalid_arg "dgeev_: lwork (argument 13)"
+   | -14 -> invalid_arg "dgeev_: info (argument 14)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgeev_ : returned %d. The computation failed." n)
+  // fixups
+  // result tuple
+  wr,wi,vr
+
+
+///Solve Cholesky
+ member this.dposv_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dposv_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dposv_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  let nrhs = NativeUtilities.matrixDim2 b in
+  // allocate results
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_uplo = 'U'
+  let mutable arg_n = n
+  let mutable arg_nrhs = nrhs
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackMKLStubs.dposv_(&&arg_uplo,&&arg_n,&&arg_nrhs,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dposv_: uplo (argument 1)"
+   | -2  -> invalid_arg "dposv_: n (argument 2)"
+   | -3  -> invalid_arg "dposv_: nrhs (argument 3)"
+   | -4  -> invalid_arg "dposv_: a (argument 4)"
+   | -5  -> invalid_arg "dposv_: lda (argument 5)"
+   | -6  -> invalid_arg "dposv_: b (argument 6)"
+   | -7  -> invalid_arg "dposv_: ldb (argument 7)"
+   | -8  -> invalid_arg "dposv_: info (argument 8)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dposv_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,b
+
+
+///Solve Upper
+ member this.dgels_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  NativeUtilities.assertDimensions "dgels_" ("(max m n)","Dim1(b)") ((max m n),NativeUtilities.matrixDim1 b);
+  let nrhs = NativeUtilities.matrixDim2 b in
+  // allocate results
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_transa = 'n'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let mutable arg_nrhs = nrhs
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max m (max 1 n)
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackMKLStubs.dgels_(&&arg_transa,&&arg_m,&&arg_n,&&arg_nrhs,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-10) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackMKLStubs.dgels_(&&arg_transa,&&arg_m,&&arg_n,&&arg_nrhs,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgels_: transa (argument 1)"
+   | -2  -> invalid_arg "dgels_: m (argument 2)"
+   | -3  -> invalid_arg "dgels_: n (argument 3)"
+   | -4  -> invalid_arg "dgels_: nrhs (argument 4)"
+   | -5  -> invalid_arg "dgels_: a (argument 5)"
+   | -6  -> invalid_arg "dgels_: lda (argument 6)"
+   | -7  -> invalid_arg "dgels_: b (argument 7)"
+   | -8  -> invalid_arg "dgels_: ldb (argument 8)"
+   | -9  -> invalid_arg "dgels_: work (argument 9)"
+   | -10 -> invalid_arg "dgels_: lwork (argument 10)"
+   | -11 -> invalid_arg "dgels_: info (argument 11)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgels_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,b
+
+
+///Eigen Value of Symetric Matrix
+ member this.dsyev_((jobz),(uplo),(a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dsyev_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  // allocate results
+  let w = Array.zeroCreate  (n)
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_jobz = jobz
+  let mutable arg_uplo = uplo
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_w = NativeUtilities.pinA w
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackMKLStubs.dsyev_(&&arg_jobz,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-8) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackMKLStubs.dsyev_(&&arg_jobz,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_w
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dsyev_: jobz (argument 1)"
+   | -2  -> invalid_arg "dsyev_: uplo (argument 2)"
+   | -3  -> invalid_arg "dsyev_: n (argument 3)"
+   | -4  -> invalid_arg "dsyev_: a (argument 4)"
+   | -5  -> invalid_arg "dsyev_: lda (argument 5)"
+   | -6  -> invalid_arg "dsyev_: w (argument 6)"
+   | -7  -> invalid_arg "dsyev_: work (argument 7)"
+   | -8  -> invalid_arg "dsyev_: lwork (argument 8)"
+   | -9  -> invalid_arg "dsyev_: info (argument 9)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dsyev_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a,w
+
+
+///Eigen Value of Symetric Matrix - Divide and Conquer
+ member this.dsyevd_((jobz),(uplo),(a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dsyevd_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  // allocate results
+  let w = Array.zeroCreate  (n)
+  let work = Array.zeroCreate  (1)
+  let iwork = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_jobz = jobz
+  let mutable arg_uplo = uplo
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_w = NativeUtilities.pinA w
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let arg_iwork = NativeUtilities.pinA iwork
+  let mutable arg_liwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackMKLStubs.dsyevd_(&&arg_jobz,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_liwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  if arg_info = 0   || arg_info=(-8)  || arg_info=(-10) then
+    arg_lwork <- int32 work.[0]
+    arg_liwork <-  iwork.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  let arg_iwork = NativeUtilities.pinA (Array.zeroCreate arg_liwork : int[])
+  // call function
+  try
+    LapackMKLStubs.dsyevd_(&&arg_jobz,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_liwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_w
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dsyevd_: jobz (argument 1)"
+   | -2  -> invalid_arg "dsyevd_: uplo (argument 2)"
+   | -3  -> invalid_arg "dsyevd_: n (argument 3)"
+   | -4  -> invalid_arg "dsyevd_: a (argument 4)"
+   | -5  -> invalid_arg "dsyevd_: lda (argument 5)"
+   | -6  -> invalid_arg "dsyevd_: w (argument 6)"
+   | -7  -> invalid_arg "dsyevd_: work (argument 7)"
+   | -8  -> invalid_arg "dsyevd_: lwork (argument 8)"
+   | -9  -> invalid_arg "dsyevd_: iwork (argument 9)"
+   | -10 -> invalid_arg "dsyevd_: liwork (argument 10)"
+   | -11 -> invalid_arg "dsyevd_: info (argument 11)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dsyevd_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a,w
+
+
+///Singular Value Decomposition
+ member this.dgesvd_((a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  // allocate results
+  let s = Array.zeroCreate  (min m n)
+  let u = Matrix.zero (m) (min m n)
+  let vt = Matrix.zero (n) (n)
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  let u = Matrix.transpose u
+  let vt = Matrix.transpose vt
+  // setup actuals
+  let mutable arg_jobu = 'A'
+  let mutable arg_jobvt = 'A'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_s = NativeUtilities.pinA s
+  let arg_u = NativeUtilities.pinM u
+  let mutable arg_ldu = m
+  let arg_vt = NativeUtilities.pinM vt
+  let mutable arg_ldvt = n
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackMKLStubs.dgesvd_(&&arg_jobu,&&arg_jobvt,&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_s.Ptr,arg_u.Ptr,&&arg_ldu,arg_vt.Ptr,&&arg_ldvt,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-13) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackMKLStubs.dgesvd_(&&arg_jobu,&&arg_jobvt,&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_s.Ptr,arg_u.Ptr,&&arg_ldu,arg_vt.Ptr,&&arg_ldvt,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_s
+    NativeUtilities.freeM arg_u
+    NativeUtilities.freeM arg_vt
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgesvd_: jobu (argument 1)"
+   | -2  -> invalid_arg "dgesvd_: jobvt (argument 2)"
+   | -3  -> invalid_arg "dgesvd_: m (argument 3)"
+   | -4  -> invalid_arg "dgesvd_: n (argument 4)"
+   | -5  -> invalid_arg "dgesvd_: a (argument 5)"
+   | -6  -> invalid_arg "dgesvd_: lda (argument 6)"
+   | -7  -> invalid_arg "dgesvd_: s (argument 7)"
+   | -8  -> invalid_arg "dgesvd_: u (argument 8)"
+   | -9  -> invalid_arg "dgesvd_: ldu (argument 9)"
+   | -10 -> invalid_arg "dgesvd_: vt (argument 10)"
+   | -11 -> invalid_arg "dgesvd_: ldvt (argument 11)"
+   | -12 -> invalid_arg "dgesvd_: work (argument 12)"
+   | -13 -> invalid_arg "dgesvd_: lwork (argument 13)"
+   | -14 -> invalid_arg "dgesvd_: info (argument 14)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgesvd_ : returned %d. The computation failed." n)
+  // fixups
+  let u = Matrix.transpose u
+  let vt = Matrix.transpose vt
+  // result tuple
+  s,u,vt
+
+
+///Singular Value Decomposition Divide- Conquer
+ member this.dgesdd_((a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  // allocate results
+  let s = Array.zeroCreate  (min m n)
+  let u = Matrix.zero (m) (m)
+  let vt = Matrix.zero (n) (n)
+  let work = Array.zeroCreate  (1)
+  let iwork = Array.zeroCreate  (8*(min m n))
+  // transpose
+  let a = Matrix.transpose a
+  let u = Matrix.transpose u
+  let vt = Matrix.transpose vt
+  // setup actuals
+  let mutable arg_JOBZ = 'A'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_s = NativeUtilities.pinA s
+  let arg_u = NativeUtilities.pinM u
+  let mutable arg_ldu = m
+  let arg_vt = NativeUtilities.pinM vt
+  let mutable arg_ldvt = n
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let arg_iwork = NativeUtilities.pinA iwork
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackMKLStubs.dgesdd_(&&arg_JOBZ,&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_s.Ptr,arg_u.Ptr,&&arg_ldu,arg_vt.Ptr,&&arg_ldvt,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-12) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackMKLStubs.dgesdd_(&&arg_JOBZ,&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_s.Ptr,arg_u.Ptr,&&arg_ldu,arg_vt.Ptr,&&arg_ldvt,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_s
+    NativeUtilities.freeM arg_u
+    NativeUtilities.freeM arg_vt
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgesdd_: JOBZ (argument 1)"
+   | -2  -> invalid_arg "dgesdd_: m (argument 2)"
+   | -3  -> invalid_arg "dgesdd_: n (argument 3)"
+   | -4  -> invalid_arg "dgesdd_: a (argument 4)"
+   | -5  -> invalid_arg "dgesdd_: lda (argument 5)"
+   | -6  -> invalid_arg "dgesdd_: s (argument 6)"
+   | -7  -> invalid_arg "dgesdd_: u (argument 7)"
+   | -8  -> invalid_arg "dgesdd_: ldu (argument 8)"
+   | -9  -> invalid_arg "dgesdd_: vt (argument 9)"
+   | -10 -> invalid_arg "dgesdd_: ldvt (argument 10)"
+   | -11 -> invalid_arg "dgesdd_: work (argument 11)"
+   | -12 -> invalid_arg "dgesdd_: lwork (argument 12)"
+   | -13 -> invalid_arg "dgesdd_: iwork (argument 13)"
+   | -14 -> invalid_arg "dgesdd_: info (argument 14)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgesdd_ : returned %d. The computation failed." n)
+  // fixups
+  let u = Matrix.transpose u
+  let vt = Matrix.transpose vt
+  // result tuple
+  s,u,vt
+
+
+///Single Value Decomposition for Symetric Matrices
+ member this.dsygv_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dsygv_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dsygv_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  NativeUtilities.assertDimensions "dsygv_" ("n","Dim2(b)") (n,NativeUtilities.matrixDim2 b);
+  // allocate results
+  let w = Array.zeroCreate  (n)
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_itype = 1
+  let mutable arg_JOBZ = 'V'
+  let mutable arg_uplo = 'U'
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let arg_w = NativeUtilities.pinA w
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackMKLStubs.dsygv_(&&arg_itype,&&arg_JOBZ,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-11) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackMKLStubs.dsygv_(&&arg_itype,&&arg_JOBZ,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeA arg_w
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dsygv_: itype (argument 1)"
+   | -2  -> invalid_arg "dsygv_: JOBZ (argument 2)"
+   | -3  -> invalid_arg "dsygv_: uplo (argument 3)"
+   | -4  -> invalid_arg "dsygv_: n (argument 4)"
+   | -5  -> invalid_arg "dsygv_: a (argument 5)"
+   | -6  -> invalid_arg "dsygv_: lda (argument 6)"
+   | -7  -> invalid_arg "dsygv_: b (argument 7)"
+   | -8  -> invalid_arg "dsygv_: ldb (argument 8)"
+   | -9  -> invalid_arg "dsygv_: w (argument 9)"
+   | -10 -> invalid_arg "dsygv_: work (argument 10)"
+   | -11 -> invalid_arg "dsygv_: lwork (argument 11)"
+   | -12 -> invalid_arg "dsygv_: info (argument 12)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dsygv_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,b,w
+
+
+///Single Value Decomposition for Symetric Matrices Divide and Conquer
+ member this.dsygvd_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dsygvd_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dsygvd_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  NativeUtilities.assertDimensions "dsygvd_" ("n","Dim2(b)") (n,NativeUtilities.matrixDim2 b);
+  // allocate results
+  let w = Array.zeroCreate  (n)
+  let work = Array.zeroCreate  (1)
+  let iwork = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_itype = 1
+  let mutable arg_JOBZ = 'V'
+  let mutable arg_uplo = 'U'
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let arg_w = NativeUtilities.pinA w
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let arg_iwork = NativeUtilities.pinA iwork
+  let mutable arg_liwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackMKLStubs.dsygvd_(&&arg_itype,&&arg_JOBZ,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_liwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  if arg_info = 0   || arg_info=(-11)  || arg_info=(-13) then
+    arg_lwork <- int32 work.[0]
+    arg_liwork <-  iwork.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  let arg_iwork = NativeUtilities.pinA (Array.zeroCreate arg_liwork : int[])
+  // call function
+  try
+    LapackMKLStubs.dsygvd_(&&arg_itype,&&arg_JOBZ,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_liwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeA arg_w
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dsygvd_: itype (argument 1)"
+   | -2  -> invalid_arg "dsygvd_: JOBZ (argument 2)"
+   | -3  -> invalid_arg "dsygvd_: uplo (argument 3)"
+   | -4  -> invalid_arg "dsygvd_: n (argument 4)"
+   | -5  -> invalid_arg "dsygvd_: a (argument 5)"
+   | -6  -> invalid_arg "dsygvd_: lda (argument 6)"
+   | -7  -> invalid_arg "dsygvd_: b (argument 7)"
+   | -8  -> invalid_arg "dsygvd_: ldb (argument 8)"
+   | -9  -> invalid_arg "dsygvd_: w (argument 9)"
+   | -10 -> invalid_arg "dsygvd_: work (argument 10)"
+   | -11 -> invalid_arg "dsygvd_: lwork (argument 11)"
+   | -12 -> invalid_arg "dsygvd_: iwork (argument 12)"
+   | -13 -> invalid_arg "dsygvd_: liwork (argument 13)"
+   | -14 -> invalid_arg "dsygvd_: info (argument 14)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dsygvd_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,b,w
+
+
+///LU factorization to compute the solution to a real  system of linear equations 
+ member this.dgesvx_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dgesvx_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dgesvx_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  let nrhs = NativeUtilities.matrixDim2 b in
+  // allocate results
+  let af = Matrix.zero (n) (n)
+  let ipiv = Array.zeroCreate  (n)
+  let r = Array.zeroCreate  (n)
+  let c = Array.zeroCreate  (n)
+  let x = Matrix.zero (n) (nrhs)
+  let ferr = Array.zeroCreate  (nrhs)
+  let berr = Array.zeroCreate  (nrhs)
+  let work = Array.zeroCreate  (4*n)
+  let iwork = Array.zeroCreate  (n)
+  // transpose
+  let a = Matrix.transpose a
+  let af = Matrix.transpose af
+  let b = Matrix.transpose b
+  let x = Matrix.transpose x
+  // setup actuals
+  let mutable arg_fact = 'E'
+  let mutable arg_transx = 'n'
+  let mutable arg_n = n
+  let mutable arg_nrhs = nrhs
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_af = NativeUtilities.pinM af
+  let mutable arg_ldaf = max 1 n
+  let arg_ipiv = NativeUtilities.pinA ipiv
+  let mutable arg_equed = 'n'
+  let arg_r = NativeUtilities.pinA r
+  let arg_c = NativeUtilities.pinA c
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let arg_x = NativeUtilities.pinM x
+  let mutable arg_ldx = max 1 n
+  let mutable arg_rcond = 0.0
+  let arg_ferr = NativeUtilities.pinA ferr
+  let arg_berr = NativeUtilities.pinA berr
+  let arg_work = NativeUtilities.pinA work
+  let arg_iwork = NativeUtilities.pinA iwork
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackMKLStubs.dgesvx_(&&arg_fact,&&arg_transx,&&arg_n,&&arg_nrhs,arg_a.Ptr,&&arg_lda,arg_af.Ptr,&&arg_ldaf,arg_ipiv.Ptr,&&arg_equed,arg_r.Ptr,arg_c.Ptr,arg_b.Ptr,&&arg_ldb,arg_x.Ptr,&&arg_ldx,&&arg_rcond,arg_ferr.Ptr,arg_berr.Ptr,arg_work.Ptr,arg_iwork.Ptr,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_af
+    NativeUtilities.freeA arg_ipiv
+    NativeUtilities.freeA arg_r
+    NativeUtilities.freeA arg_c
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeM arg_x
+    NativeUtilities.freeA arg_ferr
+    NativeUtilities.freeA arg_berr
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgesvx_: fact (argument 1)"
+   | -2  -> invalid_arg "dgesvx_: transx (argument 2)"
+   | -3  -> invalid_arg "dgesvx_: n (argument 3)"
+   | -4  -> invalid_arg "dgesvx_: nrhs (argument 4)"
+   | -5  -> invalid_arg "dgesvx_: a (argument 5)"
+   | -6  -> invalid_arg "dgesvx_: lda (argument 6)"
+   | -7  -> invalid_arg "dgesvx_: af (argument 7)"
+   | -8  -> invalid_arg "dgesvx_: ldaf (argument 8)"
+   | -9  -> invalid_arg "dgesvx_: ipiv (argument 9)"
+   | -10 -> invalid_arg "dgesvx_: equed (argument 10)"
+   | -11 -> invalid_arg "dgesvx_: r (argument 11)"
+   | -12 -> invalid_arg "dgesvx_: c (argument 12)"
+   | -13 -> invalid_arg "dgesvx_: b (argument 13)"
+   | -14 -> invalid_arg "dgesvx_: ldb (argument 14)"
+   | -15 -> invalid_arg "dgesvx_: x (argument 15)"
+   | -16 -> invalid_arg "dgesvx_: ldx (argument 16)"
+   | -17 -> invalid_arg "dgesvx_: rcond (argument 17)"
+   | -18 -> invalid_arg "dgesvx_: ferr (argument 18)"
+   | -19 -> invalid_arg "dgesvx_: berr (argument 19)"
+   | -20 -> invalid_arg "dgesvx_: work (argument 20)"
+   | -21 -> invalid_arg "dgesvx_: iwork (argument 21)"
+   | -22 -> invalid_arg "dgesvx_: info (argument 22)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgesvx_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let af = Matrix.transpose af
+  let b = Matrix.transpose b
+  let x = Matrix.transpose x
+  // result tuple
+  a,af,ipiv,arg_equed,r,c,b,x,arg_rcond,ferr,berr
+
+
+///Cholesky Factorisation - Expert
+ member this.dposvx_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dposvx_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dposvx_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  let nrhs = NativeUtilities.matrixDim2 b in
+  // allocate results
+  let af = Matrix.zero (n) (n)
+  let s = Array.zeroCreate  (n)
+  let x = Matrix.zero (n) (nrhs)
+  let ferr = Array.zeroCreate  (nrhs)
+  let berr = Array.zeroCreate  (nrhs)
+  let work = Array.zeroCreate  (3*n)
+  let iwork = Array.zeroCreate  (n)
+  // transpose
+  let a = Matrix.transpose a
+  let af = Matrix.transpose af
+  let b = Matrix.transpose b
+  let x = Matrix.transpose x
+  // setup actuals
+  let mutable arg_fact = 'E'
+  let mutable arg_uplo = 'U'
+  let mutable arg_n = n
+  let mutable arg_nrhs = nrhs
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_af = NativeUtilities.pinM af
+  let mutable arg_ldaf = max 1 n
+  let mutable arg_equed = 'n'
+  let arg_s = NativeUtilities.pinA s
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let arg_x = NativeUtilities.pinM x
+  let mutable arg_ldx = max 1 n
+  let mutable arg_rcond = 0.0
+  let arg_ferr = NativeUtilities.pinA ferr
+  let arg_berr = NativeUtilities.pinA berr
+  let arg_work = NativeUtilities.pinA work
+  let arg_iwork = NativeUtilities.pinA iwork
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackMKLStubs.dposvx_(&&arg_fact,&&arg_uplo,&&arg_n,&&arg_nrhs,arg_a.Ptr,&&arg_lda,arg_af.Ptr,&&arg_ldaf,&&arg_equed,arg_s.Ptr,arg_b.Ptr,&&arg_ldb,arg_x.Ptr,&&arg_ldx,&&arg_rcond,arg_ferr.Ptr,arg_berr.Ptr,arg_work.Ptr,arg_iwork.Ptr,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_af
+    NativeUtilities.freeA arg_s
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeM arg_x
+    NativeUtilities.freeA arg_ferr
+    NativeUtilities.freeA arg_berr
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dposvx_: fact (argument 1)"
+   | -2  -> invalid_arg "dposvx_: uplo (argument 2)"
+   | -3  -> invalid_arg "dposvx_: n (argument 3)"
+   | -4  -> invalid_arg "dposvx_: nrhs (argument 4)"
+   | -5  -> invalid_arg "dposvx_: a (argument 5)"
+   | -6  -> invalid_arg "dposvx_: lda (argument 6)"
+   | -7  -> invalid_arg "dposvx_: af (argument 7)"
+   | -8  -> invalid_arg "dposvx_: ldaf (argument 8)"
+   | -9  -> invalid_arg "dposvx_: equed (argument 9)"
+   | -10 -> invalid_arg "dposvx_: s (argument 10)"
+   | -11 -> invalid_arg "dposvx_: b (argument 11)"
+   | -12 -> invalid_arg "dposvx_: ldb (argument 12)"
+   | -13 -> invalid_arg "dposvx_: x (argument 13)"
+   | -14 -> invalid_arg "dposvx_: ldx (argument 14)"
+   | -15 -> invalid_arg "dposvx_: rcond (argument 15)"
+   | -16 -> invalid_arg "dposvx_: ferr (argument 16)"
+   | -17 -> invalid_arg "dposvx_: berr (argument 17)"
+   | -18 -> invalid_arg "dposvx_: work (argument 18)"
+   | -19 -> invalid_arg "dposvx_: iwork (argument 19)"
+   | -20 -> invalid_arg "dposvx_: info (argument 20)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dposvx_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let af = Matrix.transpose af
+  let b = Matrix.transpose b
+  let x = Matrix.transpose x
+  // result tuple
+  a,af,arg_equed,s,b,x,arg_rcond,ferr,berr
+
+
+///Cholesky factorisation of a real symmetric positive definite matrix
+ member this.dpotrf_((uplo),(a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dpotrf_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  // allocate results
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_uplo = uplo
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackMKLStubs.dpotrf_(&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dpotrf_: uplo (argument 1)"
+   | -2  -> invalid_arg "dpotrf_: n (argument 2)"
+   | -3  -> invalid_arg "dpotrf_: a (argument 3)"
+   | -4  -> invalid_arg "dpotrf_: lda (argument 4)"
+   | -5  -> invalid_arg "dpotrf_: info (argument 5)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dpotrf_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a
+
+
+///LU factorisation of general matrix using partial pivoting and row interchanges
+ member this.dgetrf_((a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  // allocate results
+  let ipiv = Array.zeroCreate  (min m n)
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_ipiv = NativeUtilities.pinA ipiv
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackMKLStubs.dgetrf_(&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_ipiv.Ptr,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_ipiv
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgetrf_: m (argument 1)"
+   | -2  -> invalid_arg "dgetrf_: n (argument 2)"
+   | -3  -> invalid_arg "dgetrf_: a (argument 3)"
+   | -4  -> invalid_arg "dgetrf_: lda (argument 4)"
+   | -5  -> invalid_arg "dgetrf_: ipiv (argument 5)"
+   | -6  -> invalid_arg "dgetrf_: info (argument 6)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgetrf_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a,ipiv
+
+
+///QR Factorisation
+ member this.dgeqrf_((a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  // allocate results
+  let tau = Array.zeroCreate  (min m n)
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_tau = NativeUtilities.pinA tau
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackMKLStubs.dgeqrf_(&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_tau.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-7) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackMKLStubs.dgeqrf_(&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_tau.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_tau
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgeqrf_: m (argument 1)"
+   | -2  -> invalid_arg "dgeqrf_: n (argument 2)"
+   | -3  -> invalid_arg "dgeqrf_: a (argument 3)"
+   | -4  -> invalid_arg "dgeqrf_: lda (argument 4)"
+   | -5  -> invalid_arg "dgeqrf_: tau (argument 5)"
+   | -6  -> invalid_arg "dgeqrf_: work (argument 6)"
+   | -7  -> invalid_arg "dgeqrf_: lwork (argument 7)"
+   | -8  -> invalid_arg "dgeqrf_: info (argument 8)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgeqrf_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a,tau
+
+
+///Matrix Vector Multiplication
+ member this.dgemv_((a:matrix),(x:vector)) = 
+  // input copies
+  let a = Matrix.copy a
+  let x = Vector.copy x
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  NativeUtilities.assertDimensions "dgemv_" ("n","Dim(x)") (n,NativeUtilities.vectorDim  x);
+  // allocate results
+  let y = Vector.zero (m)
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_trans = 'n'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let mutable arg_alpha = 1.0
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_x = NativeUtilities.pinV x
+  let mutable arg_incx = 1
+  let mutable arg_beta = 1.0
+  let arg_y = NativeUtilities.pinV y
+  let mutable arg_incx = 1
+  // call function
+  try
+    LapackMKLStubs.dgemv_(&&arg_trans,&&arg_m,&&arg_n,&&arg_alpha,arg_a.Ptr,&&arg_lda,arg_x.Ptr,&&arg_incx,&&arg_beta,arg_y.Ptr,&&arg_incx)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeV arg_x
+    NativeUtilities.freeV arg_y
+  // INFO
+  // fixups
+  // result tuple
+  y
+
+
+///EigenValues and Eigen Vectors for nonsymetruc matrices
+ member this.dggev_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dggev_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dggev_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  NativeUtilities.assertDimensions "dggev_" ("n","Dim2(b)") (n,NativeUtilities.matrixDim2 b);
+  // allocate results
+  let alphar = Array.zeroCreate  (n)
+  let alphai = Array.zeroCreate  (n)
+  let beta = Array.zeroCreate  (n)
+  let vl = Array2D.zeroCreate (n) (n)
+  let vr = Array2D.zeroCreate (n) (n)
+  let work = Array.zeroCreate  ((8*n))
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_jobvl = 'N'
+  let mutable arg_jobvr = 'V'
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let arg_alphar = NativeUtilities.pinA alphar
+  let arg_alphai = NativeUtilities.pinA alphai
+  let arg_beta = NativeUtilities.pinA beta
+  let arg_vl = NativeUtilities.pinA2 vl
+  let mutable arg_ldvl = n
+  let arg_vr = NativeUtilities.pinA2 vr
+  let mutable arg_ldvr = n
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = (8*n)
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackMKLStubs.dggev_(&&arg_jobvl,&&arg_jobvr,&&arg_n,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_alphar.Ptr,arg_alphai.Ptr,arg_beta.Ptr,arg_vl.Ptr,&&arg_ldvl,arg_vr.Ptr,&&arg_ldvr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeA arg_alphar
+    NativeUtilities.freeA arg_alphai
+    NativeUtilities.freeA arg_beta
+    NativeUtilities.freeA2 arg_vl
+    NativeUtilities.freeA2 arg_vr
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dggev_: jobvl (argument 1)"
+   | -2  -> invalid_arg "dggev_: jobvr (argument 2)"
+   | -3  -> invalid_arg "dggev_: n (argument 3)"
+   | -4  -> invalid_arg "dggev_: a (argument 4)"
+   | -5  -> invalid_arg "dggev_: lda (argument 5)"
+   | -6  -> invalid_arg "dggev_: b (argument 6)"
+   | -7  -> invalid_arg "dggev_: ldb (argument 7)"
+   | -8  -> invalid_arg "dggev_: alphar (argument 8)"
+   | -9  -> invalid_arg "dggev_: alphai (argument 9)"
+   | -10 -> invalid_arg "dggev_: beta (argument 10)"
+   | -11 -> invalid_arg "dggev_: vl (argument 11)"
+   | -12 -> invalid_arg "dggev_: ldvl (argument 12)"
+   | -13 -> invalid_arg "dggev_: vr (argument 13)"
+   | -14 -> invalid_arg "dggev_: ldvr (argument 14)"
+   | -15 -> invalid_arg "dggev_: work (argument 15)"
+   | -16 -> invalid_arg "dggev_: lwork (argument 16)"
+   | -17 -> invalid_arg "dggev_: info (argument 17)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dggev_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,b,alphar,alphai,beta,vr
+
+ end
+end
+module LapackMKL = begin
+ let MKLProvider = new Microsoft.FSharp.Math.Experimental.Provider<_>("MKL",[|"mkl_def.dll";"mkl_lapack.dll"|],fun () -> new LapackMKLService() :> ILapack)
+end
diff --git a/workyard/math-provider/lapack/lapack_service_mkl.fsi b/workyard/math-provider/lapack/lapack_service_mkl.fsi
new file mode 100755
index 0000000..1162c9d
--- /dev/null
+++ b/workyard/math-provider/lapack/lapack_service_mkl.fsi
@@ -0,0 +1,5 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Math.Bindings.Internals
+module LapackMKL =
+  val MKLProvider : Microsoft.FSharp.Math.Experimental.Provider<Microsoft.FSharp.Math.Bindings.Internals.ILapack>
+module LapackMKLStubs = begin end
diff --git a/workyard/math-provider/lapack/lapack_service_netlib.fs b/workyard/math-provider/lapack/lapack_service_netlib.fs
new file mode 100755
index 0000000..c2811c5
--- /dev/null
+++ b/workyard/math-provider/lapack/lapack_service_netlib.fs
@@ -0,0 +1,1345 @@
+namespace Microsoft.FSharp.Math.Bindings.Internals
+#nowarn "51"
+open Microsoft.FSharp.Math
+open Microsoft.FSharp.Math.Bindings.Internals
+/// Notice: This file generates bindings for netlib.org BLAS/LAPACK DLLs
+module LapackNetlibStubs = begin
+  [<System.Runtime.InteropServices.DllImport(@"blas.dll",EntryPoint="dgemm_")>]
+  extern void dgemm_(char *transa, char *transb, int *m, int *n, int *k, double *alpha, double *a, int *lda, double *b, int *ldb, double *beta, double *c, int *ldc);
+
+  [<System.Runtime.InteropServices.DllImport(@"blas.dll",EntryPoint="dtrsv_")>]
+  extern void dtrsv_(char *uplo,char *trans,char *diag,int *n,double *a,int *lda,double *x,int *incx);
+
+  [<System.Runtime.InteropServices.DllImport(@"blas.dll",EntryPoint="dtrsm_")>]
+  extern void dtrsm_(char *side,char *uplo,char *trans,char *diag,int *m,int *n,double *alpha,double *a,int *lda,double *b,int *ldb);   
+   
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dgesv_")>]
+  extern void dgesv_(int *n, int *nrhs, double *a, int *lda, int *ipiv, double *b, int *ldb, int *info);
+
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dgeev_")>]
+  extern void dgeev_(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *wr, double *wi, double *vl, int *ldvl, double *vr, int *ldvr, double *work, int *lwork, int *info);
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dposv_")>]
+  extern void dposv_(char *uplo, int *n, int *nrhs, double *a, int *lda, double *b, int *ldb, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dgels_")>]
+  extern void dgels_(char *trans, int *m,int *n, int *nrhs, double *a, int *lda, double *b, int *ldb, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dgglse_")>]
+  extern void dgglse_(int *m, int *n, int *p, double *a, int *lda, double *b, int *ldb, double *c, double *d, double *x, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dsyev_")>]
+  extern void dsyev_(char *jobz, char *uplo, int *n, double *a,int *lda, double *w, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dsyevd_")>]
+  extern void dsyevd_(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *iwork, int *liwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dgesvd_")>]
+  extern void dgesvd_(char *jobu, char *jobvt, int  *m, int *n, double *a, int *lda, double *s, double *u, int *ldu, double *vt, int *ldvt, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dgesdd_")>]
+  extern void dgesdd_(char *JOBZ, int  *m, int *n, double *a, int *lda, double *s, double *u, int *ldu, double *vt, int *ldvt, double *work, int *lwork,int *iwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dsygv_")>]
+  extern void dsygv_(int *itype, char *jobz, char *uplo, int *n, double *a, int *lda, double *b, int *ldb, double *w, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dsygvd_")>]     
+  extern void dsygvd_(int *itype, char *jobz, char *uplo, int *n, double *a, int *lda, double *b, int *ldb, double *w, double *work, int *lwork,int *iwork, int *liwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dggev_")>]     
+  extern void dggev_( char *jobvl, char *jobvr, int *n, double *a, int *lda, double *b, int *ldb, double *alphar, double *alphai,double *beta,double *vl,int *ldvl,double *vr,int *ldvr,double *work, int *lwork,int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dgesvx_")>]     
+  extern void dgesvx_(char *fact, char *trans, int *n, int *nrhs, double *a, int *lda, double *af, int *ldaf, int *ipiv, char *equed, double *r, double *c, double *b, int *ldb, double *x, int *ldx, double *rcond, double *ferr, double *berr, double *work, int *iwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dposvx_")>]     
+  extern void  dposvx_(char *fact, char *uplo, int *n, int *nrhs, double *a, int *lda, double *af, int *ldaf, char *equed, double *s, double *b, int *ldb, double *x, int *ldx, double *rcond, double  *ferr, double *berr, double *work, int *iwork, int *info);
+
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dpotrf_")>]     
+  extern void  dpotrf_(char *uplo, int *n, double *a, int *lda, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dgetrf_")>]     
+  extern void  dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"lapack.dll",EntryPoint="dgeqrf_")>]     
+  extern void dgeqrf_(int  *m, int *n, double *a, int *lda, double *tau, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"blas.dll",EntryPoint="dgemv_")>]
+  extern void dgemv_(char* trans, int* m, int* n,double* alpha, double* A, int* lda,double* x, int* incx, double* beta,double* y, int* incy);
+  
+end
+/// Internal provider of Lapack functionality, not for direct user usage.
+type LapackNetlibService() = class
+ interface ILapack with 
+///Matrix-Matrix Multiplication
+ member this.dgemm_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let k = NativeUtilities.matrixDim2 a in
+  NativeUtilities.assertDimensions "dgemm_" ("k","Dim1(b)") (k,NativeUtilities.matrixDim1 b);
+  let n = NativeUtilities.matrixDim2 b in
+  // allocate results
+  let c = Matrix.zero (m) (n)
+  // transpose
+  let c = Matrix.transpose c
+  // setup actuals
+  let mutable arg_transa = 't'
+  let mutable arg_transb = 't'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let mutable arg_k = k
+  let mutable arg_alpha = 1.0
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_ldk = k
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldn = n
+  let mutable arg_beta = 1.0
+  let arg_c = NativeUtilities.pinM c
+  let mutable arg_ldm = m
+  // call function
+  try
+    LapackNetlibStubs.dgemm_(&&arg_transa,&&arg_transb,&&arg_m,&&arg_n,&&arg_k,&&arg_alpha,arg_a.Ptr,&&arg_ldk,arg_b.Ptr,&&arg_ldn,&&arg_beta,arg_c.Ptr,&&arg_ldm)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeM arg_c
+  // INFO
+  // fixups
+  let c = Matrix.transpose c
+  // result tuple
+  c
+
+
+///Solve
+ member this.dgesv_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dgesv_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dgesv_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  let NRHS = NativeUtilities.matrixDim2 b in
+  // allocate results
+  let ipiv = Array.zeroCreate  (n)
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_n = n
+  let mutable arg_NRHS = NRHS
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_ipiv = NativeUtilities.pinA ipiv
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackNetlibStubs.dgesv_(&&arg_n,&&arg_NRHS,arg_a.Ptr,&&arg_lda,arg_ipiv.Ptr,arg_b.Ptr,&&arg_ldb,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_ipiv
+    NativeUtilities.freeM arg_b
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgesv_: n (argument 1)"
+   | -2  -> invalid_arg "dgesv_: NRHS (argument 2)"
+   | -3  -> invalid_arg "dgesv_: a (argument 3)"
+   | -4  -> invalid_arg "dgesv_: lda (argument 4)"
+   | -5  -> invalid_arg "dgesv_: ipiv (argument 5)"
+   | -6  -> invalid_arg "dgesv_: b (argument 6)"
+   | -7  -> invalid_arg "dgesv_: ldb (argument 7)"
+   | -8  -> invalid_arg "dgesv_: info (argument 8)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgesv_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,ipiv,b
+
+
+///Solve dtrsv
+ member this.dtrsv_((uplo),(a:matrix),(x:vector)) = 
+  // input copies
+  let a = Matrix.copy a
+  let x = Vector.copy x
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dtrsv_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dtrsv_" ("n","Dim(x)") (n,NativeUtilities.vectorDim  x);
+  // allocate results
+  // transpose
+  // setup actuals
+  let mutable arg_uplo = uplo
+  let mutable arg_transa = 't'
+  let mutable arg_diag = 'N'
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_x = NativeUtilities.pinV x
+  let mutable arg_incx = 1
+  // call function
+  try
+    LapackNetlibStubs.dtrsv_(&&arg_uplo,&&arg_transa,&&arg_diag,&&arg_n,arg_a.Ptr,&&arg_lda,arg_x.Ptr,&&arg_incx)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeV arg_x
+  // INFO
+  // fixups
+  // result tuple
+  x
+
+
+///Solve dtrsm
+ member this.dtrsm_((uplo),(a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let k = NativeUtilities.matrixDim2 a in
+  NativeUtilities.assertDimensions "dtrsm_" ("m","Dim1(b)") (m,NativeUtilities.matrixDim1 b);
+  let n = NativeUtilities.matrixDim2 b in
+  // allocate results
+  // transpose
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_side = 'L'
+  let mutable arg_uplo = uplo
+  let mutable arg_transa = 't'
+  let mutable arg_diag = 'N'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let mutable arg_alpha = 1.0
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = m
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = m
+  // call function
+  try
+    LapackNetlibStubs.dtrsm_(&&arg_side,&&arg_uplo,&&arg_transa,&&arg_diag,&&arg_m,&&arg_n,&&arg_alpha,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+  // INFO
+  // fixups
+  let b = Matrix.transpose b
+  // result tuple
+  b
+
+
+///Solve LSE using GRQ
+ member this.dgglse_((a:matrix),(b:matrix),(c:vector),(d:vector)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  let c = Vector.copy c
+  let d = Vector.copy d
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  let p = NativeUtilities.matrixDim1 b in
+  NativeUtilities.assertDimensions "dgglse_" ("n","Dim2(b)") (n,NativeUtilities.matrixDim2 b);
+  NativeUtilities.assertDimensions "dgglse_" ("m","Dim(c)") (m,NativeUtilities.vectorDim  c);
+  NativeUtilities.assertDimensions "dgglse_" ("p","Dim(d)") (p,NativeUtilities.vectorDim  d);
+  // allocate results
+  let x = Array.zeroCreate  (n)
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let mutable arg_p = p
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 p
+  let arg_c = NativeUtilities.pinV c
+  let arg_d = NativeUtilities.pinV d
+  let arg_x = NativeUtilities.pinA x
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackNetlibStubs.dgglse_(&&arg_m,&&arg_n,&&arg_p,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_c.Ptr,arg_d.Ptr,arg_x.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-12) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackNetlibStubs.dgglse_(&&arg_m,&&arg_n,&&arg_p,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_c.Ptr,arg_d.Ptr,arg_x.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeV arg_c
+    NativeUtilities.freeV arg_d
+    NativeUtilities.freeA arg_x
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgglse_: m (argument 1)"
+   | -2  -> invalid_arg "dgglse_: n (argument 2)"
+   | -3  -> invalid_arg "dgglse_: p (argument 3)"
+   | -4  -> invalid_arg "dgglse_: a (argument 4)"
+   | -5  -> invalid_arg "dgglse_: lda (argument 5)"
+   | -6  -> invalid_arg "dgglse_: b (argument 6)"
+   | -7  -> invalid_arg "dgglse_: ldb (argument 7)"
+   | -8  -> invalid_arg "dgglse_: c (argument 8)"
+   | -9  -> invalid_arg "dgglse_: d (argument 9)"
+   | -10 -> invalid_arg "dgglse_: x (argument 10)"
+   | -11 -> invalid_arg "dgglse_: work (argument 11)"
+   | -12 -> invalid_arg "dgglse_: lwork (argument 12)"
+   | -13 -> invalid_arg "dgglse_: info (argument 13)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgglse_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a,c,x
+
+
+///EigenValue Non-Symetrix
+ member this.dgeev_((jobvr),(a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dgeev_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  // allocate results
+  let wr = Array.zeroCreate  (n)
+  let wi = Array.zeroCreate  (n)
+  let vl = Array2D.zeroCreate (n) (n)
+  let vr = Array2D.zeroCreate (n) (n)
+  let work = Array.zeroCreate  ((4*n))
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_jobvl = 'N'
+  let mutable arg_jobvr = jobvr
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = n
+  let arg_wr = NativeUtilities.pinA wr
+  let arg_wi = NativeUtilities.pinA wi
+  let arg_vl = NativeUtilities.pinA2 vl
+  let mutable arg_ldvl = n
+  let arg_vr = NativeUtilities.pinA2 vr
+  let mutable arg_ldvr = n
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = (4*n)
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackNetlibStubs.dgeev_(&&arg_jobvl,&&arg_jobvr,&&arg_n,arg_a.Ptr,&&arg_lda,arg_wr.Ptr,arg_wi.Ptr,arg_vl.Ptr,&&arg_ldvl,arg_vr.Ptr,&&arg_ldvr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_wr
+    NativeUtilities.freeA arg_wi
+    NativeUtilities.freeA2 arg_vl
+    NativeUtilities.freeA2 arg_vr
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgeev_: jobvl (argument 1)"
+   | -2  -> invalid_arg "dgeev_: jobvr (argument 2)"
+   | -3  -> invalid_arg "dgeev_: n (argument 3)"
+   | -4  -> invalid_arg "dgeev_: a (argument 4)"
+   | -5  -> invalid_arg "dgeev_: lda (argument 5)"
+   | -6  -> invalid_arg "dgeev_: wr (argument 6)"
+   | -7  -> invalid_arg "dgeev_: wi (argument 7)"
+   | -8  -> invalid_arg "dgeev_: vl (argument 8)"
+   | -9  -> invalid_arg "dgeev_: ldvl (argument 9)"
+   | -10 -> invalid_arg "dgeev_: vr (argument 10)"
+   | -11 -> invalid_arg "dgeev_: ldvr (argument 11)"
+   | -12 -> invalid_arg "dgeev_: work (argument 12)"
+   | -13 -> invalid_arg "dgeev_: lwork (argument 13)"
+   | -14 -> invalid_arg "dgeev_: info (argument 14)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgeev_ : returned %d. The computation failed." n)
+  // fixups
+  // result tuple
+  wr,wi,vr
+
+
+///Solve Cholesky
+ member this.dposv_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dposv_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dposv_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  let nrhs = NativeUtilities.matrixDim2 b in
+  // allocate results
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_uplo = 'U'
+  let mutable arg_n = n
+  let mutable arg_nrhs = nrhs
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackNetlibStubs.dposv_(&&arg_uplo,&&arg_n,&&arg_nrhs,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dposv_: uplo (argument 1)"
+   | -2  -> invalid_arg "dposv_: n (argument 2)"
+   | -3  -> invalid_arg "dposv_: nrhs (argument 3)"
+   | -4  -> invalid_arg "dposv_: a (argument 4)"
+   | -5  -> invalid_arg "dposv_: lda (argument 5)"
+   | -6  -> invalid_arg "dposv_: b (argument 6)"
+   | -7  -> invalid_arg "dposv_: ldb (argument 7)"
+   | -8  -> invalid_arg "dposv_: info (argument 8)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dposv_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,b
+
+
+///Solve Upper
+ member this.dgels_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  NativeUtilities.assertDimensions "dgels_" ("(max m n)","Dim1(b)") ((max m n),NativeUtilities.matrixDim1 b);
+  let nrhs = NativeUtilities.matrixDim2 b in
+  // allocate results
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_transa = 'n'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let mutable arg_nrhs = nrhs
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max m (max 1 n)
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackNetlibStubs.dgels_(&&arg_transa,&&arg_m,&&arg_n,&&arg_nrhs,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-10) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackNetlibStubs.dgels_(&&arg_transa,&&arg_m,&&arg_n,&&arg_nrhs,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgels_: transa (argument 1)"
+   | -2  -> invalid_arg "dgels_: m (argument 2)"
+   | -3  -> invalid_arg "dgels_: n (argument 3)"
+   | -4  -> invalid_arg "dgels_: nrhs (argument 4)"
+   | -5  -> invalid_arg "dgels_: a (argument 5)"
+   | -6  -> invalid_arg "dgels_: lda (argument 6)"
+   | -7  -> invalid_arg "dgels_: b (argument 7)"
+   | -8  -> invalid_arg "dgels_: ldb (argument 8)"
+   | -9  -> invalid_arg "dgels_: work (argument 9)"
+   | -10 -> invalid_arg "dgels_: lwork (argument 10)"
+   | -11 -> invalid_arg "dgels_: info (argument 11)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgels_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,b
+
+
+///Eigen Value of Symetric Matrix
+ member this.dsyev_((jobz),(uplo),(a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dsyev_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  // allocate results
+  let w = Array.zeroCreate  (n)
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_jobz = jobz
+  let mutable arg_uplo = uplo
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_w = NativeUtilities.pinA w
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackNetlibStubs.dsyev_(&&arg_jobz,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-8) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackNetlibStubs.dsyev_(&&arg_jobz,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_w
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dsyev_: jobz (argument 1)"
+   | -2  -> invalid_arg "dsyev_: uplo (argument 2)"
+   | -3  -> invalid_arg "dsyev_: n (argument 3)"
+   | -4  -> invalid_arg "dsyev_: a (argument 4)"
+   | -5  -> invalid_arg "dsyev_: lda (argument 5)"
+   | -6  -> invalid_arg "dsyev_: w (argument 6)"
+   | -7  -> invalid_arg "dsyev_: work (argument 7)"
+   | -8  -> invalid_arg "dsyev_: lwork (argument 8)"
+   | -9  -> invalid_arg "dsyev_: info (argument 9)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dsyev_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a,w
+
+
+///Eigen Value of Symetric Matrix - Divide and Conquer
+ member this.dsyevd_((jobz),(uplo),(a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dsyevd_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  // allocate results
+  let w = Array.zeroCreate  (n)
+  let work = Array.zeroCreate  (1)
+  let iwork = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_jobz = jobz
+  let mutable arg_uplo = uplo
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_w = NativeUtilities.pinA w
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let arg_iwork = NativeUtilities.pinA iwork
+  let mutable arg_liwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackNetlibStubs.dsyevd_(&&arg_jobz,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_liwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  if arg_info = 0   || arg_info=(-8)  || arg_info=(-10) then
+    arg_lwork <- int32 work.[0]
+    arg_liwork <-  iwork.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  let arg_iwork = NativeUtilities.pinA (Array.zeroCreate arg_liwork : int[])
+  // call function
+  try
+    LapackNetlibStubs.dsyevd_(&&arg_jobz,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_liwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_w
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dsyevd_: jobz (argument 1)"
+   | -2  -> invalid_arg "dsyevd_: uplo (argument 2)"
+   | -3  -> invalid_arg "dsyevd_: n (argument 3)"
+   | -4  -> invalid_arg "dsyevd_: a (argument 4)"
+   | -5  -> invalid_arg "dsyevd_: lda (argument 5)"
+   | -6  -> invalid_arg "dsyevd_: w (argument 6)"
+   | -7  -> invalid_arg "dsyevd_: work (argument 7)"
+   | -8  -> invalid_arg "dsyevd_: lwork (argument 8)"
+   | -9  -> invalid_arg "dsyevd_: iwork (argument 9)"
+   | -10 -> invalid_arg "dsyevd_: liwork (argument 10)"
+   | -11 -> invalid_arg "dsyevd_: info (argument 11)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dsyevd_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a,w
+
+
+///Singular Value Decomposition
+ member this.dgesvd_((a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  // allocate results
+  let s = Array.zeroCreate  (min m n)
+  let u = Matrix.zero (m) (min m n)
+  let vt = Matrix.zero (n) (n)
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  let u = Matrix.transpose u
+  let vt = Matrix.transpose vt
+  // setup actuals
+  let mutable arg_jobu = 'A'
+  let mutable arg_jobvt = 'A'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_s = NativeUtilities.pinA s
+  let arg_u = NativeUtilities.pinM u
+  let mutable arg_ldu = m
+  let arg_vt = NativeUtilities.pinM vt
+  let mutable arg_ldvt = n
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackNetlibStubs.dgesvd_(&&arg_jobu,&&arg_jobvt,&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_s.Ptr,arg_u.Ptr,&&arg_ldu,arg_vt.Ptr,&&arg_ldvt,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-13) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackNetlibStubs.dgesvd_(&&arg_jobu,&&arg_jobvt,&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_s.Ptr,arg_u.Ptr,&&arg_ldu,arg_vt.Ptr,&&arg_ldvt,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_s
+    NativeUtilities.freeM arg_u
+    NativeUtilities.freeM arg_vt
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgesvd_: jobu (argument 1)"
+   | -2  -> invalid_arg "dgesvd_: jobvt (argument 2)"
+   | -3  -> invalid_arg "dgesvd_: m (argument 3)"
+   | -4  -> invalid_arg "dgesvd_: n (argument 4)"
+   | -5  -> invalid_arg "dgesvd_: a (argument 5)"
+   | -6  -> invalid_arg "dgesvd_: lda (argument 6)"
+   | -7  -> invalid_arg "dgesvd_: s (argument 7)"
+   | -8  -> invalid_arg "dgesvd_: u (argument 8)"
+   | -9  -> invalid_arg "dgesvd_: ldu (argument 9)"
+   | -10 -> invalid_arg "dgesvd_: vt (argument 10)"
+   | -11 -> invalid_arg "dgesvd_: ldvt (argument 11)"
+   | -12 -> invalid_arg "dgesvd_: work (argument 12)"
+   | -13 -> invalid_arg "dgesvd_: lwork (argument 13)"
+   | -14 -> invalid_arg "dgesvd_: info (argument 14)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgesvd_ : returned %d. The computation failed." n)
+  // fixups
+  let u = Matrix.transpose u
+  let vt = Matrix.transpose vt
+  // result tuple
+  s,u,vt
+
+
+///Singular Value Decomposition Divide- Conquer
+ member this.dgesdd_((a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  // allocate results
+  let s = Array.zeroCreate  (min m n)
+  let u = Matrix.zero (m) (m)
+  let vt = Matrix.zero (n) (n)
+  let work = Array.zeroCreate  (1)
+  let iwork = Array.zeroCreate  (8*(min m n))
+  // transpose
+  let a = Matrix.transpose a
+  let u = Matrix.transpose u
+  let vt = Matrix.transpose vt
+  // setup actuals
+  let mutable arg_JOBZ = 'A'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_s = NativeUtilities.pinA s
+  let arg_u = NativeUtilities.pinM u
+  let mutable arg_ldu = m
+  let arg_vt = NativeUtilities.pinM vt
+  let mutable arg_ldvt = n
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let arg_iwork = NativeUtilities.pinA iwork
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackNetlibStubs.dgesdd_(&&arg_JOBZ,&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_s.Ptr,arg_u.Ptr,&&arg_ldu,arg_vt.Ptr,&&arg_ldvt,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-12) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackNetlibStubs.dgesdd_(&&arg_JOBZ,&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_s.Ptr,arg_u.Ptr,&&arg_ldu,arg_vt.Ptr,&&arg_ldvt,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_s
+    NativeUtilities.freeM arg_u
+    NativeUtilities.freeM arg_vt
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgesdd_: JOBZ (argument 1)"
+   | -2  -> invalid_arg "dgesdd_: m (argument 2)"
+   | -3  -> invalid_arg "dgesdd_: n (argument 3)"
+   | -4  -> invalid_arg "dgesdd_: a (argument 4)"
+   | -5  -> invalid_arg "dgesdd_: lda (argument 5)"
+   | -6  -> invalid_arg "dgesdd_: s (argument 6)"
+   | -7  -> invalid_arg "dgesdd_: u (argument 7)"
+   | -8  -> invalid_arg "dgesdd_: ldu (argument 8)"
+   | -9  -> invalid_arg "dgesdd_: vt (argument 9)"
+   | -10 -> invalid_arg "dgesdd_: ldvt (argument 10)"
+   | -11 -> invalid_arg "dgesdd_: work (argument 11)"
+   | -12 -> invalid_arg "dgesdd_: lwork (argument 12)"
+   | -13 -> invalid_arg "dgesdd_: iwork (argument 13)"
+   | -14 -> invalid_arg "dgesdd_: info (argument 14)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgesdd_ : returned %d. The computation failed." n)
+  // fixups
+  let u = Matrix.transpose u
+  let vt = Matrix.transpose vt
+  // result tuple
+  s,u,vt
+
+
+///Single Value Decomposition for Symetric Matrices
+ member this.dsygv_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dsygv_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dsygv_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  NativeUtilities.assertDimensions "dsygv_" ("n","Dim2(b)") (n,NativeUtilities.matrixDim2 b);
+  // allocate results
+  let w = Array.zeroCreate  (n)
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_itype = 1
+  let mutable arg_JOBZ = 'V'
+  let mutable arg_uplo = 'U'
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let arg_w = NativeUtilities.pinA w
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackNetlibStubs.dsygv_(&&arg_itype,&&arg_JOBZ,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-11) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackNetlibStubs.dsygv_(&&arg_itype,&&arg_JOBZ,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeA arg_w
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dsygv_: itype (argument 1)"
+   | -2  -> invalid_arg "dsygv_: JOBZ (argument 2)"
+   | -3  -> invalid_arg "dsygv_: uplo (argument 3)"
+   | -4  -> invalid_arg "dsygv_: n (argument 4)"
+   | -5  -> invalid_arg "dsygv_: a (argument 5)"
+   | -6  -> invalid_arg "dsygv_: lda (argument 6)"
+   | -7  -> invalid_arg "dsygv_: b (argument 7)"
+   | -8  -> invalid_arg "dsygv_: ldb (argument 8)"
+   | -9  -> invalid_arg "dsygv_: w (argument 9)"
+   | -10 -> invalid_arg "dsygv_: work (argument 10)"
+   | -11 -> invalid_arg "dsygv_: lwork (argument 11)"
+   | -12 -> invalid_arg "dsygv_: info (argument 12)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dsygv_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,b,w
+
+
+///Single Value Decomposition for Symetric Matrices Divide and Conquer
+ member this.dsygvd_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dsygvd_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dsygvd_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  NativeUtilities.assertDimensions "dsygvd_" ("n","Dim2(b)") (n,NativeUtilities.matrixDim2 b);
+  // allocate results
+  let w = Array.zeroCreate  (n)
+  let work = Array.zeroCreate  (1)
+  let iwork = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_itype = 1
+  let mutable arg_JOBZ = 'V'
+  let mutable arg_uplo = 'U'
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let arg_w = NativeUtilities.pinA w
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let arg_iwork = NativeUtilities.pinA iwork
+  let mutable arg_liwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackNetlibStubs.dsygvd_(&&arg_itype,&&arg_JOBZ,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_liwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  if arg_info = 0   || arg_info=(-11)  || arg_info=(-13) then
+    arg_lwork <- int32 work.[0]
+    arg_liwork <-  iwork.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  let arg_iwork = NativeUtilities.pinA (Array.zeroCreate arg_liwork : int[])
+  // call function
+  try
+    LapackNetlibStubs.dsygvd_(&&arg_itype,&&arg_JOBZ,&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_w.Ptr,arg_work.Ptr,&&arg_lwork,arg_iwork.Ptr,&&arg_liwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeA arg_w
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dsygvd_: itype (argument 1)"
+   | -2  -> invalid_arg "dsygvd_: JOBZ (argument 2)"
+   | -3  -> invalid_arg "dsygvd_: uplo (argument 3)"
+   | -4  -> invalid_arg "dsygvd_: n (argument 4)"
+   | -5  -> invalid_arg "dsygvd_: a (argument 5)"
+   | -6  -> invalid_arg "dsygvd_: lda (argument 6)"
+   | -7  -> invalid_arg "dsygvd_: b (argument 7)"
+   | -8  -> invalid_arg "dsygvd_: ldb (argument 8)"
+   | -9  -> invalid_arg "dsygvd_: w (argument 9)"
+   | -10 -> invalid_arg "dsygvd_: work (argument 10)"
+   | -11 -> invalid_arg "dsygvd_: lwork (argument 11)"
+   | -12 -> invalid_arg "dsygvd_: iwork (argument 12)"
+   | -13 -> invalid_arg "dsygvd_: liwork (argument 13)"
+   | -14 -> invalid_arg "dsygvd_: info (argument 14)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dsygvd_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,b,w
+
+
+///LU factorization to compute the solution to a real  system of linear equations 
+ member this.dgesvx_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dgesvx_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dgesvx_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  let nrhs = NativeUtilities.matrixDim2 b in
+  // allocate results
+  let af = Matrix.zero (n) (n)
+  let ipiv = Array.zeroCreate  (n)
+  let r = Array.zeroCreate  (n)
+  let c = Array.zeroCreate  (n)
+  let x = Matrix.zero (n) (nrhs)
+  let ferr = Array.zeroCreate  (nrhs)
+  let berr = Array.zeroCreate  (nrhs)
+  let work = Array.zeroCreate  (4*n)
+  let iwork = Array.zeroCreate  (n)
+  // transpose
+  let a = Matrix.transpose a
+  let af = Matrix.transpose af
+  let b = Matrix.transpose b
+  let x = Matrix.transpose x
+  // setup actuals
+  let mutable arg_fact = 'E'
+  let mutable arg_transx = 'n'
+  let mutable arg_n = n
+  let mutable arg_nrhs = nrhs
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_af = NativeUtilities.pinM af
+  let mutable arg_ldaf = max 1 n
+  let arg_ipiv = NativeUtilities.pinA ipiv
+  let mutable arg_equed = 'n'
+  let arg_r = NativeUtilities.pinA r
+  let arg_c = NativeUtilities.pinA c
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let arg_x = NativeUtilities.pinM x
+  let mutable arg_ldx = max 1 n
+  let mutable arg_rcond = 0.0
+  let arg_ferr = NativeUtilities.pinA ferr
+  let arg_berr = NativeUtilities.pinA berr
+  let arg_work = NativeUtilities.pinA work
+  let arg_iwork = NativeUtilities.pinA iwork
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackNetlibStubs.dgesvx_(&&arg_fact,&&arg_transx,&&arg_n,&&arg_nrhs,arg_a.Ptr,&&arg_lda,arg_af.Ptr,&&arg_ldaf,arg_ipiv.Ptr,&&arg_equed,arg_r.Ptr,arg_c.Ptr,arg_b.Ptr,&&arg_ldb,arg_x.Ptr,&&arg_ldx,&&arg_rcond,arg_ferr.Ptr,arg_berr.Ptr,arg_work.Ptr,arg_iwork.Ptr,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_af
+    NativeUtilities.freeA arg_ipiv
+    NativeUtilities.freeA arg_r
+    NativeUtilities.freeA arg_c
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeM arg_x
+    NativeUtilities.freeA arg_ferr
+    NativeUtilities.freeA arg_berr
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgesvx_: fact (argument 1)"
+   | -2  -> invalid_arg "dgesvx_: transx (argument 2)"
+   | -3  -> invalid_arg "dgesvx_: n (argument 3)"
+   | -4  -> invalid_arg "dgesvx_: nrhs (argument 4)"
+   | -5  -> invalid_arg "dgesvx_: a (argument 5)"
+   | -6  -> invalid_arg "dgesvx_: lda (argument 6)"
+   | -7  -> invalid_arg "dgesvx_: af (argument 7)"
+   | -8  -> invalid_arg "dgesvx_: ldaf (argument 8)"
+   | -9  -> invalid_arg "dgesvx_: ipiv (argument 9)"
+   | -10 -> invalid_arg "dgesvx_: equed (argument 10)"
+   | -11 -> invalid_arg "dgesvx_: r (argument 11)"
+   | -12 -> invalid_arg "dgesvx_: c (argument 12)"
+   | -13 -> invalid_arg "dgesvx_: b (argument 13)"
+   | -14 -> invalid_arg "dgesvx_: ldb (argument 14)"
+   | -15 -> invalid_arg "dgesvx_: x (argument 15)"
+   | -16 -> invalid_arg "dgesvx_: ldx (argument 16)"
+   | -17 -> invalid_arg "dgesvx_: rcond (argument 17)"
+   | -18 -> invalid_arg "dgesvx_: ferr (argument 18)"
+   | -19 -> invalid_arg "dgesvx_: berr (argument 19)"
+   | -20 -> invalid_arg "dgesvx_: work (argument 20)"
+   | -21 -> invalid_arg "dgesvx_: iwork (argument 21)"
+   | -22 -> invalid_arg "dgesvx_: info (argument 22)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgesvx_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let af = Matrix.transpose af
+  let b = Matrix.transpose b
+  let x = Matrix.transpose x
+  // result tuple
+  a,af,ipiv,arg_equed,r,c,b,x,arg_rcond,ferr,berr
+
+
+///Cholesky Factorisation - Expert
+ member this.dposvx_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dposvx_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dposvx_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  let nrhs = NativeUtilities.matrixDim2 b in
+  // allocate results
+  let af = Matrix.zero (n) (n)
+  let s = Array.zeroCreate  (n)
+  let x = Matrix.zero (n) (nrhs)
+  let ferr = Array.zeroCreate  (nrhs)
+  let berr = Array.zeroCreate  (nrhs)
+  let work = Array.zeroCreate  (3*n)
+  let iwork = Array.zeroCreate  (n)
+  // transpose
+  let a = Matrix.transpose a
+  let af = Matrix.transpose af
+  let b = Matrix.transpose b
+  let x = Matrix.transpose x
+  // setup actuals
+  let mutable arg_fact = 'E'
+  let mutable arg_uplo = 'U'
+  let mutable arg_n = n
+  let mutable arg_nrhs = nrhs
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_af = NativeUtilities.pinM af
+  let mutable arg_ldaf = max 1 n
+  let mutable arg_equed = 'n'
+  let arg_s = NativeUtilities.pinA s
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let arg_x = NativeUtilities.pinM x
+  let mutable arg_ldx = max 1 n
+  let mutable arg_rcond = 0.0
+  let arg_ferr = NativeUtilities.pinA ferr
+  let arg_berr = NativeUtilities.pinA berr
+  let arg_work = NativeUtilities.pinA work
+  let arg_iwork = NativeUtilities.pinA iwork
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackNetlibStubs.dposvx_(&&arg_fact,&&arg_uplo,&&arg_n,&&arg_nrhs,arg_a.Ptr,&&arg_lda,arg_af.Ptr,&&arg_ldaf,&&arg_equed,arg_s.Ptr,arg_b.Ptr,&&arg_ldb,arg_x.Ptr,&&arg_ldx,&&arg_rcond,arg_ferr.Ptr,arg_berr.Ptr,arg_work.Ptr,arg_iwork.Ptr,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_af
+    NativeUtilities.freeA arg_s
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeM arg_x
+    NativeUtilities.freeA arg_ferr
+    NativeUtilities.freeA arg_berr
+    NativeUtilities.freeA arg_work
+    NativeUtilities.freeA arg_iwork
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dposvx_: fact (argument 1)"
+   | -2  -> invalid_arg "dposvx_: uplo (argument 2)"
+   | -3  -> invalid_arg "dposvx_: n (argument 3)"
+   | -4  -> invalid_arg "dposvx_: nrhs (argument 4)"
+   | -5  -> invalid_arg "dposvx_: a (argument 5)"
+   | -6  -> invalid_arg "dposvx_: lda (argument 6)"
+   | -7  -> invalid_arg "dposvx_: af (argument 7)"
+   | -8  -> invalid_arg "dposvx_: ldaf (argument 8)"
+   | -9  -> invalid_arg "dposvx_: equed (argument 9)"
+   | -10 -> invalid_arg "dposvx_: s (argument 10)"
+   | -11 -> invalid_arg "dposvx_: b (argument 11)"
+   | -12 -> invalid_arg "dposvx_: ldb (argument 12)"
+   | -13 -> invalid_arg "dposvx_: x (argument 13)"
+   | -14 -> invalid_arg "dposvx_: ldx (argument 14)"
+   | -15 -> invalid_arg "dposvx_: rcond (argument 15)"
+   | -16 -> invalid_arg "dposvx_: ferr (argument 16)"
+   | -17 -> invalid_arg "dposvx_: berr (argument 17)"
+   | -18 -> invalid_arg "dposvx_: work (argument 18)"
+   | -19 -> invalid_arg "dposvx_: iwork (argument 19)"
+   | -20 -> invalid_arg "dposvx_: info (argument 20)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dposvx_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let af = Matrix.transpose af
+  let b = Matrix.transpose b
+  let x = Matrix.transpose x
+  // result tuple
+  a,af,arg_equed,s,b,x,arg_rcond,ferr,berr
+
+
+///Cholesky factorisation of a real symmetric positive definite matrix
+ member this.dpotrf_((uplo),(a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dpotrf_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  // allocate results
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_uplo = uplo
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackNetlibStubs.dpotrf_(&&arg_uplo,&&arg_n,arg_a.Ptr,&&arg_lda,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dpotrf_: uplo (argument 1)"
+   | -2  -> invalid_arg "dpotrf_: n (argument 2)"
+   | -3  -> invalid_arg "dpotrf_: a (argument 3)"
+   | -4  -> invalid_arg "dpotrf_: lda (argument 4)"
+   | -5  -> invalid_arg "dpotrf_: info (argument 5)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dpotrf_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a
+
+
+///LU factorisation of general matrix using partial pivoting and row interchanges
+ member this.dgetrf_((a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  // allocate results
+  let ipiv = Array.zeroCreate  (min m n)
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_ipiv = NativeUtilities.pinA ipiv
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackNetlibStubs.dgetrf_(&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_ipiv.Ptr,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_ipiv
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgetrf_: m (argument 1)"
+   | -2  -> invalid_arg "dgetrf_: n (argument 2)"
+   | -3  -> invalid_arg "dgetrf_: a (argument 3)"
+   | -4  -> invalid_arg "dgetrf_: lda (argument 4)"
+   | -5  -> invalid_arg "dgetrf_: ipiv (argument 5)"
+   | -6  -> invalid_arg "dgetrf_: info (argument 6)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgetrf_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a,ipiv
+
+
+///QR Factorisation
+ member this.dgeqrf_((a:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  // allocate results
+  let tau = Array.zeroCreate  (min m n)
+  let work = Array.zeroCreate  (1)
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_tau = NativeUtilities.pinA tau
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = -1
+  let mutable arg_info = 0
+  // ask for work array size
+  try
+    LapackNetlibStubs.dgeqrf_(&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_tau.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeA arg_work
+  if arg_info = 0   || arg_info=(-7) then
+    arg_lwork <- int32 work.[0]
+  else assert(false)
+  let arg_work = NativeUtilities.pinA (Array.zeroCreate arg_lwork : float[])
+  // call function
+  try
+    LapackNetlibStubs.dgeqrf_(&&arg_m,&&arg_n,arg_a.Ptr,&&arg_lda,arg_tau.Ptr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeA arg_tau
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dgeqrf_: m (argument 1)"
+   | -2  -> invalid_arg "dgeqrf_: n (argument 2)"
+   | -3  -> invalid_arg "dgeqrf_: a (argument 3)"
+   | -4  -> invalid_arg "dgeqrf_: lda (argument 4)"
+   | -5  -> invalid_arg "dgeqrf_: tau (argument 5)"
+   | -6  -> invalid_arg "dgeqrf_: work (argument 6)"
+   | -7  -> invalid_arg "dgeqrf_: lwork (argument 7)"
+   | -8  -> invalid_arg "dgeqrf_: info (argument 8)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dgeqrf_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  // result tuple
+  a,tau
+
+
+///Matrix Vector Multiplication
+ member this.dgemv_((a:matrix),(x:vector)) = 
+  // input copies
+  let a = Matrix.copy a
+  let x = Vector.copy x
+  // dimensions
+  let m = NativeUtilities.matrixDim1 a in
+  let n = NativeUtilities.matrixDim2 a in
+  NativeUtilities.assertDimensions "dgemv_" ("n","Dim(x)") (n,NativeUtilities.vectorDim  x);
+  // allocate results
+  let y = Vector.zero (m)
+  // transpose
+  let a = Matrix.transpose a
+  // setup actuals
+  let mutable arg_trans = 'n'
+  let mutable arg_m = m
+  let mutable arg_n = n
+  let mutable arg_alpha = 1.0
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 m
+  let arg_x = NativeUtilities.pinV x
+  let mutable arg_incx = 1
+  let mutable arg_beta = 1.0
+  let arg_y = NativeUtilities.pinV y
+  let mutable arg_incx = 1
+  // call function
+  try
+    LapackNetlibStubs.dgemv_(&&arg_trans,&&arg_m,&&arg_n,&&arg_alpha,arg_a.Ptr,&&arg_lda,arg_x.Ptr,&&arg_incx,&&arg_beta,arg_y.Ptr,&&arg_incx)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeV arg_x
+    NativeUtilities.freeV arg_y
+  // INFO
+  // fixups
+  // result tuple
+  y
+
+
+///EigenValues and Eigen Vectors for nonsymetruc matrices
+ member this.dggev_((a:matrix),(b:matrix)) = 
+  // input copies
+  let a = Matrix.copy a
+  let b = Matrix.copy b
+  // dimensions
+  let n = NativeUtilities.matrixDim1 a in
+  NativeUtilities.assertDimensions "dggev_" ("n","Dim2(a)") (n,NativeUtilities.matrixDim2 a);
+  NativeUtilities.assertDimensions "dggev_" ("n","Dim1(b)") (n,NativeUtilities.matrixDim1 b);
+  NativeUtilities.assertDimensions "dggev_" ("n","Dim2(b)") (n,NativeUtilities.matrixDim2 b);
+  // allocate results
+  let alphar = Array.zeroCreate  (n)
+  let alphai = Array.zeroCreate  (n)
+  let beta = Array.zeroCreate  (n)
+  let vl = Array2D.zeroCreate (n) (n)
+  let vr = Array2D.zeroCreate (n) (n)
+  let work = Array.zeroCreate  ((8*n))
+  // transpose
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // setup actuals
+  let mutable arg_jobvl = 'N'
+  let mutable arg_jobvr = 'V'
+  let mutable arg_n = n
+  let arg_a = NativeUtilities.pinM a
+  let mutable arg_lda = max 1 n
+  let arg_b = NativeUtilities.pinM b
+  let mutable arg_ldb = max 1 n
+  let arg_alphar = NativeUtilities.pinA alphar
+  let arg_alphai = NativeUtilities.pinA alphai
+  let arg_beta = NativeUtilities.pinA beta
+  let arg_vl = NativeUtilities.pinA2 vl
+  let mutable arg_ldvl = n
+  let arg_vr = NativeUtilities.pinA2 vr
+  let mutable arg_ldvr = n
+  let arg_work = NativeUtilities.pinA work
+  let mutable arg_lwork = (8*n)
+  let mutable arg_info = 0
+  // call function
+  try
+    LapackNetlibStubs.dggev_(&&arg_jobvl,&&arg_jobvr,&&arg_n,arg_a.Ptr,&&arg_lda,arg_b.Ptr,&&arg_ldb,arg_alphar.Ptr,arg_alphai.Ptr,arg_beta.Ptr,arg_vl.Ptr,&&arg_ldvl,arg_vr.Ptr,&&arg_ldvr,arg_work.Ptr,&&arg_lwork,&&arg_info)
+  finally
+    NativeUtilities.freeM arg_a
+    NativeUtilities.freeM arg_b
+    NativeUtilities.freeA arg_alphar
+    NativeUtilities.freeA arg_alphai
+    NativeUtilities.freeA arg_beta
+    NativeUtilities.freeA2 arg_vl
+    NativeUtilities.freeA2 arg_vr
+    NativeUtilities.freeA arg_work
+  // INFO
+  match arg_info with
+   | -1  -> invalid_arg "dggev_: jobvl (argument 1)"
+   | -2  -> invalid_arg "dggev_: jobvr (argument 2)"
+   | -3  -> invalid_arg "dggev_: n (argument 3)"
+   | -4  -> invalid_arg "dggev_: a (argument 4)"
+   | -5  -> invalid_arg "dggev_: lda (argument 5)"
+   | -6  -> invalid_arg "dggev_: b (argument 6)"
+   | -7  -> invalid_arg "dggev_: ldb (argument 7)"
+   | -8  -> invalid_arg "dggev_: alphar (argument 8)"
+   | -9  -> invalid_arg "dggev_: alphai (argument 9)"
+   | -10 -> invalid_arg "dggev_: beta (argument 10)"
+   | -11 -> invalid_arg "dggev_: vl (argument 11)"
+   | -12 -> invalid_arg "dggev_: ldvl (argument 12)"
+   | -13 -> invalid_arg "dggev_: vr (argument 13)"
+   | -14 -> invalid_arg "dggev_: ldvr (argument 14)"
+   | -15 -> invalid_arg "dggev_: work (argument 15)"
+   | -16 -> invalid_arg "dggev_: lwork (argument 16)"
+   | -17 -> invalid_arg "dggev_: info (argument 17)"
+   | 0   -> ()
+   | n   -> failwith (sprintf "dggev_ : returned %d. The computation failed." n)
+  // fixups
+  let a = Matrix.transpose a
+  let b = Matrix.transpose b
+  // result tuple
+  a,b,alphar,alphai,beta,vr
+
+ end
+end
+module LapackNetlib = begin
+ let NetlibProvider = new Microsoft.FSharp.Math.Experimental.Provider<_>("Netlib",[|"blas.dll";"lapack.dll"|],fun () -> new LapackNetlibService() :> ILapack)
+end
diff --git a/workyard/math-provider/lapack/lapack_service_netlib.fsi b/workyard/math-provider/lapack/lapack_service_netlib.fsi
new file mode 100755
index 0000000..3a90d26
--- /dev/null
+++ b/workyard/math-provider/lapack/lapack_service_netlib.fsi
@@ -0,0 +1,5 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Math.Bindings.Internals
+module LapackNetlib =
+  val NetlibProvider : Microsoft.FSharp.Math.Experimental.Provider<Microsoft.FSharp.Math.Bindings.Internals.ILapack>
+module LapackNetlibStubs = begin end
diff --git a/workyard/math-provider/lapack/lapack_service_template.fs b/workyard/math-provider/lapack/lapack_service_template.fs
new file mode 100755
index 0000000..2e97523
--- /dev/null
+++ b/workyard/math-provider/lapack/lapack_service_template.fs
@@ -0,0 +1,66 @@
+// (c) Microsoft Corporation 2005-2009.
+[NOTICE]
+module [MODULENAME] = begin
+  [<System.Runtime.InteropServices.DllImport(@"[BLASDLL]",EntryPoint="dgemm[_]")>]
+  extern void dgemm_(char *transa, char *transb, int *m, int *n, int *k, double *alpha, double *a, int *lda, double *b, int *ldb, double *beta, double *c, int *ldc);
+
+  [<System.Runtime.InteropServices.DllImport(@"[BLASDLL]",EntryPoint="dtrsv[_]")>]
+  extern void dtrsv_(char *uplo,char *trans,char *diag,int *n,double *a,int *lda,double *x,int *incx);
+
+  [<System.Runtime.InteropServices.DllImport(@"[BLASDLL]",EntryPoint="dtrsm[_]")>]
+  extern void dtrsm_(char *side,char *uplo,char *trans,char *diag,int *m,int *n,double *alpha,double *a,int *lda,double *b,int *ldb);   
+   
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dgesv[_]")>]
+  extern void dgesv_(int *n, int *nrhs, double *a, int *lda, int *ipiv, double *b, int *ldb, int *info);
+
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dgeev[_]")>]
+  extern void dgeev_(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *wr, double *wi, double *vl, int *ldvl, double *vr, int *ldvr, double *work, int *lwork, int *info);
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dposv[_]")>]
+  extern void dposv_(char *uplo, int *n, int *nrhs, double *a, int *lda, double *b, int *ldb, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dgels[_]")>]
+  extern void dgels_(char *trans, int *m,int *n, int *nrhs, double *a, int *lda, double *b, int *ldb, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dgglse[_]")>]
+  extern void dgglse_(int *m, int *n, int *p, double *a, int *lda, double *b, int *ldb, double *c, double *d, double *x, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dsyev[_]")>]
+  extern void dsyev_(char *jobz, char *uplo, int *n, double *a,int *lda, double *w, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dsyevd[_]")>]
+  extern void dsyevd_(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *iwork, int *liwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dgesvd[_]")>]
+  extern void dgesvd_(char *jobu, char *jobvt, int  *m, int *n, double *a, int *lda, double *s, double *u, int *ldu, double *vt, int *ldvt, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dgesdd[_]")>]
+  extern void dgesdd_(char *JOBZ, int  *m, int *n, double *a, int *lda, double *s, double *u, int *ldu, double *vt, int *ldvt, double *work, int *lwork,int *iwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dsygv[_]")>]
+  extern void dsygv_(int *itype, char *jobz, char *uplo, int *n, double *a, int *lda, double *b, int *ldb, double *w, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dsygvd[_]")>]     
+  extern void dsygvd_(int *itype, char *jobz, char *uplo, int *n, double *a, int *lda, double *b, int *ldb, double *w, double *work, int *lwork,int *iwork, int *liwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dggev[_]")>]     
+  extern void dggev_( char *jobvl, char *jobvr, int *n, double *a, int *lda, double *b, int *ldb, double *alphar, double *alphai,double *beta,double *vl,int *ldvl,double *vr,int *ldvr,double *work, int *lwork,int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dgesvx[_]")>]     
+  extern void dgesvx_(char *fact, char *trans, int *n, int *nrhs, double *a, int *lda, double *af, int *ldaf, int *ipiv, char *equed, double *r, double *c, double *b, int *ldb, double *x, int *ldx, double *rcond, double *ferr, double *berr, double *work, int *iwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dposvx[_]")>]     
+  extern void  dposvx_(char *fact, char *uplo, int *n, int *nrhs, double *a, int *lda, double *af, int *ldaf, char *equed, double *s, double *b, int *ldb, double *x, int *ldx, double *rcond, double  *ferr, double *berr, double *work, int *iwork, int *info);
+
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dpotrf[_]")>]     
+  extern void  dpotrf_(char *uplo, int *n, double *a, int *lda, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dgetrf[_]")>]     
+  extern void  dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[LAPACKDLL]",EntryPoint="dgeqrf[_]")>]     
+  extern void dgeqrf_(int  *m, int *n, double *a, int *lda, double *tau, double *work, int *lwork, int *info);
+  
+  [<System.Runtime.InteropServices.DllImport(@"[BLASDLL]",EntryPoint="dgemv[_]")>]
+  extern void dgemv_(char* trans, int* m, int* n,double* alpha, double* A, int* lda,double* x, int* incx, double* beta,double* y, int* incy);
+  
+end
diff --git a/workyard/math-provider/lapack/linear_algebra.fs b/workyard/math-provider/lapack/linear_algebra.fs
new file mode 100755
index 0000000..1c6b026
--- /dev/null
+++ b/workyard/math-provider/lapack/linear_algebra.fs
@@ -0,0 +1,201 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Math.Experimental
+
+open Microsoft.FSharp.Math
+
+module LinearAlgebra = 
+  // This module is the dispatcher to BLAS/LAPACK service implementation vs managed implementation
+  // It is the user facing module.
+  open Microsoft.FSharp.Math.Bindings.Internals
+  open Microsoft.FSharp.Math.Experimental
+  
+  type Permutation = Microsoft.FSharp.Compatibility.permutation
+
+  let Lapack         = LinearAlgebraService.LAPACKService // The service/provider object
+  let MKLProvider    = LapackMKL.MKLProvider              // MKL provider
+  let NetlibProvider = LapackNetlib.NetlibProvider        // Netlib provider
+
+  module Locals = 
+    let HaveService() = Lapack.Available()
+  open Locals
+
+  let SolveTriangularLinearSystem (A:matrix) (b:vector) (isLower:bool) =
+    if HaveService() then LinearAlgebraService.solveTriangularForVector A b isLower
+                     else LinearAlgebraManaged.SolveTriangularLinearSystem A b isLower
+                   
+  let SolveTriangularLinearSystems (A:matrix) (B:matrix) (isLower:bool) =
+    if HaveService() then LinearAlgebraService.solveTriangularForMatrix A B isLower
+                     else LinearAlgebraManaged.SolveTriangularLinearSystems A B isLower
+  
+  let SolveLinearSystem (A:matrix) (b:vector) =
+    if HaveService() then LinearAlgebraService.preDivideByVector A b
+                     else LinearAlgebraManaged.SolveLinearSystem A b
+                   
+  let SolveLinearSystems (A:matrix) (B:matrix) =
+    if HaveService() then LinearAlgebraService.preDivideByMatrix A B
+                     else LinearAlgebraManaged.SolveLinearSystems A B
+
+  /// Given A[n,m] and B[n] solve for x[m] such that Ax = B
+  /// This call may fail.
+  let preDivideByVector A b = 
+    if HaveService() then LinearAlgebraService.preDivideByVector A b
+                     else LinearAlgebraManaged.SolveLinearSystem A b
+    
+
+  /// Given A[n,m] and B[n,k] solve for X[m,k] such that AX = B
+  /// This call may fail.
+  let preDivideByMatrix a b = 
+    if HaveService() then LinearAlgebraService.preDivideByMatrix a b
+                     else LinearAlgebraManaged.SolveLinearSystems a b
+    
+  /// Compute eigenvalue/eigenvector decomposition of a square real matrix.
+  /// Returns two arrays containing the eigenvalues and eigenvectors, which may be complex.
+  /// This call may fail.
+  let EigenSpectrum m = 
+    if HaveService() then let evals, evecs = LinearAlgebraService.eigenvectors m
+                          let n = evals.Length
+                          Vector.Generic.init n (fun i -> evals.[i]), Matrix.Generic.init n n (fun i j -> (evecs.[i]).[j])
+                     else LinearAlgebraManaged.eigenvectors m
+                           
+  /// Compute eigenvalues of a square real matrix.
+  /// Returns arrays containing the eigenvalues which may be complex.
+  /// This call may fail.
+  let EigenValues m =
+    if HaveService() then let evals = LinearAlgebraService.eigenvalues m
+                          let n = evals.Length
+                          Vector.Generic.init n (fun i -> evals.[i])
+                     else LinearAlgebraManaged.eigenvalues m
+
+  /// Compute eigenvalues for a real symmetric matrix.
+  /// Returns array of real eigenvalues.
+  /// This call may fail.
+  let EigenValuesWhenSymmetric a =
+    if HaveService() then let evals = LinearAlgebraService.symmetricEigenvalues a
+                          let n = evals.Length
+                          Vector.init n (fun i -> evals.[i])
+                     else LinearAlgebraManaged.symmetricEigenvalues a
+    
+  /// Compute eigenvalues and eigenvectors for a real symmetric matrix.
+  /// Returns arrays of the values and vectors (both based on reals).
+  /// This call may fail.
+  let EigenSpectrumWhenSymmetric a =
+    if HaveService() then let evals, evecs = LinearAlgebraService.symmetricEigenvectors a
+                          let n = evals.Length
+                          Vector.init n (fun i -> evals.[i]), Matrix.init n n (fun i j -> (evecs.[i]).[j])
+                     else LinearAlgebraManaged.symmetricEigenvectors a
+    
+  /// Given A[n,n] find it's inverse.
+  /// This call may fail.
+  let Inverse a = 
+    if HaveService() then LinearAlgebraService.inverse a
+                     else LinearAlgebraManaged.Inverse a
+
+  /// Given A[m,n] and B[m] solves AX = B for X[n].
+  /// When m=>n, have over constrained system, finds least squares solution for X.
+  /// When m<n, have under constrained system, finds least norm solution for X.
+  let LeastSquares a b =
+    if HaveService() then LinearAlgebraService.leastSquares a b
+                     else LinearAlgebraManaged.leastSquares a b
+    
+  /// Given A[n,n] real symmetric positive definite.
+  /// Finds the cholesky decomposition L such that L' * L = A.
+  /// May fail if not positive definite.
+  let Cholesky a = 
+    if HaveService() then LinearAlgebraService.Cholesky a
+                     else LinearAlgebraManaged.Cholesky a
+      
+  /// Given A[n,n] real matrix.
+  /// Finds P,L,U such that L*U = P*A with L,U lower/upper triangular.
+  let LU a = 
+    if HaveService() then LinearAlgebraService.LU a
+                     else LinearAlgebraManaged.LU a
+      
+
+  /// Given A[m,n] finds Q[m,m] and R[k,n] where k = min m n.
+  /// Have A = Q.R  when m<=n.
+  /// Have A = Q.RX when m>n and RX[m,n] is R[n,n] row extended with (m-n) zero rows.
+  let QR a = 
+    if HaveService() then LinearAlgebraService.QR a
+                     else LinearAlgebraManaged.QR a
+  
+  let SVD a = 
+    if HaveService() then let U,D,V = LinearAlgebraService.SVD a
+                          U,Vector.ofArray D,V
+                     else LinearAlgebraManaged.SVD a
+
+  let Hessenberg A =
+    if HaveService() then failwith "Not implemented yet."// REVIEW LinearAlgebraService.Hessenberg A
+                     else LinearAlgebraManaged.Hessenberg A
+
+  /// This method computes the condition number by just dividing the largest singular value
+  /// by the smallest.
+  let Condition (A:matrix) =
+    let _,D,_ = SVD A
+    D.[0] / D.[D.Length-1]
+
+  /// Compute the determinant of a matrix by performing an LU decomposition since if A = P'LU,
+  /// then det(A) = det(P') * det(L) * det(U).
+  let Determinant A =
+    let P,_,U = LU A
+    // Compute the sign of a permutation REVIEW maybe this should go into permutation?
+    let PermutationSign (len,p) =
+        let a = Array.init len (fun i -> p i)                        // Get an array representation of the permutation
+        let v = Array.init len                                         // Find the positions of all the positions in the permutation
+                            (fun i -> Array.findIndex (fun x -> x = i) a)
+        let mutable sign = 1.0                                              // Remember the sign
+        for i=0 to len-2 do                                            // Start transposing elements keeping track of how many
+            if a.[i] <> i then                                              // transpositions we have taken.
+                a.[v.[i]] <- a.[i]
+                a.[i] <- i
+                v.[a.[v.[i]]] <- v.[i]
+                v.[i] <- i
+                sign <- -sign
+        assert(a = [|0 .. len-1|])
+        assert(v = [|0 .. len-1|])
+        sign
+    let n = A.NumRows
+    let P = (fun i -> P i)
+    (PermutationSign (n,P)) * (Vector.prod U.Diagonal)
+        
+
+
+(*TESTING
+#load "lapack_base.fs";;
+#load "lapack.fs";;
+#load "lapack_service_mkl.fs";;
+//#r "fsharp.math.lapack.dll";;
+open Microsoft.FSharp.Math.Experimental.LinearAlgebra
+open Microsoft.FSharp.Math;;
+
+Microsoft.FSharp.Math.Bindings.Internals.LapackMKL.register();;
+verbose := true;;
+let A = (Matrix.of_list [[10.0; 1.0];[1.0;10.0]]);;
+let B = symmetricPositiveDefiniteCholeskyLU A
+let A = (Matrix.of_list [[10.0;  1.0; 0.0];
+                         [ 1.0; 10.0; 0.0];
+                         [ 1.0;  0.0; 2.0]])
+let r,vs,tau = QR A
+let h v tau = Matrix.iden
+
+#q;;
+
+let A = (Matrix.of_list [[10.0; 12.0; 0.3];
+                         [ 1.0; 13.0; 0.2];
+                         [99.0;-12.0; 2.0]])
+let m,n = matrixDims A
+// QR check
+let q,r = QR A
+q * r - A
+let [|h1;h2;h3|] = hs
+let Q = h1 * (h2 * h3)
+Q * r - A
+let h (v:vector) tau = Matrix.identity 3 - (tau:float) $* (v * v.Transpose)
+let hs = Array.map2 h vs tau
+
+// SVD check
+let vs,U,W = SVD A
+let VS = Matrix.init 3 3 (fun r c -> if r=c then vs.[r] else 0.0)
+U * VS * W - A
+
+*)
diff --git a/workyard/math-provider/lapack/linear_algebra.fsi b/workyard/math-provider/lapack/linear_algebra.fsi
new file mode 100755
index 0000000..8bff7ac
--- /dev/null
+++ b/workyard/math-provider/lapack/linear_algebra.fsi
@@ -0,0 +1,82 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Math.Experimental
+
+open Microsoft.FSharp.Math
+open Microsoft.FSharp.Math.Experimental
+open Microsoft.FSharp.Math.Bindings.Internals
+open Microsoft.FSharp.Collections
+
+/// Attribution and acknowledgement:
+///
+/// These modules provide linear algebra functionality on F# matrix types.
+/// Some functionality is implemented using a provider model.
+/// The providers dynamic link to BLAS and Lapack DLLs.
+///
+/// There are currently providers for:
+/// a) blas.dll and lapack.dll which can be built from netlib.org sources.
+/// b) the High Performance Intel(R) Math Kernel Library (MKL) runtime DLLs.
+///
+/// For information on the Intel(R) MKL High Performance library, please see:
+/// http://www.intel.com/cd/software/products/asmo-na/eng/307757.htm
+  
+module LinearAlgebra =
+    type Permutation = Microsoft.FSharp.Compatibility.permutation
+    
+    /// The LAPACK and BLAS service.
+    /// The default providers are already registered.
+    /// The service is primed to auto start on the first service request.
+    val Lapack         : Service<ILapack>
+
+    /// The MKL provider for the BLAS/LAPACK service
+    val MKLProvider    : Provider<ILapack>
+
+    /// The Netlib provider for the BLAS/LAPACK service
+    val NetlibProvider : Provider<ILapack>
+    
+    /// Computes the determinant of a matrix. Uses an LU factorization to compute the determinant.
+    val Determinant : matrix -> float
+    /// Estimates the condition number of matrix A in 2-norm using an SVD decomposition of A.
+    val Condition : A:matrix -> float
+    
+    /// Solves a system of linear equations for vector x when A is triangular: Ax=b. The isLower
+    /// flag specifies whether the input argument A is lower triangular. Uses BLAS *trsv if possible.
+    val SolveTriangularLinearSystem : A:matrix -> b:vector -> isLower:bool -> vector
+    /// Solves a system of linear equations for every column vector of B when A is triangular: AX=B. The isLower
+    /// flag specifies whether the input argument A is lower triangular. Uses BLAS *trsm if possible.
+    val SolveTriangularLinearSystems : A:matrix -> B:matrix -> isLower:bool -> matrix
+    
+    /// Solves the linear system Ax=b when given A and b with no particular structure for A assumed. The method may
+    /// fail when A is singular.
+    val SolveLinearSystem : A:matrix -> b:vector -> vector
+    /// Solves the linear system Ax=B when given A and B with no particular structure for A nor B assumed. The method may
+    /// fail when A is singular.
+    val SolveLinearSystems : A:matrix -> B:matrix -> matrix
+    
+    /// Compute the LU decomposition of matrix A: PA=LU. Uses LAPACK *getrf if possible.
+    val LU : A:matrix -> P:Microsoft.FSharp.Compatibility.permutation * L:matrix * U:matrix
+    /// Compute the cholesky decomposition of matrix A: A = C�C. Uses LAPACK *potrf if possible.
+    val Cholesky : A:matrix -> matrix
+    /// Computes the inverse of matrix A. Uses LAPACK *gesv on an identity matrix if possible.
+    val Inverse : A:matrix -> matrix
+    
+    /// Compute the QR factorization of matrix A: A=QR. Uses LAPACK *geqrf if possible.
+    val QR : A:matrix -> Q:matrix * R:matrix
+    
+    /// Compute the SVD of matrix A: A=UDV'. The singular values are returned in descending
+    /// order. Uses LAPACK *gesvd if possible.
+    val SVD : A:matrix -> U:matrix * D:Vector<float> * V:matrix
+    
+    /// Compute the eigenvalues of matrix A: A=UVU'. Uses LAPACK *geev if possible.
+    val EigenValues : A:matrix -> Vector<complex>
+    /// Compute the eigenvalue-eigenvector decomposition of matrix A: A=UVU'. Uses LAPACK *geev if possible.
+    val EigenSpectrum : A:matrix -> V:Vector<complex> * U:Matrix<complex>
+    /// Compute the eigenvalues of matrix A: A=UVU'. Uses LAPACK *syev if possible.
+    val EigenValuesWhenSymmetric : A:matrix -> vector
+    /// Compute the eigenvalue-eigenvector decomposition of matrix A: A=UVU'. Uses LAPACK *syev if possible.
+    val EigenSpectrumWhenSymmetric : A:matrix -> V:vector * U:matrix
+    /// Compute a Hessenberg form of the matrix A. Uses LAPACK *gehrd if possible.
+    val Hessenberg : A:matrix -> Q:matrix * H:matrix
+    
+    /// Computes a least squares solution using a QR factorization; e.g. min_x ||b - Ax||
+    /// using the 2-norm. Uses LAPACK *gels if possible.
+    val LeastSquares : A:matrix -> b:vector -> vector
diff --git a/workyard/math-provider/lapack/linear_algebra_managed.fs b/workyard/math-provider/lapack/linear_algebra_managed.fs
new file mode 100755
index 0000000..170df85
--- /dev/null
+++ b/workyard/math-provider/lapack/linear_algebra_managed.fs
@@ -0,0 +1,238 @@
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Math.Experimental
+
+open Microsoft.FSharp.Math
+open Microsoft.FSharp.Math.Bindings.Internals.NativeUtilities
+
+/// This module is for internal use only.
+module LinearAlgebraManaged = 
+  
+    let NYI () = failwith "Not yet implemented, managed fallback linear algebra ops coming soon"
+    
+    type Permutation = Permutation of int * (int -> int)
+    
+    let SVD A = NYI()
+    let EigenSpectrum A = NYI()
+    let Condition A = NYI()
+
+    let eigenvectors m = NYI()
+    let eigenvalues m = NYI()
+    let symmetricEigenvalues a = NYI()
+    let symmetricEigenvectors a = NYI()
+
+    let SolveTriangularLinearSystems K B isLower =
+        if isLower then
+            let (nK,mK) = matrixDims K
+            let (nB,mB) = matrixDims B
+            if nK<>mK || nB<> nK then invalid_arg "Cannot do backward substitution on non-square matrices."
+            let X = Matrix.zero nK mK
+            for i=0 to nK-1 do
+                for k=0 to mB-1 do
+                    let s = ref B.[i,k]
+                    for j=0 to i-1 do
+                        s := !s - K.[i,j] * X.[j,k]
+                    done
+                    X.[i,k] <- !s / K.[i,i]
+                done
+            done
+            X
+        else
+            let (nK,mK) = matrixDims K
+            let (nB,mB) = matrixDims B
+            if nK<>mK || nB<> nK then invalid_arg "Cannot do backward substitution on non-square matrices."
+            let X = Matrix.zero nK mK
+            for i=0 to nK-1 do
+                for k=0 to mB-1 do
+                    let s = ref B.[nK-i-1,k]
+                    for j=0 to i-1 do
+                        s := !s - K.[nK-i-1,nK-j-1] * X.[nK-j-1,k]
+                    done
+                    X.[nK-i-1,k] <- !s / K.[nK-i-1,nK-i-1]
+                done
+            done
+            X
+
+    let SolveTriangularLinearSystem K v isLower = (SolveTriangularLinearSystems K (Matrix.ofVector v) isLower).Column 0
+
+    type range = int * int
+
+    let inline sumfR f ((a,b):range) =
+        let mutable res = 0.0 in
+        for i = a to b do
+            res <- res + f i
+        res
+      
+
+    let Cholesky (a: matrix) =
+        let nA,mA = a.Dimensions
+        if nA<>mA              then invalid_arg "choleskyFactor: not square";
+        let lres = Matrix.zero nA nA (* nA=mA *)
+        for j=0 to nA-1 do
+        for i=j to nA-1 do (* j <= i *)
+          (* Consider a_ij = sum(k=0...n-1)  (lres_ik . lresT_kj)
+           *               = sum(k=0...n-1)  (lres_ik . lres_jk)
+           *               = sum(k=0...j-1)  (lres_ik . lres_jk) + lres_ij . lres_jj + (0 when k>j)
+           *               = psum                                + lres_ij . lres_jj
+           * This determines lres_ij terms of preceeding terms.
+           * lres_ij depends on lres_ik and lres_jk (and maybe lres_ii) for k<i
+           *)
+          let psum = sumfR (fun k -> lres.[i,k] * lres.[j,k]) (0,j-1)
+          let a_ij = a.[i,j]
+          if i=j then
+            let t = (a_ij - psum)
+            if t >= 0.0 then lres.[i,i] <- (System.Math.Sqrt t) else invalid_arg "choleskyFactor: not symmetric postive definite"
+          else
+            lres.[i,j] <- ((a_ij - psum) / lres.[j,j])
+        done
+        done;
+        // if not (isLowerTriangular lres) then failwith "choleskyFactor: not lower triangular result";
+        lres.Transpose  // REVIEW optimize this so we don't have to take transpose ...
+    
+    let LU A =
+        let (nA,mA) = matrixDims A
+        if nA<>mA then invalid_arg "lu: not square";
+        let L = Matrix.zero nA nA
+        let U = Matrix.copy A
+        let P = [| 0 .. nA-1 |]
+        let abs (x:float) = System.Math.Abs x
+        let swapR X i j =                           //  REVIEW should we make this a general method?
+            let (nX,mX) = matrixDims X
+            let t = X.[i .. i,0 .. ]
+            for k=0 to mX-1 do
+                X.[i,k] <- X.[j,k]
+                X.[j,k] <- t.[0,k]
+            done
+            
+        for i=0 to nA-2 do
+            let mutable maxi = i        //  Find the biggest pivot element.
+            for k=i+1 to nA-1 do
+                if abs(U.[maxi,i]) < abs(U.[k,i]) then maxi <- k
+            done
+            //let maxi = maxIndex (i+1) (nA-1) (fun k -> abs(U.[k,i]))
+            
+            if maxi <> i then
+                swapR U i maxi     // Swap rows if needed.
+                swapR L i maxi     // REVIEW can be made more performant.
+                let t = P.[i]
+                P.[i] <- P.[maxi]
+                P.[maxi] <- t
+            
+            for j=i+1 to nA-1 do
+                L.[j,i] <- U.[j,i] / U.[i,i]
+                for k=i+1 to nA-1 do
+                    U.[j,k] <- U.[j,k] - L.[j,i] * U.[i,k]
+                done
+                U.[j,i] <- 0.0
+            done
+        done
+        (((*P.Length,*)Permutation.ofArray P),L + Matrix.identity nA,U)
+    
+    let SolveLinearSystem (A:matrix) (b:vector) =
+        let (n,m) = matrixDims A
+        if n <> m then invalid_arg "Matrix must be square." 
+        let P,L,U = LU A
+        (SolveTriangularLinearSystem U (SolveTriangularLinearSystem L (b.Permute P) true) false)
+        
+    let SolveLinearSystems (A:matrix) (B:matrix) =
+        let (n,m) = matrixDims A
+        if n <> m then invalid_arg "Matrix must be square." 
+        let P,L,U = LU A
+        (SolveTriangularLinearSystems U (SolveTriangularLinearSystems L (B.PermuteRows P) true) false)
+    
+    let Inverse A =
+        let (n,m) = matrixDims A
+        if n <> m then invalid_arg "Matrix must be square when computing its inverse." 
+        let P,L,U = LU A
+        (SolveTriangularLinearSystems U (SolveTriangularLinearSystems L ((Matrix.identity n).PermuteRows P) true) false)
+        
+    /// Generates a unit vector [1 0 .. 0 ].
+    let unitV k = let e = Vector.create k 0.0 in e.[0] <- 1.0; e
+
+    /// Computes the sign of a floating point number.
+    let sign (f: float) = float (System.Math.Sign f)                    // REVIEW put in float library.
+
+    /// This method computes and performs a Householder reflection. It will change the
+    /// input matrix and return the reflection vector.
+    let HouseholderTransform (A:matrix) (i:int) =
+        // REVIEW do this using views and get rid of the i.
+        let (n,m) = matrixDims A
+        let x = A.[i..,i..i].Column 0                       // Get part of the i'th column of the matrix.
+        let nx = Vector.norm x
+        let vu = x + sign(x.[0]) * nx * (unitV (n-i))               // Compute the reflector.
+        let v = 1.0/(Vector.norm vu) * vu                           // Normalize reflector.
+        
+        // Perform the reflection.
+        let v'A = RowVector.init (m-i) (fun j -> v.Transpose * (A.[i..,i+j..i+j].Column 0))
+        for l=i to n-1 do
+            for k=i to m-1 do
+                A.[l,k] <- A.[l,k] - 2.0 * v.[l-i] * v'A.[k-i]
+        v                                                              // Return reflection vector.
+            
+    let QR (A:matrix) =
+        let (n,m) = matrixDims A
+        let mutable Q = Matrix.identity n                                   // Keeps track of the orthogonal matrix.
+        let R = Matrix.copy A
+
+        // This method will update the orhogonal transformation fast when given a reflection vector.
+        let UpdateQ (Q:matrix) (v:vector) =
+            let n = Vector.length v
+            let (nQ,mQ) = matrixDims Q
+            
+            // Cache the computation of Q*v.
+            let Qv = Vector.init nQ (fun i -> (Q.[i..i,nQ-n..].Row 0) * v)
+
+            // Update the orthogonal transformation.
+            for i=0 to nQ-1 do
+                for j=nQ-n to nQ-1 do
+                    Q.[i,j] <- Q.[i,j] - 2.0 * Qv.[i] * v.[j-nQ+n]
+            ()
+        
+        // This QR implementation keeps the unreduced part of A in R. It computes reflectors one at a time
+        // and reduces R column by column. In the process it keeps track of the Q matrix.
+        for i=0 to (min n m)-1 do
+            let v = HouseholderTransform R i
+            UpdateQ Q v
+        Q,R
+
+    let Hessenberg (A:matrix) =
+        // REVIEW we can do with less copying here.
+        let (n,m) = matrixDims A
+        if n<>m then invalid_arg "Currently only implemented for square matrices."
+        let mutable Q = Matrix.identity n                                   // Keeps track of the orthogonal matrix.
+        let R = A.[1..,*]
+
+        // This method will update the orhogonal transformation fast when given a reflection vector.
+        let UpdateQ (Q:matrix) (v:vector) =
+            let n = Vector.length v
+            let (nQ,mQ) = matrixDims Q
+            
+            // Cache the computation of Q*v.
+            let Qv = Vector.init nQ (fun i -> (Q.[i..i,nQ-n..].Row 0) * v)
+
+            // Update the orthogonal transformation.
+            for i=0 to nQ-1 do
+                for j=nQ-n to nQ-1 do
+                    Q.[i,j] <- Q.[i,j] - 2.0 * Qv.[i] * v.[j-nQ+n]
+            ()
+        
+        // This QR implementation keeps the unreduced part of A in R. It computes reflectors one at a time
+        // and reduces R column by column. In the process it keeps track of the Q matrix.
+        for i=0 to n-2 do
+            let v = HouseholderTransform R i
+            UpdateQ Q v
+        Q,Matrix.init n m (fun i j -> if i = 0 then A.[i,j] else R.[i-1,j])
+        
+    let leastSquares A (b: vector) =
+        let (m,n) = matrixDims A
+        // Is this an overdetermined or underdetermined system?
+        if m > n then
+            let Q,R = QR A
+            let Qtb = Q.Transpose * b
+            SolveTriangularLinearSystem R.[0..n-1,0..n-1] Qtb.[0..n-1] false
+        else
+            let Q,R = QR A
+            let Qtb = Q.Transpose * b
+            let s = SolveTriangularLinearSystem R.[0..m-1,0..m-1] Qtb false
+            Vector.init n (fun i -> if i < m then s.[i] else 0.0)
+
diff --git a/workyard/math-provider/lapack/linear_algebra_service.fs b/workyard/math-provider/lapack/linear_algebra_service.fs
new file mode 100755
index 0000000..d61d03c
--- /dev/null
+++ b/workyard/math-provider/lapack/linear_algebra_service.fs
@@ -0,0 +1,175 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Math.Experimental
+
+/// This module is for internal use only.
+module LinearAlgebraService = 
+
+  /// Attribution and acknowledgement:
+  ///
+  /// These modules provide linear algebra functionality on F# matrix types.
+  /// The functionality is implemented using a provider model.
+  /// The providers dynamic link to BLAS and Lapack DLLs.
+  ///
+  /// There are currently providers for:
+  /// a) blas.dll and lapack.dll which can be built from netlib.org sources.
+  /// b) the High Performance Intel(R) Math Kernel Library (MKL) runtime DLLs.
+  ///
+  /// For information on the Intel(R) MKL High Performance library, please see:
+  /// http://www.intel.com/cd/software/products/asmo-na/eng/307757.htm
+  ///
+
+  open Microsoft.FSharp.Math
+  open Microsoft.FSharp.Math.Bindings
+  open Microsoft.FSharp.Math.Bindings.Internals
+  open Microsoft.FSharp.Math.Bindings.Internals.NativeUtilities
+  open Microsoft.FSharp.Collections
+  open System.IO
+  
+  open Microsoft.FSharp.Math.Experimental
+
+  let MKLProvider    = LapackMKL.MKLProvider
+  let NetlibProvider = LapackNetlib.NetlibProvider    
+  let LAPACKService = new Service<ILapack>([MKLProvider;NetlibProvider])
+
+  let Service() = 
+    match LAPACKService.Service() with
+    | Some svc -> svc
+    | None     -> failwith "LAPACK service either not available, or not started"
+  
+  /// Compute eigenvalue/eigenvector decomposition of a square real matrix.
+  /// Returns two arrays containing the eigenvalues and eigenvectors, which may be complex.
+  /// This call may fail.
+  let eigenvectors m = 
+    let complex r = Complex.mkRect(r,0.0)
+    let makeEigenVectors (wr:float[],wi:float[],vr:float[,]) =
+      let n = wr.Length
+      let eigenValues  = Array.init n (fun i -> Complex.mkRect(wr.[i],wi.[i]))
+      let cvr = Array.init n (fun i -> Vector.Generic.init n (fun j -> complex vr.[i,j]))
+      let eigenVectors = Array.zeroCreate n : Vector<Complex> array // zeros....
+      let mutable i = 0
+      while (i < n) do      
+        if wi.[i] = 0.0 then
+          eigenVectors.[i] <-  cvr.[i]
+          i <- i + 1
+        else
+          assert(wi.[i] = -wi.[i+1]) // better error message?
+          eigenVectors.[i]   <- cvr.[i] + Complex.OneI * cvr.[i+1]
+          eigenVectors.[i+1] <- cvr.[i] - Complex.OneI * cvr.[i+1]
+          i <- i + 2
+      done
+      eigenValues,eigenVectors
+    Service().dgeev_ ('V',m) |> makeEigenVectors
+      
+  /// Compute eigenvalues of a square real matrix.
+  /// Returns arrays containing the eigenvalues which may be complex.
+  /// This call may fail.
+  let eigenvalues m = 
+    let complex r = Complex.mkRect(r,0.0)
+    let makeEigenValues (wr:float[],wi:float[],_) =
+      let n = wr.Length
+      let eigenValues  = Array.init n (fun i -> Complex.mkRect(wr.[i],wi.[i]))
+      eigenValues
+    Service().dgeev_ ('N',m) |> makeEigenValues
+
+  /// Compute eigenvalues for a real symmetric matrix.
+  /// Returns array of real eigenvalues.
+  /// This call may fail.
+  let symmetricEigenvalues a =
+    let a,lambdas = Service().dsyev_ ('N','U',a)
+    lambdas
+
+  /// Compute eigenvalues and eigenvectors for a real symmetric matrix.
+  /// Returns arrays of the values and vectors (both based on reals).
+  /// This call may fail.
+  let symmetricEigenvectors a =
+    let n,m = matrixDims a
+    let a,lambdas = Service().dsyev_ ('V','U',a)
+    let vs = Array.init n (fun j -> Vector.init n (fun i -> a.[i,j]))
+    lambdas,vs
+
+  /// Given A[n,m] and B[n] solve for x[m] such that Ax = B
+  /// This call may fail.
+  let preDivideByVector A b = 
+    let _,_,x  = Service().dgesv_(A,Matrix.ofVector b)
+    Matrix.toVector x
+
+  /// Given A[n,m] and B[n,k] solve for X[m,k] such that AX = B
+  /// This call may fail.
+  let preDivideByMatrix a b = 
+    let _,_,x  = Service().dgesv_(a,b)
+    x
+
+  let solveTriangularForVector a b isLower =
+    // NOTE: L and U transposed. Check. Is this the right away around?
+    Service().dtrsv_((if isLower then 'u' else 'l'),a,b) (* CHECK: parser error without brackets? *)
+
+  let solveTriangularForMatrix a b isLower = 
+    // NOTE: L and U transposed. Check. Is this the right away around?
+    Service().dtrsm_((if isLower then 'u' else 'l'),a,b) (* CHECK: parser error without brackets? *)
+
+  /// Given A[n,n] find it's inverse.
+  /// This call may fail.
+  let inverse a = 
+    let n,m = matrixDims a
+    NativeUtilities.assertDimensions "inverse" ("rows","columns") (n,m)
+    let _,_,x  = Service().dgesv_(a,Matrix.identity n)
+    x
+
+  /// Given A[m,n] and B[m] solves AX = B for X[n].
+  /// When m=>n, have over constrained system, finds least squares solution for X.
+  /// When m<n, have under constrained system, finds least norm solution for X.
+  let leastSquares a b =
+    let m,n = matrixDims a
+    let b = if m>n then Matrix.ofVector b else Matrix.init n 1 (fun i j -> if i<m then b.[i] else 0.0)
+    let a,b = Service().dgels_(a,b)
+    Vector.init n (fun i -> b.[i,0])
+
+  /// Given A[n,n] real symmetric positive definite.
+  /// Finds the cholesky decomposition L such that L' * L = A.
+  /// May fail if not positive definite.
+  let Cholesky a = 
+    let n,_ = matrixDims a  
+    let b = Service().dpotrf_('U',a)
+    let b = Matrix.init n n (fun i j -> if j>=i then b.[i,j] else 0.0)
+    b
+  
+  /// Given A[n,n] real matrix.
+  /// Finds P,L,U such that L*U = P*A with L,U lower/upper triangular.
+  let LU a = 
+    // This method translates a BLAS/LAPACK permutation into an FSharp.Collections.Permutation.
+    // The BLAS/LAPACK permutation (P: int array) encodes that in step i, row i and P.[i] were
+    // swapped. 
+    let TranslatePermutation P =
+        let n = Array.length P
+        let x = [|0 .. n-1|]
+        for l=0 to n-1 do
+            let t = x.[l]
+            x.[l] <- x.[P.[l]]
+            x.[P.[l]] <- t
+        ((*n,*)Permutation.ofArray(x))
+    let n,m = matrixDims a  
+    let lu,p = Service().dgetrf_(a)
+    let l = Matrix.init n m (fun i j -> if j<i then lu.[i,j] elif j = i then 1.0 else 0.0)
+    let u = Matrix.init n m (fun i j -> if j>=i then lu.[i,j] else 0.0)
+    p |> Array.map (fun i -> i-1) |> TranslatePermutation,l,u
+
+  /// Given A[m,n] finds Q[m,m] and R[k,n] where k = min m n.
+  /// Have A = Q.R  when m<=n.
+  /// Have A = Q.RX when m>n and RX[m,n] is R[n,n] row extended with (m-n) zero rows.
+  let QR a = 
+    let m,n = matrixDims a
+    let k = min m n 
+    let res,tau = Service().dgeqrf_(a)
+    let R  = Matrix.init k n (fun r c -> if r <= c then res.[r,c] else 0.0)
+    let ks = [| 0 .. (k-1) |]
+    let vs = ks |> Array.map (fun i -> Vector.init m (fun j -> if j < i then 0.0 else
+                                                               if j = i then 1.0 else
+                                                               res.[j,i]))
+    let h (v:vector) tau = Matrix.identity m - (tau:float) * (v * v.Transpose)
+    let hs = Array.map2 h vs tau
+    let Q  = Array.reduceBack ( * ) hs
+    Q,R (*,tau,vs,hs*)
+
+  let SVD a = 
+    let vs,u,w = Service().dgesvd_ a
+    u,vs,w
diff --git a/workyard/math-provider/lapack/regen.bat b/workyard/math-provider/lapack/regen.bat
new file mode 100755
index 0000000..3790d46
--- /dev/null
+++ b/workyard/math-provider/lapack/regen.bat
@@ -0,0 +1,3 @@
+..\..\..\..\..\bin\fsc code_generator.fs
+code_generator.exe
+del code_generator.exe
diff --git a/workyard/math-provider/lapack/service.fs b/workyard/math-provider/lapack/service.fs
new file mode 100755
index 0000000..36a2ef1
--- /dev/null
+++ b/workyard/math-provider/lapack/service.fs
@@ -0,0 +1,165 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Math.Experimental
+
+// NOTE: Abstractable code.
+//   This file is a Service/Provider model cache with pre-checks that supporting DLLs are available.
+//   This is not LAPACK specific, and is more generally useful.
+//   It has been abstracted over the underlying service type (ILapack becomes 'a).
+//   The providers could have other pre-conditions, e.g. machine architecture, OS, etc.
+
+open Microsoft.FSharp.Collections
+open System.IO
+open System.Collections.Generic
+ 
+/// Generic provider with unmanaged DLL dependencies.
+type Provider<'a>(name:string,requiredDLLs:string[],provide:unit -> 'a) = 
+    // NOTE: The dependencies could be extended to include architecture.
+    member this.Name         = name 
+    member this.RequiredDLLs = requiredDLLs
+    member this.Provide()    = provide()   
+  
+module Locals =     
+    let mkProvider (name,requireDLLs,provide) = Provider(name,requireDLLs,provide) 
+    
+    let noRepeats xs = xs |> Set.ofList |> Set.toList
+    let noLaterRepeats xs =
+      let collect (soFar,revXs) x =
+        if Set.contains x soFar then (soFar,revXs) else (Set.add x soFar,x::revXs)
+      let (_,revXs) = List.fold collect (Set.empty,[]) xs
+      List.rev revXs
+    
+    let searchPathsForDLLImports() =         
+      // The providers have DLL dependencies via their platform-invoke DLLImport attributes.
+      // The DLLs search procedure for those DLLs is described below. (follow links).
+      // Here, we compute those paths (a superset of them).
+      // 
+      // From: VC++ Programming Guide: Search Path Used by Windows to Locate a DLL
+      //   http://msdn2.microsoft.com/en-us/library/7d83bc18(VS.80).aspx
+      //
+      // Search order:
+      //   The directory where the executable module for the current process is located.
+      //   The current directory.
+      //   The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.
+      //   The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.
+      //   The directories listed in the PATH environment variable.
+      //
+      // From: Development Impacts of Security Changes in Windows Server 2003
+      //   http://msdn2.microsoft.com/en-us/library/ms972822.aspx
+      // This reports that system directories are now searched first.
+      //
+      let windowsSystemDir = System.Environment.SystemDirectory
+      let windowsDir       = System.IO.Path.GetDirectoryName(windowsSystemDir)
+      let currentExeDirs   =
+        // This includes EXE directory, and loaded DLL directories.
+        // It may be an over-estimate of the search path.
+        let proc = System.Diagnostics.Process.GetCurrentProcess()
+        let mods  : System.Diagnostics.ProcessModule list = proc.Modules |> Seq.cast |> Seq.toList
+        mods     |> List.map (fun m -> Path.GetDirectoryName m.FileName) |> noRepeats
+      let currentDir = System.Environment.CurrentDirectory 
+      let pathDirs =
+        match System.Environment.GetEnvironmentVariable("PATH") with
+        | null  -> []
+        | paths -> paths.Split([|';'|]) |> Array.toList      
+      let orderedSearchPaths = windowsSystemDir :: windowsDir :: (currentExeDirs @ [currentDir] @ pathDirs)
+      noLaterRepeats orderedSearchPaths
+    
+    let pathDLLs (path:string) = if not (Directory.Exists path) then [||] else Directory.GetFiles(path,"*.DLL")       
+    
+    let dllFilename (dll:string) = (Path.GetFileName dll).ToLower() // normalizes filename
+        
+    let loadableDLLPaths() =
+      // Makes a table of (DLL,availablePaths)
+      // This is reusable code...
+      let paths = searchPathsForDLLImports()
+      let dllPaths = new Dictionary<string,ResizeArray<string>>()
+      let add path dll = 
+        let dll = dllFilename dll
+        if not (dllPaths.ContainsKey(dll)) then dllPaths.[dll] <- new ResizeArray<_>()
+        dllPaths.[dll].Add(path)
+      List.iter (fun path -> Array.iter (add path) (pathDLLs path)) paths
+      dllPaths
+
+    let loadableProvider (dllPaths:Dictionary<_,_>) (provider:Provider<'a>) = 
+      let dllAvailable    (dll:string) = dllPaths.ContainsKey(dllFilename dll)
+      let availableReason (dll:string) = let quote s = "'" + s + "'"
+                                         let paths = dllPaths.[dllFilename dll] |> ResizeArray.toList
+                                         let pathNote path = sprintf "Required %s seen in %s" dll path
+                                         System.String.Join("\n", Array.ofList(List.map pathNote paths))
+      if Array.forall dllAvailable provider.RequiredDLLs then
+        let justification = System.String.Join("\n", Array.map availableReason provider.RequiredDLLs)
+        let justification = "Provider: " ^ provider.Name ^ "\n" ^ justification
+        Some (provider,justification)
+      else
+        None
+        
+    let checkProvider p = 
+      match loadableProvider (loadableDLLPaths()) p with
+      | None                   -> "Provider is not loadable"
+      | Some (p,justification) -> justification
+        
+    // This type is internal to Service (motivates nested types).
+    type 'a ServiceState =
+    | ServiceDisabled                          // service disabled, do not look for it.
+    | ServiceEnabledUninitialised              // service enabled, but no search made yet.
+    | ServiceEnabledOK     of 'a * string      // service enabled, and justification string for diagnostics.
+    | ServiceEnabledFailed                     // service enabled, but DLLs not found, or load failed.
+
+open Locals
+  
+type Provider<'a> with
+    member this.Check() = checkProvider this
+
+type Service<'a>(providers:Provider<'a> seq) =
+    let mutable providers = Seq.toArray providers                // possible providers configuration state
+    let mutable state = ServiceEnabledUninitialised               // service state
+    
+    /// Service Providers
+    member this.Providers with get()  = providers
+                           and set(x) = providers <- x
+    
+    /// Disable the service.
+    member this.Stop()       = state <- ServiceDisabled
+
+    /// Use the LAPACK service from the given provider.
+    /// If the supporting DLLs are not available, this may fail (now or later).
+    member this.StartWith(p:Provider<'a>) =
+      let justification = 
+          match loadableProvider (loadableDLLPaths()) p with
+          | None                   -> "The provider DLLs did not appear to be present, the service may fail"
+          | Some (p,justification) -> justification      
+      state <- ServiceEnabledOK (p.Provide(),justification)
+
+    /// Start the service with the first provider that looks loadable.     
+    member this.Start() =
+      let candidates = Array.choose (loadableProvider (loadableDLLPaths())) providers
+      if candidates.Length=0 then                                     // guard
+        state <- ServiceEnabledFailed
+        false
+      else
+        let provider,justification = candidates.[0]
+        state <- ServiceEnabledOK (provider.Provide(),justification)  // index covered by guard above
+        true
+
+    member this.Service() = 
+      match state with
+      | ServiceEnabledUninitialised -> this.Start() |> ignore
+      | _ -> ()
+      match state with
+        | ServiceDisabled                          
+        | ServiceEnabledUninitialised  // (The above initialisation call must have failed)
+        | ServiceEnabledFailed                     -> None
+        | ServiceEnabledOK (service,justification) -> Some service
+    
+    member this.Available() =         
+      match state with
+        | ServiceDisabled            
+        | ServiceEnabledFailed        
+        | ServiceEnabledUninitialised              -> false
+        | ServiceEnabledOK (service,justification) -> true
+                        
+    member this.Status() =         
+      match state with
+        | ServiceDisabled                          -> "Disabled"           
+        | ServiceEnabledFailed                     -> "Failed to start"
+        | ServiceEnabledUninitialised              -> "Will auto enable on demand"
+        | ServiceEnabledOK (service,justification) -> "Enabled\n" ^ justification
diff --git a/workyard/math-provider/lapack/service.fsi b/workyard/math-provider/lapack/service.fsi
new file mode 100755
index 0000000..345c6ad
--- /dev/null
+++ b/workyard/math-provider/lapack/service.fsi
@@ -0,0 +1,19 @@
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Math.Experimental
+
+type Provider<'a> =
+    new : name:string * requiredDLLs:string [] * provide:(unit -> 'a) -> Provider<'a>
+    member Provide : unit -> 'a
+    member Name : string
+    member RequiredDLLs : string []
+    member Check : unit -> string  
+  
+type Service<'a> =
+    new : providers:seq<Provider<'a>> -> Service<'a>
+    member Start     : unit -> bool
+    member StartWith : p:Provider<'a> -> unit
+    member Stop      : unit -> unit
+    member Service   : unit -> 'a option
+    member Available : unit -> bool
+    member Status    : unit -> string
+    member Providers : Provider<'a> array with get,set
\ No newline at end of file
diff --git a/workyard/tests/LexAndYaccMiniProject/LexAndYaccMiniProject.fsproj b/workyard/tests/LexAndYaccMiniProject/LexAndYaccMiniProject.fsproj
new file mode 100755
index 0000000..2aac13b
--- /dev/null
+++ b/workyard/tests/LexAndYaccMiniProject/LexAndYaccMiniProject.fsproj
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{3b566646-652d-41ed-95a9-c0da626150c8}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>LexAndYaccMiniProject</RootNamespace>
+    <AssemblyName>LexAndYaccMiniProject</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <Name>LexAndYaccMiniProject</Name>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <Tailcalls>false</Tailcalls>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <WarningLevel>3</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+    <DocumentationFile>bin\Debug\LexAndYaccMiniProject.XML</DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <Tailcalls>true</Tailcalls>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <WarningLevel>3</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+    <DocumentationFile>bin\Release\LexAndYaccMiniProject.XML</DocumentationFile>
+  </PropertyGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition=" Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
+  <Import Project="$(MSBuildExtensionsPath)\FSharp\1.0\FSharp.PowerPack.Targets" />
+  <ItemGroup>
+    <Compile Include="Parser.fsi" />
+    <Compile Include="Parser.fs" />
+    <Compile Include="Lexer.fs" />
+    <Compile Include="Program.fs" />
+    <None Include="App.config">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <FsYacc Include="Parser.fsy">
+      <OtherFlags>--module Parser</OtherFlags>
+    </FsYacc>
+    <FsLex Include="Lexer.fsl">
+      <OtherFlags>--unicode</OtherFlags>
+    </FsLex>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="FSharp.PowerPack, Version=2.0.0.0, Culture=neutral, PublicKeyToken=a19089b1c74d0809" />
+    <Reference Include="mscorlib" />
+    <Reference Include="FSharp.Core" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+  </ItemGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+	     Other similar extension points exist, see Microsoft.Common.targets.
+	<Target Name="BeforeBuild">
+	</Target>
+	<Target Name="AfterBuild">
+	</Target>
+	-->
+</Project>
\ No newline at end of file
diff --git a/workyard/tests/LexAndYaccMiniProject/Lexer.fsl b/workyard/tests/LexAndYaccMiniProject/Lexer.fsl
new file mode 100755
index 0000000..12489c8
--- /dev/null
+++ b/workyard/tests/LexAndYaccMiniProject/Lexer.fsl
@@ -0,0 +1,25 @@
+{
+
+module Lexer
+
+// Opens methods related to fslex.exe
+open Microsoft.FSharp.Text.Lexing
+
+let newline (lexbuf: LexBuffer<_>) = 
+  lexbuf.StartPos <- lexbuf.StartPos.NextLine
+
+}
+
+// Regular expressions
+let whitespace = [' ' '\t' ]
+let newline = ('\n' | '\r' '\n')
+
+rule tokenstream = parse
+// --------------------------
+| "hello" 		{ Parser.HELLO }
+// --------------------------
+| whitespace	{ tokenstream lexbuf }
+| newline	{ newline lexbuf; tokenstream lexbuf }
+// --------------------------
+| _    		{ failwith ("ParseError" + LexBuffer<_>.LexemeString lexbuf) }
+| eof   	{ Parser.EOF }
\ No newline at end of file
diff --git a/workyard/tests/LexAndYaccMiniProject/Parser.fsy b/workyard/tests/LexAndYaccMiniProject/Parser.fsy
new file mode 100755
index 0000000..761e569
--- /dev/null
+++ b/workyard/tests/LexAndYaccMiniProject/Parser.fsy
@@ -0,0 +1,27 @@
+%{
+
+
+%}
+
+// The start token becomes a parser function in the compiled code:
+%start start
+
+// Regular tokens
+%token HELLO
+
+// Misc tokens
+%token EOF
+
+// This is the type of the data produced by a successful reduction of the 'start'
+// symbol:
+%type < int > start
+
+%%
+
+// These are the rules of the grammar along with the F# code of the 
+// actions executed as rules are reduced.  
+start: File EOF { $1 }
+
+File:
+	| HELLO						{ 1 }
+	| HELLO HELLO				    { 2 }
diff --git a/workyard/tests/LexAndYaccMiniProject/Program.fs b/workyard/tests/LexAndYaccMiniProject/Program.fs
new file mode 100755
index 0000000..7fc8fb0
--- /dev/null
+++ b/workyard/tests/LexAndYaccMiniProject/Program.fs
@@ -0,0 +1,32 @@
+// Learn more about F# at http://fsharp.net
+
+open System.IO
+open Microsoft.FSharp.Text.Lexing
+
+let testLexerAndParserFromString text expectedCount = 
+    let lexbuf = LexBuffer<char>.FromString text
+
+    let countFromParser = Parser.start Lexer.tokenstream lexbuf
+
+    printfn "countFromParser: result = %d, expected %d" countFromParser expectedCount
+
+let testLexerAndParserFromFile (fileName:string) expectedCount = 
+    use textReader = new System.IO.StreamReader(fileName)
+    let lexbuf = LexBuffer<char>.FromTextReader textReader
+
+    let countFromParser = Parser.start Lexer.tokenstream lexbuf
+
+    printfn "countFromParser: result = %d, expected %d" countFromParser expectedCount
+
+testLexerAndParserFromString "hello" 1
+testLexerAndParserFromString "hello hello" 2
+
+let testFile = Path.Combine(__SOURCE_DIRECTORY__, "test.txt")
+File.WriteAllText(testFile, "hello hello")
+testLexerAndParserFromFile testFile 2
+
+printfn "Press any key to continue..."
+System.Console.ReadLine() |> ignore
+
+
+
diff --git a/workyard/tests/codedom/CodeDOM.TestSuite.csproj b/workyard/tests/codedom/CodeDOM.TestSuite.csproj
new file mode 100755
index 0000000..0632c91
--- /dev/null
+++ b/workyard/tests/codedom/CodeDOM.TestSuite.csproj
@@ -0,0 +1,91 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{67A52EA3-8915-49D9-B445-945C263CD63E}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <StartupObject>Microsoft.Samples.CodeDomTestSuite.Program</StartupObject>
+    <RootNamespace>CdtSuite</RootNamespace>
+    <NoStandardLibraries>false</NoStandardLibraries>
+    <AssemblyName>CdtSuite</AssemblyName>
+    <PublishUrl>http://localhost/CdtSuite</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Web</InstallFrom>
+    <FallbackCulture>en-US</FallbackCulture>
+    <UpdateEnabled>true</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <UpdateUrlEnabled>false</UpdateUrlEnabled>
+    <ApplicationVersion>1.0.0.*</ApplicationVersion>
+    <ApplicationRevision>0</ApplicationRevision>
+    <IsWebBootstrapper>true</IsWebBootstrapper>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>2.0</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <Optimize>false</Optimize>
+    <OutputPath>.\bin\Debug\</OutputPath>
+    <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
+    <DefineConstants>TRACE;DEBUG;WHIDBEY; FSHARP</DefineConstants>
+    <WarningLevel>4</WarningLevel>
+    <IncrementalBuild>false</IncrementalBuild>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugSymbols>false</DebugSymbols>
+    <Optimize>true</Optimize>
+    <OutputPath>.\bin\Release\</OutputPath>
+    <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
+    <DefineConstants>TRACE;WHIDBEY</DefineConstants>
+    <WarningLevel>4</WarningLevel>
+    <IncrementalBuild>false</IncrementalBuild>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.JScript" />
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <AppDesigner Include="Properties\" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperFile Include="Microsoft.Net.Framework.2.0">
+      <InProject>False</InProject>
+      <ProductName>.NET Framework 2.0</ProductName>
+      <Install>true</Install>
+    </BootstrapperFile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="CodeDomTest\CodeDOM.TestCore.csproj">
+      <Project>{09E715E3-DCEF-4A52-B784-33C52A452117}</Project>
+      <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
+      <Name>CodeDOM.TestCore</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Properties\" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+  <ProjectExtensions>
+    <VisualStudio AllowExistingFolder="true" />
+  </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/workyard/tests/codedom/CodeDomTest/CDHelper.cs b/workyard/tests/codedom/CodeDomTest/CDHelper.cs
new file mode 100755
index 0000000..f17c3f3
--- /dev/null
+++ b/workyard/tests/codedom/CodeDomTest/CDHelper.cs
@@ -0,0 +1,426 @@
+using System;
+using System.CodeDom;
+using System.Reflection;
+using System.Globalization;
+
+namespace Microsoft.Samples.CodeDomTestSuite {
+
+    [CLSCompliant(true)]
+#if WHIDBEY
+    public static class CDHelper {
+#else
+    public class CDHelper {
+#endif
+
+        /////////////////////////////////////////////////////////////
+        // CodeTypeDeclaration helpers
+
+        // classes
+        public static CodeTypeDeclaration CreateClass (string name) {
+            CodeTypeDeclaration ct = new CodeTypeDeclaration (name);
+            ct.IsClass = true;
+
+            return ct;
+        }
+
+        public static CodeTypeDeclaration CreateClass (string name, MemberAttributes attribute) {
+            CodeTypeDeclaration ct = new CodeTypeDeclaration (name);
+            ct.Attributes = attribute;
+            ct.IsClass = true;
+
+            return ct;
+        }
+
+        public static CodeTypeDeclaration CreateClass (string name, MemberAttributes attribute,
+                TypeAttributes typeAttr) {
+            CodeTypeDeclaration ct = new CodeTypeDeclaration (name);
+            ct.Attributes = attribute;
+            ct.TypeAttributes = typeAttr;
+            ct.IsClass = true;
+
+            return ct;
+        }
+
+        public static CodeTypeDeclaration CreateClass (string name, MemberAttributes attribute,
+                TypeAttributes typeAttr, CodeTypeReference[] baseTypes) {
+            CodeTypeDeclaration ct = new CodeTypeDeclaration (name);
+            ct.Attributes = attribute;
+            ct.TypeAttributes = typeAttr;
+            ct.BaseTypes.AddRange (baseTypes);
+            ct.IsClass = true;
+
+            return ct;
+        }
+
+        public static CodeTypeDeclaration CreateClass (string name, MemberAttributes attribute,
+                CodeTypeReference[] baseTypes) {
+            CodeTypeDeclaration ct = new CodeTypeDeclaration (name);
+            ct.Attributes = attribute;
+            ct.BaseTypes.AddRange (baseTypes);
+            ct.IsClass = true;
+
+            return ct;
+        }
+
+        // interfaces
+        public static CodeTypeDeclaration CreateInterface (string name) {
+            CodeTypeDeclaration ct = new CodeTypeDeclaration (name);
+            ct.IsInterface = true;
+
+            return ct;
+        }
+
+        public static CodeTypeDeclaration CreateInterface (string name, MemberAttributes attribute) {
+            CodeTypeDeclaration ct = new CodeTypeDeclaration (name);
+            ct.Attributes = attribute;
+            ct.IsInterface = true;
+
+            return ct;
+        }
+
+        public static CodeTypeDeclaration CreateInterface (string name, MemberAttributes attribute,
+            TypeAttributes typeAttr)
+        {
+            CodeTypeDeclaration ct = new CodeTypeDeclaration (name);
+            ct.Attributes = attribute;
+            ct.TypeAttributes = typeAttr;
+            ct.IsInterface = true;
+
+            return ct;
+        }
+
+        public static CodeTypeDeclaration CreateInterface (string name, MemberAttributes attribute,
+            TypeAttributes typeAttr, CodeTypeReference[] baseTypes)
+        {
+            CodeTypeDeclaration ct = new CodeTypeDeclaration (name);
+            ct.Attributes = attribute;
+            ct.TypeAttributes = typeAttr;
+            ct.BaseTypes.AddRange (baseTypes);
+            ct.IsInterface = true;
+
+            return ct;
+        }
+
+        // end CodeTypeDeclaration helpers
+        /////////////////////////////////////////////////////////////
+
+        // CodeConstructor helpers
+        public static CodeConstructor CreateConstructor () {
+            return new CodeConstructor ();
+        }
+
+        public static CodeConstructor CreateConstructor (MemberAttributes attribute) {
+            CodeConstructor cc = CreateConstructor ();
+            cc.Attributes = attribute;
+
+            return cc;
+        }
+
+        // CodeMemberMethod helpers
+        public static CodeMemberMethod CreateMethod (string name) {
+            CodeMemberMethod cm = new CodeMemberMethod ();
+            cm.Name = name;
+
+            return cm;
+        }
+
+        public static CodeMemberMethod CreateMethod (string name, CodeTypeReference returnType)
+        {
+            CodeMemberMethod cm = CreateMethod (name);
+            cm.ReturnType = returnType;
+
+            return cm;
+        }
+
+        public static CodeMemberMethod CreateMethod (string name, CodeTypeReference returnType,
+            MemberAttributes attribute)
+        {
+            CodeMemberMethod cm = CreateMethod (name, returnType);
+            cm.Attributes = attribute;
+
+            return cm;
+        }
+
+        public static CodeMemberMethod CreateMethod (string name, CodeTypeReference returnType,
+            MemberAttributes attribute, CodeParameterDeclarationExpressionCollection parameters)
+        {
+            CodeMemberMethod cm = CreateMethod (name, returnType, attribute);
+            if (parameters != null)
+                foreach (CodeParameterDeclarationExpression p in parameters)
+                    cm.Parameters.Add (p);
+
+            return cm;
+        }
+
+        // CodeNamespace helpers
+        public static CodeNamespace CreateNamespace (string name) {
+            return new CodeNamespace (name);
+        }
+
+        // CodeParameterDeclarationExpressionCollection helpers
+        // -- this one is possibly dangerous?
+        public static CodeParameterDeclarationExpressionCollection CreateParameterList (params object[] parameters) {
+
+            // must have an even number of arguments for
+            // a list of pairs to be valid
+            if (parameters.Length % 2 != 0)
+                throw new ArgumentException ("Must supply an even number of arguments.");
+
+            CodeParameterDeclarationExpressionCollection exps =
+                new CodeParameterDeclarationExpressionCollection ();
+
+            for (Int32 i = 0; i < parameters.Length; i += 2) {
+                if (!typeof (string).IsInstanceOfType (parameters[i + 1]))
+                    throw new ArgumentException (String.Format (CultureInfo.InvariantCulture,
+                        "Argument {0} should be of type string.", i + 1));
+
+                if (typeof (Type).IsInstanceOfType (parameters[i])) {
+                    exps.Add (new CodeParameterDeclarationExpression (
+                        (Type) parameters[i], (string) parameters[i + 1]));
+                } else if (typeof (string).IsInstanceOfType (parameters[i])) {
+                    exps.Add (new CodeParameterDeclarationExpression (
+                        (string) parameters[i], (string) parameters[i + 1]));
+                } else if (typeof (CodeTypeReference).IsInstanceOfType (parameters[i])) {
+                    exps.Add (new CodeParameterDeclarationExpression (
+                        (CodeTypeReference) parameters[i], (string) parameters[i + 1]));
+                } else {
+                    throw new ArgumentException (String.Format (CultureInfo.InvariantCulture,
+                        "Argument {0} should be of Type, string, or CodeTypeReference.", i));
+                }
+            }
+
+            return exps;
+        }
+
+        // CodeMemberProperty helpers
+        // -- type defined by string
+        public static CodeMemberProperty CreateProperty (string type, string name) {
+            CodeMemberProperty cp = new CodeMemberProperty ();
+            cp.Name = name;
+            cp.Type = new CodeTypeReference (type);
+
+            return cp;
+        }
+
+        public static CodeMemberProperty CreateProperty (string type, string name,
+            MemberAttributes attribute)
+        {
+            CodeMemberProperty cp = CreateProperty (type, name);
+            cp.Attributes = attribute;
+
+            return cp;
+        }
+
+        // -- type defined by Type
+        public static CodeMemberProperty CreateProperty (Type type, string name) {
+            CodeMemberProperty cp = new CodeMemberProperty ();
+            cp.Name = name;
+            cp.Type = new CodeTypeReference (type);
+
+            return cp;
+        }
+
+        public static CodeMemberProperty CreateProperty (Type type, string name,
+            MemberAttributes attribute)
+        {
+            CodeMemberProperty cp = CreateProperty (type, name);
+            cp.Attributes = attribute;
+
+            return cp;
+        }
+
+
+        // -- type defined by CodeTypeReference
+        public static CodeMemberProperty CreateProperty (CodeTypeReference type, string name,
+            MemberAttributes attribute)
+        {
+            CodeMemberProperty cp = CreateProperty (type, name);
+            cp.Attributes = attribute;
+
+            return cp;
+        }
+
+        public static CodeMemberProperty CreateProperty (CodeTypeReference type, string name) {
+            CodeMemberProperty cp = new CodeMemberProperty ();
+            cp.Name = name;
+            cp.Type = type;
+
+            return cp;
+        }
+
+
+        // ----------------------------------------------------
+        // CodeStatement helpers
+
+        // Creates:
+        // for (varName = startVal; varName < limit; varName = varName + 1) {
+        //
+        // }
+        public static CodeIterationStatement CreateCountUpLoop (string varName, int startVal, CodeExpression limit) {
+            CodeIterationStatement iter = new CodeIterationStatement ();
+
+            iter.InitStatement = new CodeAssignStatement (new CodeVariableReferenceExpression (varName),
+                new CodePrimitiveExpression (startVal));
+            iter.TestExpression = new CodeBinaryOperatorExpression (new CodeVariableReferenceExpression (varName),
+                CodeBinaryOperatorType.LessThan, limit);
+            iter.IncrementStatement = new CodeAssignStatement (new CodeVariableReferenceExpression (varName),
+                new CodeBinaryOperatorExpression (new CodeVariableReferenceExpression (varName), CodeBinaryOperatorType.Add,
+                new CodePrimitiveExpression (1)));
+
+            return iter;
+        }
+
+        // creates:
+        // var1 (op) var2
+        //
+        // It automatically boxes any strings as variable references,
+        // ints and doubles become primitives everything else generates a
+        // runtime exception
+        public static CodeBinaryOperatorExpression CreateBinaryOperatorExpression (object var1,
+                CodeBinaryOperatorType op, object var2) {
+
+            if (var1 == null)
+                throw new ArgumentNullException ("var1");
+            if (var2 == null)
+                throw new ArgumentNullException ("var2");
+
+            CodeExpression var1Exp = null;
+            CodeExpression var2Exp = null;
+
+            if (var1 is string)
+                var1Exp = new CodeVariableReferenceExpression ((string) var1);
+            else if (var1 is int)
+                var1Exp = new CodePrimitiveExpression ((int) var1);
+            else if (var1 is double)
+                var1Exp = new CodePrimitiveExpression ((double) var2);
+            else
+                var1Exp = (CodeExpression) var1;
+
+            if (var2 is string)
+                var2Exp = new CodeVariableReferenceExpression ((string) var2);
+            else if (var2 is int)
+                var2Exp = new CodePrimitiveExpression ((int) var2);
+            else if (var2 is double)
+                var2Exp = new CodePrimitiveExpression ((double) var2);
+            else
+                var2Exp = (CodeExpression) var2;
+
+            return new CodeBinaryOperatorExpression (var1Exp, op, var2Exp);
+        }
+
+        // creates:
+        // varName = var1 (OP) var2
+        //
+        // See above for rules about var1, var2
+        public static CodeAssignStatement CreateBinaryOperatorStatement (string varName, object var1, CodeBinaryOperatorType op,
+                object var2) {
+            return new CodeAssignStatement (new CodeVariableReferenceExpression (varName),
+                CreateBinaryOperatorExpression (var1, op, var2));
+        }
+
+
+        // creates:
+        // varName = (type) var1 (OP) var2
+        public static CodeAssignStatement CreateBinaryOperatorStatementWithCast (string varName, CodeTypeReference type,
+               object var1, CodeBinaryOperatorType op, object var2) {
+            return new CodeAssignStatement (new CodeVariableReferenceExpression (varName),
+                new CodeCastExpression (type, CreateBinaryOperatorExpression (var1, op, var2)));
+        }
+
+        // creates:
+        // varName = (type) var1 (OP) var2
+        public static CodeAssignStatement CreateBinaryOperatorStatementWithCast (string varName, Type type,
+               object var1, CodeBinaryOperatorType op, object var2) {
+            return new CodeAssignStatement (new CodeVariableReferenceExpression (varName),
+                new CodeCastExpression (type, CreateBinaryOperatorExpression (var1, op, var2)));
+        }
+
+        // creates:
+        // varName = varName + expression;
+        public static CodeAssignStatement CreateIncrementByStatement (string varName, CodeExpression expression) {
+            return CreateBinaryOperatorStatement (varName, new CodeVariableReferenceExpression (varName),
+                    CodeBinaryOperatorType.Add, expression);
+
+        }
+
+        public static CodeAssignStatement CreateIncrementByStatement (string varName, int expression) {
+            return CreateBinaryOperatorStatement (varName, new CodeVariableReferenceExpression (varName),
+                    CodeBinaryOperatorType.Add, new CodePrimitiveExpression (expression));
+        }
+
+        public static CodeAssignStatement CreateIncrementByStatement (CodeExpression varName, int expression) {
+            return new CodeAssignStatement (varName,
+                    new CodeBinaryOperatorExpression (varName, CodeBinaryOperatorType.Add,
+                        new CodePrimitiveExpression (expression)));
+        }
+
+        public static CodeAssignStatement CreateIncrementByStatement (string varName, string expression) {
+            return CreateBinaryOperatorStatement (varName, new CodeVariableReferenceExpression (varName),
+                    CodeBinaryOperatorType.Add, new CodeVariableReferenceExpression (expression));
+        }
+
+/*        public static CodeAssignStatement CreateIncrementByStatement (CodeExpression varName, string expression) {
+            return new CodeBinaryOperatorExpression (varName,
+                    CodeBinaryOperatorType.Add, new CodeVariableReferenceExpression (expression));
+        }*/
+
+        // creates:
+        // array[index]
+        //
+        // Automatically boxes strings into CodeVariableReferenceExpression
+        public static CodeArrayIndexerExpression CreateArrayRef (string array, string index) {
+            return new CodeArrayIndexerExpression (new CodeVariableReferenceExpression (array),
+                    new CodeVariableReferenceExpression (index));
+        }
+
+        // Same but automatically boxes int into CodePrimitiveExpression
+        public static CodeArrayIndexerExpression CreateArrayRef (string array, int index) {
+            return new CodeArrayIndexerExpression (new CodeVariableReferenceExpression (array),
+                    new CodePrimitiveExpression (index));
+        }
+        
+        // creates:
+        // var.fieldName
+        public static CodeFieldReferenceExpression CreateFieldRef (string var, string fieldName) {
+            return new CodeFieldReferenceExpression (new CodeVariableReferenceExpression (var),
+                    fieldName);
+        }
+
+        // creates:
+        // target.methodName ()
+        //
+        // Boxes all string params as CodeVariableReferenceExpressions,
+        //   CodeExpressions get passed directly in
+        //   all others get boxed as CodePrimitiveExpressions
+        public static CodeMethodInvokeExpression CreateMethodInvoke (CodeExpression target, string methodName,
+                params object [] args) {
+            CodeMethodInvokeExpression exp = new CodeMethodInvokeExpression (
+                    new CodeMethodReferenceExpression (target, methodName));
+            foreach (object a in args) {
+                if (a is string)
+                    exp.Parameters.Add (new CodeVariableReferenceExpression ((string) a));
+                else if (a is CodeExpression)
+                    exp.Parameters.Add ((CodeExpression) a);
+                else
+                    exp.Parameters.Add (new CodePrimitiveExpression (a));
+            }
+
+            return exp;
+        }
+
+        public static CodeStatement ConsoleWriteLineStatement (CodeExpression exp) {
+            return new CodeExpressionStatement (
+                new CodeMethodInvokeExpression (
+                new CodeMethodReferenceExpression (
+                new CodeTypeReferenceExpression (new CodeTypeReference (typeof (System.Console))),
+                "WriteLine"),
+                new CodeExpression[] {
+                    exp,
+                }));
+        }
+
+        public static CodeStatement ConsoleWriteLineStatement (string txt) {
+            return ConsoleWriteLineStatement (new CodePrimitiveExpression (txt));
+        }
+    }
+}
diff --git a/workyard/tests/codedom/CodeDomTest/CodeDOM.TestCore.csproj b/workyard/tests/codedom/CodeDomTest/CodeDOM.TestCore.csproj
new file mode 100755
index 0000000..9f9d0a1
--- /dev/null
+++ b/workyard/tests/codedom/CodeDomTest/CodeDOM.TestCore.csproj
@@ -0,0 +1,57 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{09E715E3-DCEF-4A52-B784-33C52A452117}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>CodeDomTest</RootNamespace>
+    <AssemblyName>CodeDomTest</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>2.0</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>.\bin\Debug\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WHIDBEY; FSHARP</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugSymbols>false</DebugSymbols>
+    <Optimize>true</Optimize>
+    <OutputPath>.\bin\Release\</OutputPath>
+    <DefineConstants>TRACE;WHIDBEY</DefineConstants>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.JScript" />
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CDHelper.cs" />
+    <Compile Include="CodeDomTest.cs" />
+    <Compile Include="CodeDomTestTree.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="SubsetConformance.cs" />
+    <Compile Include="TestTypes.cs" />
+    <AppDesigner Include="Properties\" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+</Project>
\ No newline at end of file
diff --git a/workyard/tests/codedom/CodeDomTest/CodeDOM.TestCore.csproj.user b/workyard/tests/codedom/CodeDomTest/CodeDOM.TestCore.csproj.user
new file mode 100755
index 0000000..a2ec83c
--- /dev/null
+++ b/workyard/tests/codedom/CodeDomTest/CodeDOM.TestCore.csproj.user
@@ -0,0 +1,7 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="">
+    <LastOpenVersion>8.0.40607</LastOpenVersion>
+    <ProjectView>ProjectFiles</ProjectView>
+    <ProjectTrust>0</ProjectTrust>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/workyard/tests/codedom/CodeDomTest/CodeDomTest.cs b/workyard/tests/codedom/CodeDomTest/CodeDomTest.cs
new file mode 100755
index 0000000..46c24e4
--- /dev/null
+++ b/workyard/tests/codedom/CodeDomTest/CodeDomTest.cs
@@ -0,0 +1,490 @@
+using System;
+using System.IO;
+using System.Text;
+using System.CodeDom;
+using System.Security;
+using System.Reflection;
+using System.Collections;
+using System.Diagnostics;
+using System.Globalization;
+using System.CodeDom.Compiler;
+using System.Security.Permissions;
+using System.Runtime.InteropServices;
+
+[assembly:ComVisible(false)]
+[assembly:CLSCompliantAttribute (true)]
+[assembly:FileIOPermission(SecurityAction.RequestMinimum)]
+namespace Microsoft.Samples.CodeDomTestSuite {
+
+    /// <summary>
+    /// Base class for all CodeDom test cases.  You must inherit from this class
+    /// if you are writing a test case for the CodeDom test suite.
+    /// </summary>
+    public abstract class CodeDomTest {
+
+			  /// <summary>
+			  /// Any additional comment needed...
+			  /// </summary>
+		  	public virtual string Comment {
+						get { return ""; }
+		  	}
+
+        /// <summary>
+        /// The classification of this test.  This will determine which
+        /// bucket of test cases this test case falls into.
+        /// </summary>
+        /// <value>The classification of this test case.</value>
+        public abstract TestTypes TestType {
+            get;
+        }
+
+        /// <summary>
+        /// The name of the test case.  This will be displayed to the user.
+        /// The user will also use this name to identify this test case.
+        /// </summary>
+        /// <value>The name of this test case.</value>
+        public abstract string Name {
+            get;
+        }
+
+        /// <summary>
+        /// This will be shown along with the test case name in the list
+        /// of test cases.
+        /// </summary>
+        /// <value>Short description of the test case.</value>
+        public abstract string Description {
+            get;
+        }
+
+        /// <summary>
+        /// Overriden to provide test functionality for the given
+        /// provider.  Return true to signal a test pass, false for
+        /// test failure.  Use LogMessage to output test status
+        /// along the way.
+        /// </summary>
+        /// <param name="provider">Provider to test.</param>
+        /// <returns>True if the test passed.  False otherwise.</returns>
+        public abstract bool Run (CodeDomProvider provider);
+
+        protected bool Supports (CodeDomProvider provider, GeneratorSupport support) {
+#if WHIDBEY
+            return provider.Supports (support);
+#else
+            return (provider.CreateGenerator ()).Supports (support);
+#endif
+        }
+
+        /// <summary>
+        /// Used to drop the given string to the given filename.  All IO
+        /// and security exceptions are caught and displayed using LogMessage.
+        /// </summary>
+        protected void DumpStringToFile (string dumpText, string fileName) {
+            try {
+                using (StreamWriter srcWriter = new StreamWriter (
+                            new FileStream (fileName, FileMode.Create),
+                            Encoding.UTF8)) {
+                    srcWriter.Write (dumpText);
+                }
+            } catch (IOException e) {
+                // catch exceptions here because we want to continue testing if possible
+                LogMessage ("Problem writing to '{0}'.", fileName);
+                LogMessage ("Exception stack:");
+                LogMessage (e.ToString ());
+            } catch (SecurityException e) {
+                // catch exceptions here because we want to continue testing if possible
+                LogMessage ("Problem writing to '{0}'.", fileName);
+                LogMessage ("Exception stack:");
+                LogMessage (e.ToString ());
+            }
+        }
+
+        #region Message logging
+        string indentString = String.Empty;
+        readonly string indentIncrement = "  ";
+        TextWriter log = null;
+        bool echoToConsole = false;
+
+        /// <summary>
+        /// Gets/sets the TextWriter stream that log messages should
+        /// be written to.
+        /// </summary>
+        /// <value>The TextWriter to write messages to.</value>
+        public TextWriter LogStream {
+            get { return log; }
+            set { log = value; }
+        }
+
+        /// <summary>
+        /// In addition to writing to the TextWriter specified by the
+        /// LogStream property, a true EchoToConsole property will also
+        /// echo any output to the console.
+        /// </summary>
+        /// <value>Whether to echo to the console or not.</value>
+        public bool EchoToConsole {
+            get { return echoToConsole; }
+            set { echoToConsole = value; }
+        }
+
+        /// <summary>
+        /// Unindents the current indent string.  Used in combination
+        /// with LogMessageIndent to make output follow a somewhat
+        /// heirachial format.
+        /// </summary>
+        public void LogMessageUnindent () {
+            if (indentString.Length >= 1)
+                indentString = indentString.Substring (indentIncrement.Length);
+        }
+
+        /// <summary>
+        /// Indents the current indent string.  Used in combination
+        /// with LogMessageIndent to make output follow a somewhat
+        /// heirachial format.
+        /// </summary>
+        public void LogMessageIndent () {
+            indentString += indentIncrement;
+        }
+
+        /// <summary>
+        /// Provides communication with the test suite.  Use this to log
+        /// any arbitrary message during any part of your test.
+        /// </summary>
+        /// <param name="txt">The message to log.</param>
+        public void LogMessage (string txt) {
+            // always echo to console if the log stream is null
+            if (log == null || echoToConsole) {
+                Console.Write (indentString);
+                Console.WriteLine (txt);
+            }
+            if (log != null) {
+                log.Write (indentString);
+                log.WriteLine (txt);
+            }
+        }
+
+        /// <summary>
+        /// Provides communication with the test suite.  Use this to log
+        /// any arbitrary message during any part of your test.  This overload
+        /// allows formatting.
+        /// </summary>
+        /// <param name="text">Message to log.  You may use formats as in String.Format.</param>
+        /// <param name="p">Parameters to your message.</param>
+        public void LogMessage (string message, params object[] p) {
+            LogMessage (String.Format (CultureInfo.InvariantCulture, message, p));
+        }
+        #endregion
+
+        #region Common verification routines
+        /// <summary>
+        /// This method finds the given methodName in the type and object
+        /// and invokes it with the given parameters.  If the return value of
+        /// this call matches the given expected return value, VerifyMethod()
+        /// returns true.  False otherwise.  It makes liberal use of LogMessage().
+        /// </summary>
+        /// <param name="container">Type of the given instance.</param>
+        /// <param name="instance">An instantiated object of the given type.</param>
+        /// <param name="methodName">The method to find and invoke.</param>
+        /// <param name="parameters">The parameters to pass to the method.</param>
+        /// <param name="expectedReturn">The expected return value of the method.</param>
+        /// <returns>True if verification succeeded.  False otherwise.</returns>
+        protected bool VerifyMethod (Type container, object instance, string methodName, object[] parameters, object expectedReturn) {
+
+            if (container == null)
+                throw new ArgumentNullException ("container");
+            if (instance == null)
+                throw new ArgumentNullException ("instance");
+            if (methodName == null)
+                throw new ArgumentNullException ("methodName");
+
+            LogMessage ("Calling {0}, expecting '{1}' for a return value.", methodName, expectedReturn);
+
+            // output parameters
+            if (parameters != null) {
+                LogMessage ("with parameters");
+                int i = 0;
+                LogMessageIndent ();
+                foreach (object parameter in parameters) {
+                    LogMessage ("{0}: type={1}, value='{2}'", i++, parameter.GetType (), parameter);
+                }
+                LogMessageUnindent ();
+            }
+
+            Type [] typeArray = parameters == null ? new Type[0] :
+                System.Type.GetTypeArray (parameters);
+            MethodInfo methodInfo = container.GetMethod (methodName, typeArray);
+
+            if (methodInfo == null) {
+                LogMessage ("Unable to get " + methodName);
+                return false;
+            }
+
+            object returnValue = methodInfo.Invoke (instance, parameters == null ?
+                    new Object [0] : parameters);
+
+            if (expectedReturn == null && returnValue == null) {
+                LogMessage ("Return value was '{0}'", returnValue);
+                LogMessage ("");
+                return true;
+            }
+
+            if (returnValue == null) {
+                LogMessage ("Unable to get return value.");
+                return false;
+            }
+            if (returnValue.GetType () != expectedReturn.GetType ()) {
+                LogMessage ("Return value is wrong type. Returned type=" +
+                    returnValue.GetType ().ToString () + ", expected " +
+                    expectedReturn.GetType ().ToString () + ".");
+                return false;
+            }
+            if (!returnValue.Equals (expectedReturn)) {
+                LogMessage ("Return value is incorrect. Returned '" +
+                    returnValue.ToString () + "', expected '" + expectedReturn.ToString () + "'.");
+                return false;
+            }
+
+            LogMessage ("Return value was '{0}'", returnValue);
+            LogMessage ("");
+
+            return true;
+        }
+
+        /// <summary>
+        /// This method finds the given propName in the type and object
+        /// and sets its value with the given object (setVal).  If the set
+        /// succeeds, VerifyPropertySet() returns true.  It makes liberal
+        /// use of LogMessage().
+        /// </summary>
+        /// <param name="container">Type of the given instance.</param>
+        /// <param name="instance">An instantiated object of the given type.</param>
+        /// <param name="propName">Property name to set.</param>
+        /// <param name="setVal">Value to set the property to.</param>
+        /// <returns>True if the operation succeeded.  False otherwise.</returns>
+        protected bool VerifyPropertySet (Type container, object instance, string propName, object setVal) {
+
+            if (container == null)
+                throw new ArgumentNullException ("container");
+            if (instance == null)
+                throw new ArgumentNullException ("instance");
+            if (propName == null)
+                throw new ArgumentNullException ("propName");
+
+            PropertyInfo propInfo;
+
+            LogMessage ("Setting property '{0}' to '{1}'.", propName, setVal);
+            if (setVal != null && setVal.GetType () != null) {
+                propInfo = container.GetProperty(propName, setVal.GetType());
+            } else {
+                propInfo = container.GetProperty(propName);
+            }
+
+            if (propInfo == null) {
+                LogMessage ("Unable to get property '{0}' from the assembly.", propName);
+                return false;
+            }
+
+            propInfo.SetValue(instance, setVal, null);
+
+            LogMessage ("Set.");
+            LogMessage ("");
+            return true;
+        }
+
+        /// <summary>
+        /// This method finds the given propName in the type and object
+        /// and gets its value in order to compare it with the given object
+        /// (expectedReturn).  If they match, VerifyPropertyGet() returns true.
+        /// It makes liberal use of LogMessage().
+        /// </summary>
+        /// <param name="testType">Type of the given instance.</param>
+        /// <param name="instance">An instantiated object of the given type.</param>
+        /// <param name="propName">Property name to get.</param>
+        /// <param name="setVal">Value you expect the property to return.</param>
+        /// <returns>True if the operation succeeded.  False otherwise.</returns>
+        protected bool VerifyPropertyGet (Type container, object instance, string propName, object expectedReturn) {
+
+            if (container == null)
+                throw new ArgumentNullException ("container");
+            if (instance == null)
+                throw new ArgumentNullException ("instance");
+            if (propName == null)
+                throw new ArgumentNullException ("propName");
+
+            PropertyInfo propInfo = null;
+            LogMessage ("Getting property '{0}' expecting '{1}'.", propName, expectedReturn);
+            if (expectedReturn != null && expectedReturn.GetType () != null) {
+                propInfo = container.GetProperty (propName, expectedReturn.GetType ());
+            } else {
+                propInfo = container.GetProperty (propName);
+            }
+
+            if (propInfo == null) {
+                LogMessage ("Unable to get property '{0}'.", propName);
+                return false;
+            }
+
+            object retVal = propInfo.GetValue (instance, new object [0]);
+            if (retVal == null) {
+                LogMessage ("Return value is null.");
+                return false;
+            }
+            if (retVal.GetType () != expectedReturn.GetType ()) {
+                LogMessage ("Return value is wrong type. Returned type=" +
+                        retVal.GetType ().ToString () + ", expected " + expectedReturn.GetType ().ToString () + ".");
+                return false;
+            }
+            if (!retVal.Equals (expectedReturn)) {
+                LogMessage ("Return value is incorrect. Returned '" + retVal.ToString () + "', expected '" + expectedReturn.ToString () + "'.");
+                return false;
+            }
+            LogMessage ("Return value was '{0}'.", retVal);
+            LogMessage ("");
+            return true;
+        }
+
+        /// <summary>
+        /// Verifies that the given exception (expectedException) is thrown
+        /// when the given methodName is called on the instance which is
+        /// of type container with the parameters.  True is returned if this
+        /// is the case.  False otherwise.
+        /// </summary>
+        /// <param name="container">The type in which to find the method.</param>
+        /// <param name="instance">An instantiated object of the given type.</param>
+        /// <param name="methodName">The name of the method to find.</param>
+        /// <param name="parameters">The parameters to pass to the method.</param>
+        /// <param name="expectedException">The expected exception to be thrown.</param>
+        /// <returns>True if the exception was thrown.  False otherwise.</returns>
+        protected bool VerifyException (Type container, object instance, string methodName, object[] parameters, object expectedException) {
+
+            if (container == null)
+                throw new ArgumentNullException ("container");
+            if (instance == null)
+                throw new ArgumentNullException ("instance");
+            if (methodName == null)
+                throw new ArgumentNullException ("methodName");
+            
+            LogMessage ("Calling {0} and expecting {1} to be thrown.", methodName, expectedException.GetType ());
+            MethodInfo methodInfo = container.GetMethod (methodName);
+            if (methodInfo == null) {
+                LogMessage ("Unable to get " + methodName);
+                return false;
+            }
+
+            try {
+                object returnValue = methodInfo.Invoke (instance, parameters);
+            }
+            catch (Exception e) {
+                if (e.GetType () != expectedException.GetType ()) {
+                    LogMessage ("Return value type is incorrect.  Returned " + e.GetType ().ToString ());
+                    return false;
+                }
+            }
+            LogMessage ("Exception was thrown as expected.");
+            LogMessage ("");
+            return true;
+        }
+
+        /// <summary>
+        /// Used for attribute verification.  This method finds the given type
+        /// and attempts to retrieve the value of the property specified in
+        /// propertyName.  It compares this value with the given propertyValue
+        /// and returns true if they match.  False is otherwise returned.  The
+        /// type is searched for in the given attributes array.
+        /// </summary>
+        /// <param name="attributes">Array of objects in which to find the type.</param>
+        /// <param name="type">The type to find.</param>
+        /// <param name="propertyName">The property to validate against.</param>
+        /// <param name="propertyValue">The expected value of this property.</param>
+        /// <returns></returns>
+        protected bool VerifyAttribute (object[] attributes, Type type, string propertyName, object propertyValue) {
+            if (attributes == null)
+                throw new ArgumentNullException ("attributes");
+            if (type == null)
+                throw new ArgumentNullException ("type");
+            if (propertyName == null)
+                throw new ArgumentNullException ("propertyName");
+
+            LogMessage ("Attempting to find attribute " + type.Name);
+            foreach (object attr in attributes) {
+                if (attr.GetType () == type) {
+                    object retVal = type.InvokeMember (propertyName, BindingFlags.GetProperty, null, attr, null, CultureInfo.InvariantCulture);
+                    if (retVal == null) {
+                        LogMessage ("Unable to get return value.");
+                        return false;
+                    }
+                    if (retVal.GetType () != propertyValue.GetType ()) {
+                        LogMessage ("Return value is wrong type. Returned type=" +
+                                retVal.GetType ().ToString () + ", expected " + propertyValue.GetType ().ToString () + ".");
+                        return false;
+                    }
+                    if (!retVal.Equals (propertyValue)) {
+                        LogMessage ("Return value is incorrect. Returned '" +
+                                retVal.ToString () + "', expected '" + propertyValue.ToString () + "'.");
+                        return false;
+                    }
+                    LogMessage ("Found attribute: " + type.Name);
+                    LogMessage ("");
+                    return true;
+                }
+            }
+            LogMessage ("Unable to find attribute: " + type.Name);
+            LogMessage ("");
+            return false;
+        }
+
+        /// <summary>
+        /// Finds and instantiates the given type name in the assembly.  Both the
+        /// type and instantiated object are out parameters.  If the type can't be
+        /// found or instantiated, false is returned.
+        /// </summary>
+        /// <param name="typeName">Type to find in the given assembly.</param>
+        /// <param name="typeAssembly">Assembly to search through for the given type name.</param>
+        /// <param name="obj">Instantiated object of the given type.</param>
+        /// <param name="genType">The type that was found in the assembly.</param>
+        /// <returns>True if the type was found and instantiated, false otherwise.</returns>
+        protected bool FindAndInstantiate (string typeName, Assembly typeAssembly, out object obj, out Type genType) {
+
+            if (typeAssembly == null)
+                throw new ArgumentNullException ("typeAssembly");
+
+            obj = null;
+            if (FindType (typeName, typeAssembly, out genType)) {
+                LogMessage ("Instantiating type '{0}'.", typeName);
+                new ReflectionPermission (ReflectionPermissionFlag.NoFlags).Demand ();
+                obj = Activator.CreateInstance (genType);
+                if (obj == null) {
+                    LogMessage ("Unable to instantiate {0}", typeName);
+                    return false;
+                }
+                LogMessage ("Instantiated.");
+                LogMessage ("");
+                return true;
+            }
+
+            return false;
+        }
+        /// <summary>
+        /// Finds the given type name in the assembly.  The type is an out parameter.
+        /// If the type can't be found, false is returned.
+        /// </summary>
+        /// <param name="typeName">Type to find in the given assembly.</param>
+        /// <param name="typeAssembly">Assembly to search through for the given type name.</param>
+        /// <param name="genType">The type that was found in the assembly.</param>
+        /// <returns>True if the type was found, false otherwise.</returns>
+        protected bool FindType (string typeName, Assembly typeAssembly, out Type genType) {
+            if (typeAssembly == null)
+                throw new ArgumentNullException ("typeAssembly");
+            genType = null;
+            LogMessage ("Finding type '{0}' in the given assembly.", typeName);
+            genType = typeAssembly.GetType (typeName);
+            if (genType == null) {
+                LogMessage ("Unable to get type {0}.", typeName);
+                return false;
+            }
+            LogMessage ("Found.");
+            LogMessage ("");
+            return true;
+        }
+        #endregion
+    }
+}
+
diff --git a/workyard/tests/codedom/CodeDomTest/CodeDomTestTree.cs b/workyard/tests/codedom/CodeDomTest/CodeDomTestTree.cs
new file mode 100755
index 0000000..1f84d3e
--- /dev/null
+++ b/workyard/tests/codedom/CodeDomTest/CodeDomTestTree.cs
@@ -0,0 +1,522 @@
+using System;
+using System.IO;
+using System.CodeDom;
+using System.Reflection;
+using System.Collections;
+using System.Diagnostics;
+using System.Globalization;
+using System.CodeDom.Compiler;
+using System.Runtime.Serialization;
+
+namespace Microsoft.Samples.CodeDomTestSuite {
+    /// <summary>
+    /// Marks incorrect usage of scenario management (AddScenario()/VerifyScenario()).
+    /// </summary>
+    [Serializable]
+    public class ScenarioException : Exception {
+        public ScenarioException() {}
+        public ScenarioException(string s) : base (s) {}
+        public ScenarioException(string s, Exception innerException) : base (s, innerException) {}
+        protected ScenarioException (SerializationInfo info, StreamingContext context) : base(info, context) {}
+    }
+
+    /// <summary>
+    /// Base class for all CodeDom test cases.  You must inherit from this class
+    /// if you are writing a test case for the CodeDom test suite.
+    /// </summary>
+    public abstract class CodeDomTestTree : CodeDomTest {
+        // path to save source and assembly output from the compiler
+        // if specified
+        string saveSourceFileName = String.Empty;
+        string saveAssemblyFileName = String.Empty;
+
+        // used for scenario management (verification) of this test
+        // case
+        ScenarioCollection scenarios = new ScenarioCollection();
+
+        /// <summary>
+        /// A test case that has this set to true and does not compile will be marked
+        /// as failed.
+        /// </summary>
+        /// <value>Whether or not the CodeDom tree should be compiled.</value>
+        public virtual bool ShouldCompile {
+            get {
+                return true;
+            }
+        }
+
+        /// <summary>
+        /// The VerifyAssembly() method of this test case will be called depending on
+        /// this value.
+        /// </summary>
+        /// <value>Whether or not assembly verification should take place.</value>
+        public virtual bool ShouldVerify {
+            get {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// The Search() method will be called depending on this value.
+        /// </summary>
+        /// <value>Whether or not the source code search should take place.</value>
+        public virtual bool ShouldSearch {
+            get {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// Compiler parameters that the test suite should use to compile the generated
+        /// source code.
+        /// </summary>
+        /// <param name="provider">Used to determine if certain compiler switches
+        /// should be on or off (i.e. based on GeneratorSupport).</param>
+        /// <returns>The compiler parameters with which the generated code should be
+        /// compiled.</returns>
+        public virtual CompilerParameters GetCompilerParameters (CodeDomProvider provider) {
+            CompilerParameters parms = new CompilerParameters (new string[] {
+                "System.dll", "System.Windows.Forms.dll", "System.Data.dll",
+                "System.Drawing.dll", "System.Xml.dll"});
+            parms.GenerateExecutable = false;
+            parms.TreatWarningsAsErrors = true;
+            parms.IncludeDebugInformation = true;
+            parms.TempFiles.KeepFiles = false;
+
+            return parms;
+        }
+
+        /// <summary>
+        /// Generator options that the test suite should use to generate the
+        /// source code.
+        /// </summary>
+        /// <param name="provider">Used to determine if certain compiler switches
+        /// should be on or off (i.e. based on GeneratorSupport).</param>
+        /// <returns>The generator options with which the code should be
+        /// generated.</returns>
+        public virtual CodeGeneratorOptions GetGeneratorOptions (CodeDomProvider provider) {
+            CodeGeneratorOptions genOptions = new CodeGeneratorOptions ();
+            return genOptions;
+        }
+
+        /// <summary>
+        /// Save any generated source to this file.
+        /// </summary>
+        /// <value>The string value that points to the file to write
+        /// to.  Will default to writing to the local directory if no
+        /// path is specified in the string.</value>
+        public string SourceFileName {
+            set { saveSourceFileName = value; }
+            get { return saveSourceFileName; }
+        }
+
+        /// <summary>
+        /// Write to the given assembly file name.
+        /// </summary>
+        /// <value>The string that points to the assembly file name
+        /// you would like the compiled code to be saved to.</value>
+        public string AssemblyFileName {
+            set { saveAssemblyFileName = value; }
+            get { return saveAssemblyFileName; }
+        }
+
+        /// <summary>
+        /// Clears all added scenarios.
+        /// </summary>
+        public void ClearScenarios () {
+            scenarios.Clear ();
+        }
+
+        /// <summary>
+        /// This overrides the CodeDomTest Run method that does verification
+        /// on the tree provided in the BuildTree method you provide.
+        /// </summary>
+        /// <param name="provider">Provider to test.</param>
+        /// <returns>True if the tree builds, compiles, searches and passes
+        /// assembly verification.  False if any of these fails.</returns>
+        public override bool Run (CodeDomProvider provider) {
+            bool fail = false;
+
+            // build the tree
+            LogMessageIndent ();
+            LogMessage ("- Generating tree.");
+            CodeCompileUnit cu = new CodeCompileUnit ();
+            LogMessageIndent ();
+            BuildTree (provider, cu);
+            LogMessageUnindent ();
+
+            // validate tree using 'experimental' subset tester
+            // but only if the test believes its in the subset
+            if ((TestType & TestTypes.Subset) != 0) {
+                SubsetConformance subsConf = new SubsetConformance ();
+                LogMessage ("- Checking tree subset conformance.");
+                if (!subsConf.ValidateCodeCompileUnit (cu))
+                    LogMessage ("Failed subset tester: {0}",
+                            subsConf.ToString ());
+            }
+
+            // realize source
+            StringWriter sw = new StringWriter (CultureInfo.InvariantCulture);
+#if WHIDBEY
+            provider.GenerateCodeFromCompileUnit (cu, sw, GetGeneratorOptions (provider));
+#else
+            ICodeGenerator generator = provider.CreateGenerator ();
+            generator.GenerateCodeFromCompileUnit (cu, sw, GetGeneratorOptions (provider));
+#endif
+
+            // only continue if the source could be realized into a string.
+            if (!fail) {
+                string source = sw.ToString ();
+
+                if (saveSourceFileName.Length > 0) {
+                    LogMessage ("- Saving source into '" + saveSourceFileName + "'");
+
+                    // save this source to a file
+                    DumpStringToFile (source, saveSourceFileName);
+                }
+
+                // log the source code
+                //LogMessage (source);
+
+                // search the source if the test case asks us to
+                if (ShouldSearch) {
+                    LogMessageIndent ();
+                    Search (provider, source);
+                    LogMessageUnindent ();
+                }
+                
+                // continue only if the test case wants to compile or verify
+                if (ShouldCompile || ShouldVerify) {
+
+                    // ask the test case which compiler parameters it would like to use
+                    CompilerParameters parms = GetCompilerParameters (provider);
+
+#if FSHARP
+                    // If the generated code has entrypoint, then F# requires us to generate EXE
+                    bool hasEntryPoint = false;
+                    foreach(CodeNamespace ns in cu.Namespaces)
+                        foreach (CodeTypeDeclaration ty in ns.Types)
+                            foreach(CodeTypeMember mem in ty.Members)
+                                if (mem is CodeEntryPointMethod) { hasEntryPoint = true; }
+
+                    // If the output file name is specified then it should be EXE
+                    if (hasEntryPoint && parms.GenerateExecutable == false)
+                    {
+                        parms.GenerateExecutable = true;
+                        if (saveAssemblyFileName.ToLower().EndsWith(".dll"))
+                            saveAssemblyFileName = saveAssemblyFileName.Substring(0, saveAssemblyFileName.Length - 4) + ".exe";
+                    }
+#endif
+                    
+                    // add the appropriate compiler parameters if the user asked us
+                    // to save assemblies to file
+                    if (saveAssemblyFileName.Length > 0) {
+                        parms.OutputAssembly = saveAssemblyFileName;
+                        LogMessage ("- Compiling to '" + saveAssemblyFileName + "'.");
+                    }
+
+                    // always generate in memory for verification purposes
+                    parms.GenerateInMemory = true;
+
+                    // compile!
+#if WHIDBEY
+                    CompilerResults results = provider.CompileAssemblyFromDom (parms, cu);
+#else
+                    ICodeCompiler compiler = provider.CreateCompiler ();
+                    CompilerResults results = compiler.CompileAssemblyFromDom (parms, cu);
+#endif
+
+                    if (results.NativeCompilerReturnValue != 0) {
+                        // compilation failed
+                        fail = true;
+                        LogMessage ("- Compilation failed.");
+                        
+                        // log the compilation failed output
+                        foreach (string msg in results.Output)
+                            LogMessage (msg);
+
+                    } else if (ShouldVerify) {
+                        // compilation suceeded and we are asked to verify the
+                        // compiled assembly
+                        LogMessage ("- Verifying assembly.");
+
+                        // verify the compiled assembly if it's there
+                        if (results.CompiledAssembly != null) {
+                            LogMessageIndent ();
+                            VerifyAssembly (provider, results.CompiledAssembly);
+                            LogMessageUnindent ();
+                        }
+                    }
+                }
+            }
+
+            if (fail || !AreAllValidated ()) {
+                // one of the steps above failed or a scenario was not
+                // verified within the test case
+                fail = true;
+                LogMessage ("! Test '" + Name + "' failed.");
+
+                // output failing scenarios
+                if (!AreAllValidated()) {
+                    LogMessage ("! Failing scenarios:");
+                    foreach (Scenario s in GetNotValidated())
+                    {
+                        LogMessage ("-  " + s.ToString());
+                    }
+                }
+            } else {
+                // test passed
+                LogMessage ("* Test '" + Name + "' passed.");
+            }
+            LogMessageUnindent ();
+
+            // return true on success, false on failure
+            return !fail;
+        }
+
+        /// <summary>
+        /// Takes the given provider and generates a tree in the given CodeCompileUnit.
+        /// This is where the bulk of your test case should reside.  You may use AddScenario()
+        /// as you build your tree to enable scenario verification.
+        /// </summary>
+        /// <param name="provider">The provider that will be used to generate and
+        /// compile the tree.</param>
+        /// <param name="cu">The compile unit on which to build your tree.</param>
+        public abstract void BuildTree (CodeDomProvider provider, CodeCompileUnit cu);
+
+        /// <summary>
+        /// Runs verification of the compiled source code emitted by the provider.  The
+        /// source code is generated from the tree you built in BuildTree().  You should
+        /// use VerifyScenario() to verify any scenarios defined in BuildTree().  You may
+        /// also add new scenarios as long as they are also verified by the end of
+        /// VerifyAssembly()'s execution.  Refer to the accompanying documentation for
+        /// more information on how to write a test case.
+        /// </summary>
+        /// <param name="provider">The provider that was used to compile the given
+        /// assembly.</param>
+        /// <param name="asm">The assembly compiled by the given provider.</param>
+        public abstract void VerifyAssembly (CodeDomProvider provider, Assembly builtAssembly);
+
+        /// <summary>
+        /// Searches the given code output as you define.  The given string will
+        /// be the source code emitted by the given provider that was generated
+        /// from the tree defined in BuildTree().  You should use VerifyScenario()
+        /// as in VerifyAssembly() to match any successful scenarios.
+        /// </summary>
+        /// <param name="provider">The provider used to generate the given
+        /// output code.</param>
+        /// <param name="output">The code generated from the given provider using
+        /// the tree defined in BuildTree().</param>
+        public virtual void Search (CodeDomProvider provider, String output) {}
+
+        /// <summary>
+        /// Adds a scenario to this test case's scenario collection.  The
+        /// key must be unique among this collection otherwise a ScenarioException
+        /// will be thrown.
+        /// </summary>
+        /// <param name="key">A unique key.</param>
+        /// <param name="description">Short description of the scenario.</param>
+        protected void AddScenario(string key, string description) {
+            if (!scenarios.Contains(key))
+                scenarios.Add(key, description);
+            else
+                throw new ScenarioException(String.Format(CultureInfo.InvariantCulture,
+                            "Key {0} already exists.", key));
+        }
+
+        /// <summary>
+        /// Adds a scenario to this test case's scenario collection.  The
+        /// key must be unique among this collection otherwise a ScenarioException
+        /// will be thrown.
+        /// </summary>
+        /// <param name="key">A unique key.</param>
+        protected void AddScenario(string key) {
+            if (!scenarios.Contains(key))
+                scenarios.Add(key);
+            else
+                throw new ScenarioException(String.Format(CultureInfo.InvariantCulture,
+                            "Key {0} already exists.", key));
+        }
+
+        /// <summary>
+        /// Marks the scenario with the given key as validated.  If no scenario
+        /// is found with the given key an exception is thrown.  Also, if the
+        /// given scenario key was already validated an exception is thrown.
+        /// </summary>
+        /// <param name="key">Scenario key to validate.</param>
+        protected void VerifyScenario(string key) {
+            bool found = false;
+            bool alreadyValidated = false;
+
+            foreach (Scenario scenario in scenarios) {
+                if (scenario.KeyMatch(key)) {
+
+                    if (!scenario.Validated) {
+                        scenario.Validated = true;
+                        found = true;
+                    }
+                    else
+                        alreadyValidated = true;
+
+                    break;
+                }
+            }
+
+            if (alreadyValidated)
+                throw new ScenarioException(String.Format(CultureInfo.InvariantCulture,
+                            "Scenario {0} was already validated.", key));
+
+            if (!found)
+                throw new ScenarioException(String.Format(CultureInfo.InvariantCulture,
+                            "Scenario {0} not found.", key));
+        }
+
+        /// <summary>
+        /// If all scenarios in the scenario collection are validated this method
+        /// returns true.
+        /// </summary>
+        /// <returns>True if all scenarios have been validated, false otherwise.</returns>
+        bool AreAllValidated() {
+            bool allValidated = true;
+
+            foreach (Scenario scenario in scenarios) {
+                if (!scenario.Validated)
+                    allValidated = false;
+            }
+
+            return allValidated;
+        }
+
+        /// <returns>The scenarios that have not been validated in this test case.</returns>
+        ScenarioCollection GetNotValidated() {
+            ScenarioCollection unvalidated = new ScenarioCollection();
+
+            foreach (Scenario scenario in scenarios) {
+                if (!scenario.Validated)
+                    unvalidated.Add(scenario);
+            }
+
+            return unvalidated;
+        }
+
+        // Scenario classes (scenario class, exception, collection)
+        #region Scenario management classes
+
+        /// <summary>
+        /// Scenario type.  Describes a scenario by key, description and validity
+        /// flags.  The key of the scenario is the most important, and can be
+        /// any arbitrary string that is not already in the test case's scenario
+        /// collection.  The test case developer should choose this key carefully
+        /// so they can easily search to it when they audit their code.
+        /// </summary>
+        class Scenario {
+            string key;
+            string description;
+            bool   validated;
+
+            /// <summary>
+            /// Creates a new scenario with the given key.  Description is
+            /// set to the empty string, and is marked as not valid.
+            /// </summary>
+            /// <param name="key">Key to give the scenario.</param>
+            public Scenario(string key) {
+                if (key == null)
+                    throw new ArgumentNullException("key");
+
+                this.key = key;
+                this.description = String.Empty;
+                this.validated = false;
+            }
+
+            /// <summary>
+            /// Creates a new scenario with the given key and description.
+            /// It is marked as not valid, by default.
+            /// </summary>
+            /// <param name="key">Key to give the scenario.</param>
+            /// <param name="description">Description that describes the scenario.</param>
+            public Scenario(string key, string description) {
+                if (key == null)
+                    throw new ArgumentNullException("key");
+                if (description == null)
+                    throw new ArgumentNullException("description");
+
+                this.key = key;
+                this.description = description;
+                this.validated = false;
+            }
+
+            /// <value>Unique (among others in its collection) key of this scenario.</value>
+            public string Key {
+                get { return key; }
+            }
+
+            /// <value>Quick description of this scenario to enable the user to get more
+            /// information about what this scenario is about.</value>
+            public string Description
+            {
+                get { return description; }
+            }
+
+            /// <value>True if this scenario has been validated.  False otherwise.</value>
+            public bool Validated {
+                get { return validated; }
+                set { validated = value; }
+            }
+
+            /// <summary>
+            /// Utility function that compares the given string with the internal key.  It
+            /// uses the invariant culture to do a <b>case-insensitive</b> comparison.
+            /// </summary>
+            /// <param name="outKey">String to match to the key.</param>
+            /// <returns>If the key matches the given string, true is returned.  False otherwise</returns>
+            public bool KeyMatch(string outKey) {
+                return String.Compare(outKey, key, true, CultureInfo.InvariantCulture) == 0;
+            }
+
+            /// <returns>Key along with the description of this scenario in a human
+            /// readable format.  No valdiation information is returned.</returns>
+            public override string ToString() {
+                return String.Format(CultureInfo.InvariantCulture, "{0}{1}", key,
+                        (description == null || description.Length <= 0) ?
+                            String.Empty :
+                            (": " + description));
+            }
+        }
+
+        /// <summary>
+        /// Strongly-typed collection for Scenario objects.
+        /// </summary>
+        class ScenarioCollection : CollectionBase {
+            public ScenarioCollection() {
+            }
+
+            public bool Contains(string key) {
+                bool cont = false;
+                foreach (Scenario s in InnerList)
+                    if (s.KeyMatch (key)) {
+                        cont = true;
+                        break;
+                    }
+                return cont;
+            }
+
+            public ScenarioCollection (ScenarioCollection sc) {
+                foreach (Scenario s in sc)
+                    InnerList.Add (s);
+            }
+
+            public void Add (string key, string description) {
+                InnerList.Add (new Scenario(key, description));
+            }
+
+            public void Add (string key) {
+                InnerList.Add (new Scenario(key));
+            }
+
+            public void Add (Scenario s) {
+                InnerList.Add (s);
+            }
+        }
+        #endregion
+    }
+}
diff --git a/workyard/tests/codedom/CodeDomTest/Properties/AssemblyInfo.cs b/workyard/tests/codedom/CodeDomTest/Properties/AssemblyInfo.cs
new file mode 100755
index 0000000..88b6070
--- /dev/null
+++ b/workyard/tests/codedom/CodeDomTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+#region Using directives
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+#endregion
+
+// 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("CodeDomTest")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("CodeDomTest")]
+[assembly: AssemblyCopyright("Copyright @ Microsoft 2004")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.*")]
diff --git a/workyard/tests/codedom/CodeDomTest/Properties/Resources.resx b/workyard/tests/codedom/CodeDomTest/Properties/Resources.resx
new file mode 100755
index 0000000..a814449
--- /dev/null
+++ b/workyard/tests/codedom/CodeDomTest/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?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.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="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" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/workyard/tests/codedom/CodeDomTest/Properties/Settings.settings b/workyard/tests/codedom/CodeDomTest/Properties/Settings.settings
new file mode 100755
index 0000000..c7fa9fb
--- /dev/null
+++ b/workyard/tests/codedom/CodeDomTest/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='iso-8859-1'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>
\ No newline at end of file
diff --git a/workyard/tests/codedom/CodeDomTest/SubsetConformance.cs b/workyard/tests/codedom/CodeDomTest/SubsetConformance.cs
new file mode 100755
index 0000000..52a347b
--- /dev/null
+++ b/workyard/tests/codedom/CodeDomTest/SubsetConformance.cs
@@ -0,0 +1,1155 @@
+using System;
+using System.Text;
+using System.CodeDom;
+using System.Reflection;
+using System.Collections;
+using System.Globalization;
+using System.CodeDom.Compiler;
+using System.Runtime.Serialization;
+
+namespace Microsoft.Samples.CodeDomTestSuite {
+
+    [Serializable]
+    public class SubsetConformanceException : Exception {
+        public SubsetConformanceException () {}
+        public SubsetConformanceException (string e) : base (e) {}
+        public SubsetConformanceException (string message, Exception innerException): base (message, innerException) {}
+        protected SubsetConformanceException (SerializationInfo info, StreamingContext context) : base (info, context) {}
+    }
+
+    public class SubsetConformance {
+
+        Stack errorStack;
+        Stack locationStack;
+
+        public SubsetConformance () {
+            errorStack = new Stack ();
+            locationStack = new Stack ();
+        }
+
+        public void ClearStacks () {
+            errorStack.Clear ();
+            locationStack.Clear ();
+        }
+
+        private void PushLocation (object exp) {
+            locationStack.Push (exp.ToString ());
+        }
+
+        private void PopLocation () {
+            locationStack.Pop ();
+        }
+
+        public override string ToString () {
+            StringBuilder sb = new StringBuilder ();
+            foreach (string error in errorStack)
+                sb.Append (error + Environment.NewLine);
+
+            return sb.ToString ();
+        }
+
+        private string GetLocationStack () {
+            StringBuilder sb = new StringBuilder ();
+
+            bool first = true;
+
+            // show location
+            foreach (string loc in locationStack)
+                if (first) {
+                    sb.AppendFormat ("{0}{1}", loc, Environment.NewLine);
+                    first = false;
+                } else
+                    sb.AppendFormat ("\t-> {0}{1}", loc, Environment.NewLine);
+
+            return sb.ToString ();
+        }
+
+        private void PushError (string error) {
+
+            // push the error on the stack
+            errorStack.Push (GetLocationStack () + "\t*** " + error);
+        }
+
+        // PushError with format
+        private void PushError (string error, params object [] parms) {
+            PushError (String.Format (CultureInfo.InvariantCulture, error, parms));
+        }
+
+        private bool IsSimpleTarget (CodeObject exp) {
+            bool result = false;
+
+            // A Simple Target is any argument, Local Variables, Field references,
+            // Property References, ThisReference, BaseReference, CodeCastExpression,
+            // CodePrimitives, CodeObjectCreate, CodeArrayCreate, TypeOf,
+            // ArrayReferences, TypeReferences
+
+            if (exp == null) {
+                result = true;
+            } else if (exp is CodeTypeReference) {
+                result = ValidateCodeTypeReference ((CodeTypeReference) exp);
+            } else if (exp is CodeExpression) {
+
+                if (exp is CodeVariableReferenceExpression) {
+                    result = ValidateCodeVariableReferenceExpression ((CodeVariableReferenceExpression) exp);
+                }
+
+                else if (exp is CodeThisReferenceExpression) {
+                    result = ValidateCodeThisReferenceExpression ((CodeThisReferenceExpression) exp);
+                }
+
+                else if (exp is CodeBaseReferenceExpression) {
+                    result = ValidateCodeBaseReferenceExpression ((CodeBaseReferenceExpression) exp);
+                }
+
+                else if (exp is CodeTypeOfExpression) {
+                    result = ValidateCodeTypeOfExpression ((CodeTypeOfExpression) exp);
+                }
+
+                else if (exp is CodeTypeReferenceExpression) {
+                    result = ValidateCodeTypeReferenceExpression ((CodeTypeReferenceExpression) exp);
+                }
+
+                else if (exp is CodeFieldReferenceExpression) {
+                    result = ValidateCodeFieldReferenceExpression ((CodeFieldReferenceExpression) exp);
+                }
+
+                else if (exp is CodePropertyReferenceExpression) {
+                    result = ValidateCodePropertyReferenceExpression ((CodePropertyReferenceExpression) exp);
+                }
+                
+                else if (exp is CodeCastExpression) {
+                    result = ValidateCodeCastExpression ((CodeCastExpression) exp);
+                }
+
+                else if (exp is CodePrimitiveExpression) {
+                    result = ValidateCodePrimitiveExpression ((CodePrimitiveExpression) exp);
+                }
+
+                else if (exp is CodeObjectCreateExpression) {
+                    result = ValidateCodeObjectCreateExpression ((CodeObjectCreateExpression) exp);
+                }
+
+                else if (exp is CodeArrayCreateExpression) {
+                    result = ValidateCodeArrayCreateExpression ((CodeArrayCreateExpression) exp);
+                }
+
+                else if (exp is CodeArrayIndexerExpression) {
+                    result = ValidateCodeArrayIndexerExpression ((CodeArrayIndexerExpression) exp);
+                }
+
+                else if (exp is CodeArgumentReferenceExpression) {
+                    result = ValidateCodeArgumentReferenceExpression ((CodeArgumentReferenceExpression) exp);
+                }
+
+                else if (exp is CodeDelegateCreateExpression) {
+                    result = ValidateCodeDelegateCreateExpression ((CodeDelegateCreateExpression) exp);
+                }
+            }
+
+            if (!result)
+                if (exp != null)
+                    PushError ("This is not a Simple Target {0}.", exp.ToString ());
+                else
+                    PushError ("This is not a Simple Target.");
+
+            return result;
+        }
+
+        private bool ValidateCodeParameterDeclarationExpression (CodeParameterDeclarationExpression exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            // all conditions must be met for this to be true at the end
+            // of the method
+            bool allValid = true;
+
+            // A simple parameter has default FieldDirection (In), and is not an array
+            // or is a single-dimensional array. Must not have CustomAttributes.
+
+            if (exp.Direction != FieldDirection.In) {
+                allValid = false;
+                PushError ("Can only be an 'in' direction parameter.");
+            }
+
+            if (exp.Type.ArrayRank > 1) {
+                allValid = false;
+                PushError ("Can only declare single-dimensional array parameters.");
+            }
+
+            if (exp.CustomAttributes.Count > 0) {
+                allValid = false;
+                PushError ("Cannot declare custom attributes on parameters.");
+            }
+
+            if (allValid)
+                result = true;
+
+            PopLocation ();
+            return result;
+        }
+
+
+        /*private bool IsSingleDimensionalArrayType (CodeTypeReference type) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (type.ArrayRank == 1)
+                result = true;
+            else
+                PushError ("Type is not a single dimensional array.")
+
+            PopLocation ();
+            return result;
+        }*/
+
+        private bool IsOfBasicType (object obj) {
+            bool result = false;
+
+            if (obj == null ||
+                    obj is Boolean ||
+                    obj is Byte ||
+                    obj is Int16 ||
+                    obj is Int32 ||
+                    obj is Int64 ||
+                    obj is Single ||
+                    obj is Double ||
+                    obj is Char ||
+                    obj is String)
+                result =  true;
+
+            return result;
+        }
+
+        public bool ValidateCodeCompileUnit (CodeCompileUnit exp) {
+            bool result = true;
+            PushLocation (exp);
+
+            foreach (CodeAttributeDeclaration attr in exp.AssemblyCustomAttributes)
+                if (!ValidateCodeAttributeDeclaration (attr))
+                    result = false;
+
+            foreach (CodeNamespace ns in exp.Namespaces)
+                if (!ValidateCodeNamespace (ns))
+                    result = false;
+
+            PopLocation ();
+            return result;
+        }
+
+        public bool ValidateCodePrimitiveExpression (CodePrimitiveExpression exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (IsOfBasicType (exp.Value))
+                result = true;
+            else
+                PushError ("Value must be a basic type.  Currently it is '{0}'.",
+                        exp != null ? exp.Value.GetType ().ToString () : "null");
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeArrayCreateExpression (CodeArrayCreateExpression exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            // are all conditions valid?
+            bool allValid = true;
+
+            // check the type of the array create
+            if (exp.CreateType.ArrayRank != 1) {
+                allValid = false;
+                PushError ("ArrayRank must be 1.");
+            }
+
+            // check initializers... all must be simple targets and
+            // not arraycreate statements
+
+            foreach (CodeExpression e in exp.Initializers) {
+                if (e is CodeArrayCreateExpression) {
+                    allValid = false;
+                    PushError ("Cannot nest CodeArrayCreateExpressions.");
+                } else if (!IsSimpleTarget (e))
+                    allValid = false;
+            }
+
+            // check size expression
+            if (exp.SizeExpression != null &&
+                    !IsSimpleTarget (exp.SizeExpression))
+                allValid = false;
+
+            if (allValid)
+                result = true;
+
+            PopLocation ();
+            return result;
+        }
+
+        private bool IsValidAttribute (MemberAttributes attr) {
+            bool result = true;
+
+            // TODO: Validate combinations.
+            if ((attr & ~(MemberAttributes.Public |
+                     MemberAttributes.Private |
+                     MemberAttributes.Family |
+                     MemberAttributes.Final |
+                     MemberAttributes.Overloaded |
+                     MemberAttributes.Override |
+                     MemberAttributes.Static |
+                     MemberAttributes.New)) != 0) {
+                result = false;
+                PushError ("Attribute must be some combination of assembly, public, private, family, final, new, overload, and override.");
+            }
+
+            //TODO: FIX SO IT WORKS
+            /*if ((attr & MemberAttributes.Static) != 0 &&
+                    ((attr & MemberAttributes.Public) != 0 ||
+                    (attr & MemberAttributes.Assembly) != 0 ||
+                    (attr & MemberAttributes.Family) != 0)) {
+                result = false;
+                PushError ("Non-private static attributes are not in the subset.");
+            }*/
+
+            return result;
+        }
+
+        private bool IsValidTypeAttribute (TypeAttributes attr) {
+            bool result = true;
+
+            // TODO: Validate combinations.
+            if ((attr & ~(TypeAttributes.Class |
+                     TypeAttributes.Interface |
+                     TypeAttributes.Public |
+                     TypeAttributes.Sealed |
+                     TypeAttributes.Abstract)) != 0) {
+                result = false;
+                PushError ("TypeAttribute must be some combination of class, interface, public, sealed, abstract, or assembly.");
+            }
+
+            return result;
+        }
+
+        public bool ValidateCodeMemberMethod (CodeMemberMethod exp){
+            bool result = true;
+            PushLocation (exp);
+
+            if (!IsValidAttribute (exp.Attributes))
+                result = false;
+
+            foreach (CodeAttributeDeclaration attr in exp.CustomAttributes)
+                if (!ValidateCodeAttributeDeclaration (attr))
+                    result = false;
+
+            foreach (CodeParameterDeclarationExpression param in exp.Parameters) {
+                if (!ValidateCodeParameterDeclarationExpression (param))
+                    result = false;
+            }
+
+            if (exp.ReturnTypeCustomAttributes != null && exp.ReturnTypeCustomAttributes.Count > 0) {
+                PushError ("Cannot use return type custom attributes.");
+                result = false;
+            }
+
+
+            if (exp.ImplementationTypes.Count > 1) {
+                PushError ("ImplementationTypes may only be a collection of one type.");
+                result = false;
+            }
+
+            if (exp.PrivateImplementationType != null &&
+                    (exp.ImplementationTypes != null || exp.ImplementationTypes.Count > 0)) {
+                PushError ("Only one of ImplementationTypes and PrivateImplementationType may be declared at once.");
+                result = false;
+            }
+
+            foreach (CodeStatement stmt in exp.Statements) {
+                if (!ValidateCodeStatement (stmt))
+                    result = false;
+            }
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeExpression (CodeExpression exp){
+            bool result = false;
+
+            if (exp is CodeArrayCreateExpression) {
+                result = ValidateCodeArrayCreateExpression ((CodeArrayCreateExpression) exp);
+            }
+            else if (exp is CodeArrayIndexerExpression) {
+                result = ValidateCodeArrayIndexerExpression ((CodeArrayIndexerExpression) exp);
+            }
+            else if (exp is CodeArgumentReferenceExpression) {
+                result = ValidateCodeArgumentReferenceExpression ((CodeArgumentReferenceExpression) exp);
+            }
+            else if (exp is CodeBaseReferenceExpression) {
+                result = ValidateCodeBaseReferenceExpression ((CodeBaseReferenceExpression) exp);
+            }
+            else if (exp is CodeBinaryOperatorExpression) {
+                result = ValidateCodeBinaryOperatorExpression ((CodeBinaryOperatorExpression) exp);
+            }
+            else if (exp is CodeCastExpression) {
+                result = ValidateCodeCastExpression ((CodeCastExpression) exp);
+            }
+            else if (exp is CodeDelegateCreateExpression) {
+                result = ValidateCodeDelegateCreateExpression ((CodeDelegateCreateExpression) exp);
+            }
+            else if (exp is CodeDelegateInvokeExpression) {
+                result = ValidateCodeDelegateInvokeExpression ((CodeDelegateInvokeExpression) exp);
+            }
+            else if (exp is CodeDirectionExpression) {
+                result = ValidateCodeDirectionExpression ((CodeDirectionExpression) exp);
+            }
+            else if (exp is CodeEventReferenceExpression) {
+                result = ValidateCodeEventReferenceExpression ((CodeEventReferenceExpression) exp);
+            }
+            else if (exp is CodeFieldReferenceExpression) {
+                result = ValidateCodeFieldReferenceExpression ((CodeFieldReferenceExpression) exp);
+            }
+            else if (exp is CodeIndexerExpression) {
+                result = ValidateCodeIndexerExpression ((CodeIndexerExpression) exp);
+            }
+            else if (exp is CodeMethodInvokeExpression) {
+                result = ValidateCodeMethodInvokeExpression ((CodeMethodInvokeExpression) exp);
+            }
+            else if (exp is CodeMethodReferenceExpression) {
+                result = ValidateCodeMethodReferenceExpression ((CodeMethodReferenceExpression) exp);
+            }
+            else if (exp is CodeObjectCreateExpression) {
+                result = ValidateCodeObjectCreateExpression ((CodeObjectCreateExpression) exp);
+            }
+            else if (exp is CodeParameterDeclarationExpression) {
+                result = ValidateCodeParameterDeclarationExpression ((CodeParameterDeclarationExpression) exp);
+            }
+            else if (exp is CodePrimitiveExpression) {
+                result = ValidateCodePrimitiveExpression ((CodePrimitiveExpression) exp);
+            }
+            else if (exp is CodePropertyReferenceExpression) {
+                result = ValidateCodePropertyReferenceExpression ((CodePropertyReferenceExpression) exp);
+            }
+            else if (exp is CodePropertySetValueReferenceExpression) {
+                result = ValidateCodePropertySetValueReferenceExpression ((CodePropertySetValueReferenceExpression) exp);
+            }
+            else if (exp is CodeSnippetExpression) {
+                result = ValidateCodeSnippetExpression ((CodeSnippetExpression) exp);
+            }
+            else if (exp is CodeThisReferenceExpression) {
+                result = ValidateCodeThisReferenceExpression ((CodeThisReferenceExpression) exp);
+            }
+            else if (exp is CodeTypeOfExpression) {
+                result = ValidateCodeTypeOfExpression ((CodeTypeOfExpression) exp);
+            }
+            else if (exp is CodeTypeReferenceExpression) {
+                result = ValidateCodeTypeReferenceExpression ((CodeTypeReferenceExpression) exp);
+            }
+            else if (exp is CodeVariableReferenceExpression) {
+                result = ValidateCodeVariableReferenceExpression ((CodeVariableReferenceExpression) exp);
+            }
+            else {
+                PushError ("Cannot validate an unknown CodeExpression.");
+                result = false;
+            }
+
+            return result;
+        }
+
+        public bool ValidateCodeTypeMember (CodeTypeMember exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (exp is CodeMemberEvent) {
+                result = ValidateCodeMemberEvent ((CodeMemberEvent) exp);
+            }
+
+            else if (exp is CodeMemberField) {
+                result = ValidateCodeMemberField ((CodeMemberField) exp);
+            }
+
+            else if (exp is CodeMemberMethod) {
+                result = ValidateCodeMemberMethod ((CodeMemberMethod) exp);
+            }
+
+            else if (exp is CodeMemberProperty) {
+                result = ValidateCodeMemberProperty ((CodeMemberProperty) exp);
+            }
+
+            else if (exp is CodeSnippetTypeMember) {
+                result = ValidateCodeSnippetTypeMember ((CodeSnippetTypeMember) exp);
+            }
+
+            else if (exp is CodeTypeDeclaration) {
+                result = ValidateCodeTypeDeclaration ((CodeTypeDeclaration) exp);
+            }
+            else {
+                PushError ("Cannot validate an unknown CodeExpression.");
+                result = false;
+            }
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeStatement (CodeStatement exp){
+            bool result = false;
+            PushLocation (exp);
+
+            // branch off into the corresponding statement based on the type
+            if (exp is CodeAssignStatement) {
+                result = ValidateCodeAssignStatement ((CodeAssignStatement) exp);
+            }
+            else if (exp is CodeAttachEventStatement) {
+                result = ValidateCodeAttachEventStatement ((CodeAttachEventStatement) exp);
+            }
+            else if (exp is CodeCommentStatement) {
+                result = ValidateCodeCommentStatement ((CodeCommentStatement) exp);
+            }
+            else if (exp is CodeConditionStatement) {
+                result = ValidateCodeConditionStatement ((CodeConditionStatement) exp);
+            }
+            else if (exp is CodeExpressionStatement) {
+                result = ValidateCodeExpressionStatement ((CodeExpressionStatement) exp);
+            }
+            else if (exp is CodeGotoStatement) {
+                result = ValidateCodeGotoStatement ((CodeGotoStatement) exp);
+            }
+            else if (exp is CodeIterationStatement) {
+                result = ValidateCodeIterationStatement ((CodeIterationStatement) exp);
+            }
+            else if (exp is CodeLabeledStatement) {
+                result = ValidateCodeLabeledStatement ((CodeLabeledStatement) exp);
+            }
+            else if (exp is CodeMethodReturnStatement) {
+                result = ValidateCodeMethodReturnStatement ((CodeMethodReturnStatement) exp);
+            }
+            else if (exp is CodeRemoveEventStatement) {
+                result = ValidateCodeRemoveEventStatement ((CodeRemoveEventStatement) exp);
+            }
+            else if (exp is CodeSnippetStatement) {
+                result = ValidateCodeSnippetStatement ((CodeSnippetStatement) exp);
+            }
+            else if (exp is CodeThrowExceptionStatement) {
+                result = ValidateCodeThrowExceptionStatement ((CodeThrowExceptionStatement) exp);
+            }
+            else if (exp is CodeTryCatchFinallyStatement) {
+                result = ValidateCodeTryCatchFinallyStatement ((CodeTryCatchFinallyStatement) exp);
+            }
+            else if (exp is CodeVariableDeclarationStatement) {
+                result = ValidateCodeVariableDeclarationStatement ((CodeVariableDeclarationStatement) exp);
+            } else {
+                PushError ("Cannot validate an unknown statement.");
+                result = false;
+            }
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeObjectCreateExpression (CodeObjectCreateExpression exp){
+            bool result = true;
+            PushLocation (exp);
+
+            foreach (CodeExpression e in exp.Parameters)
+                if (!IsSimpleTarget (e))
+                    result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeCastExpression (CodeCastExpression exp){
+            bool result = false;
+            PushLocation (exp);
+
+            if (IsSimpleTarget (exp.Expression))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeFieldReferenceExpression (CodeFieldReferenceExpression exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (IsSimpleTarget (exp.TargetObject))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodePropertyReferenceExpression (CodePropertyReferenceExpression exp){
+            bool result = false;
+            PushLocation (exp);
+
+            if (IsSimpleTarget (exp.TargetObject))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+
+        public bool ValidateCodeAssignStatement (CodeAssignStatement exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (IsSimpleTarget (exp.Left) &&
+                    ValidateCodeExpression (exp.Right))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeAttributeArgument (CodeAttributeArgument exp){
+            bool result = true;
+            PushLocation(exp);
+
+            if (exp.Name != null && exp.Name.Length > 0) {
+                PushError ("Cannot use named attribute arguments.");
+                result = false;
+            }
+
+            if (!IsSimpleTarget (exp.Value))
+                result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeAttributeDeclaration (CodeAttributeDeclaration exp) {
+            bool result = true;
+            PushLocation(exp);
+
+            foreach (CodeAttributeArgument arg in exp.Arguments)
+                if (!ValidateCodeAttributeArgument (arg))
+                    result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeAttachEventStatement (CodeAttachEventStatement exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (ValidateCodeEventReferenceExpression (exp.Event) &&
+                    IsSimpleTarget (exp.Listener))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeCommentStatement (CodeCommentStatement exp) {
+            PushLocation (exp);
+
+            bool result = ValidateCodeComment (exp.Comment);
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeComment (CodeComment exp){
+            return true;
+        }
+
+        public bool ValidateCodeConditionStatement (CodeConditionStatement exp) {
+            bool result = true;
+            PushLocation (exp);
+
+            // are binary ops allowed?  I sure hope so.
+            if (!(exp.Condition is CodeBinaryOperatorExpression) &&
+                    !IsSimpleTarget (exp.Condition))
+                result = false;
+
+            foreach (CodeStatement stmt in exp.FalseStatements)
+                if (!ValidateCodeStatement (stmt))
+                    result = false;
+
+            foreach (CodeStatement stmt in exp.TrueStatements)
+                if (!ValidateCodeStatement (stmt))
+                    result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeConstructor (CodeConstructor exp){
+            bool result = true;
+            PushLocation(exp);
+
+            foreach (CodeExpression e in exp.BaseConstructorArgs)
+                if (!IsSimpleTarget (e))
+                    result = false;
+
+            if (exp.ChainedConstructorArgs != null ||
+                    exp.ChainedConstructorArgs.Count > 0) {
+                PushError ("Chained constructors are not in the subset.");
+                result = false;
+            }
+
+            if (!(((exp.Attributes & ~MemberAttributes.Assembly) == 0 &&
+                    (exp.Attributes & MemberAttributes.Assembly) != 0) &&
+                        (exp.Attributes & ~MemberAttributes.Family) == 0 &&
+                            (exp.Attributes & MemberAttributes.Family) != 0) &&
+                        ((exp.Attributes & ~MemberAttributes.Public) == 0 &&
+                            (exp.Attributes & MemberAttributes.Public) != 0) &&
+                        ((exp.Attributes & ~MemberAttributes.Private) == 0 &&
+                            (exp.Attributes & MemberAttributes.Private) != 0)) {
+                PushError ("Attributes must be one of Assembly, Family, Private or Public.");
+                result = false;
+            }
+
+            foreach (CodeParameterDeclarationExpression param in exp.Parameters)
+                if (!ValidateCodeParameterDeclarationExpression (param))
+                    result = false;
+
+            foreach (CodeStatement stmt in exp.Statements)
+                if (!ValidateCodeStatement (stmt))
+                    result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeDelegateCreateExpression (CodeDelegateCreateExpression exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (IsSimpleTarget (exp.TargetObject))
+                result = true;
+
+            PopLocation ();
+            return result;
+        }
+
+        public bool ValidateCodeExpressionStatement (CodeExpressionStatement exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (ValidateCodeExpression (exp.Expression))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeGotoStatement (CodeGotoStatement exp) {
+            PushError ("CodeGotoStatement is not allowed.");
+            return false;
+        }
+
+        public bool ValidateCodeIterationStatement (CodeIterationStatement exp) {
+            bool result = true;
+            PushLocation (exp);
+
+            if (!ValidateCodeStatement (exp.IncrementStatement))
+                result = false;
+
+            if (!ValidateCodeStatement (exp.InitStatement))
+                result = false;
+
+            if (exp.IncrementStatement is CodeVariableDeclarationStatement ||
+                exp.InitStatement is CodeVariableDeclarationStatement) {
+                PushError ("Increment and/or init statements may not be variable declarations.");
+                result = false;
+            }
+
+            foreach (CodeStatement stmt in exp.Statements)
+                if (!ValidateCodeStatement (stmt))
+                    result = false;
+
+            // may need to add something about simple targets
+            if (!ValidateCodeExpression (exp.TestExpression))
+                result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeLabeledStatement (CodeLabeledStatement exp) {
+            PushError ("CodeLabeledStatement is not allowed.");
+            return false;
+        }
+
+        public bool ValidateCodeMethodReturnStatement (CodeMethodReturnStatement exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (ValidateCodeExpression (exp.Expression))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeNamespace (CodeNamespace exp) {
+            bool result = true;
+            PushLocation (exp);
+
+            foreach (CodeCommentStatement comment in exp.Comments)
+                if (!ValidateCodeCommentStatement (comment))
+                    result = false;
+
+            foreach (CodeNamespaceImport import in exp.Imports)
+                if (!ValidateCodeNamespaceImport (import))
+                    result = false;
+
+            foreach (CodeTypeDeclaration decl in exp.Types)
+                if (!ValidateCodeTypeDeclaration (decl))
+                    result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeNamespaceImport (CodeNamespaceImport exp) {
+            return true;
+        }
+
+        public bool ValidateCodeRemoveEventStatement (CodeRemoveEventStatement exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (IsSimpleTarget (exp.Listener) &&
+                    ValidateCodeEventReferenceExpression (exp.Event))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeSnippetStatement (CodeSnippetStatement exp) {
+            return true;
+        }
+
+        public bool ValidateCodeThrowExceptionStatement (CodeThrowExceptionStatement exp) {
+            PushError ("CodeThrowExceptionStatement is not in the subset.");
+            return false;
+        }
+
+        public bool ValidateCodeTryCatchFinallyStatement (CodeTryCatchFinallyStatement exp) {
+            PushError ("CodeTryCatchFinallyStatement is not in the subset.");
+            return false;
+        }
+
+        public bool ValidateCodeVariableDeclarationStatement (CodeVariableDeclarationStatement exp) {
+            bool result = true;
+            PushLocation (exp);
+
+            if (exp.InitExpression != null && !ValidateCodeExpression (exp.InitExpression))
+                result = false;
+
+            PopLocation();
+            return result;
+        }
+
+
+        public bool ValidateCodeArgumentReferenceExpression (CodeArgumentReferenceExpression exp) {
+            return true;
+        }
+
+        public bool ValidateCodeArrayIndexerExpression (CodeArrayIndexerExpression exp) {
+            bool result = true;
+            PushLocation (exp);
+
+            if (exp.Indices != null && exp.Indices.Count > 0) {
+                if (exp.Indices.Count > 1) {
+                    PushError ("Can only have one index.");
+                    result = false;
+                } else {
+                    if (!IsSimpleTarget (exp.Indices[0]))
+                        result = false;
+                }
+            }
+
+            if (!IsSimpleTarget (exp.TargetObject))
+                result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeBaseReferenceExpression (CodeBaseReferenceExpression exp) {
+            // could include code that looks up the location stack to see if there's a type member
+            // that has a MemberAttribute of Override
+            return true;
+        }
+
+        public bool ValidateCodeBinaryOperatorExpression (CodeBinaryOperatorExpression exp) {
+            bool result = true;
+            PushLocation (exp);
+
+            if (!IsSimpleTarget (exp.Left)) {
+                PushError ("Left must be a simple target.");
+                result = false;
+            }
+
+            if (!IsSimpleTarget (exp.Right)) {
+                PushError ("Right must be a simple target.");
+                result = false;
+            }
+
+            if (((exp.Left is CodePrimitiveExpression &&
+                    ((CodePrimitiveExpression) exp.Left).Value is String) ||
+                (exp.Right is CodePrimitiveExpression &&
+                    ((CodePrimitiveExpression) exp.Right).Value is String)) &&
+                exp.Operator != CodeBinaryOperatorType.Add) {
+
+                PushError ("Can only use add operator when either operand is a string.");
+                result = false;
+            }
+
+
+            // what about !=????
+            if (exp.Operator == CodeBinaryOperatorType.IdentityEquality ||
+                exp.Operator == CodeBinaryOperatorType.Assign) {
+                PushError ("May not use operator {0}.", Enum.Format (typeof (CodeBinaryOperatorType),
+                            exp.Operator, "F"));
+                result = false;
+            }
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeDelegateInvokeExpression (CodeDelegateInvokeExpression exp) {
+            bool result = true;
+            PushLocation (exp);
+
+            foreach (CodeExpression e in exp.Parameters)
+                if (!IsSimpleTarget (e))
+                    result = false;
+
+            if (exp.TargetObject != null && !IsSimpleTarget (exp.TargetObject))
+                result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeDirectionExpression (CodeDirectionExpression exp) {
+            PushError ("CodeDirectionExpression is not allowed.");
+            return false;
+        }
+
+        public bool ValidateCodeEventReferenceExpression (CodeEventReferenceExpression exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (IsSimpleTarget (exp.TargetObject))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeIndexerExpression (CodeIndexerExpression exp) {
+            bool result = true;
+            PushLocation (exp);
+
+            if (!IsSimpleTarget (exp.TargetObject))
+                result = false;
+
+            if (exp.Indices == null || exp.Indices.Count != 1) {
+                PushError ("There must be at least one index.");
+                result = false;
+            }
+
+            if (exp.Indices.Count == 1 && !IsSimpleTarget (exp.Indices[0])) {
+                PushError ("Index must be a simple target.");
+                result = false;
+            }
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeMethodInvokeExpression (CodeMethodInvokeExpression exp) {
+            bool result = true;
+            PushLocation (exp);
+
+            if (!ValidateCodeMethodReferenceExpression (exp.Method))
+                result = false;
+
+            foreach (CodeExpression e in exp.Parameters)
+                if (!IsSimpleTarget (e))
+                    result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeMethodReferenceExpression (CodeMethodReferenceExpression exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (IsSimpleTarget (exp.TargetObject))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodePropertySetValueReferenceExpression (CodePropertySetValueReferenceExpression exp) {
+            return true;
+        }
+
+        public bool ValidateCodeSnippetExpression (CodeSnippetExpression exp) {
+            return true;
+        }
+
+        public bool ValidateCodeThisReferenceExpression (CodeThisReferenceExpression exp) {
+            return true;
+        }
+
+        public bool ValidateCodeTypeOfExpression (CodeTypeOfExpression exp) {
+            return true;
+        }
+
+        public bool ValidateCodeTypeReferenceExpression (CodeTypeReferenceExpression exp) {
+            bool result = false;
+            PushLocation (exp);
+
+            if (ValidateCodeTypeReference (exp.Type))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeVariableReferenceExpression (CodeVariableReferenceExpression exp) {
+            return true;
+        }
+
+
+        public bool ValidateCodeMemberEvent (CodeMemberEvent exp) {
+            bool result = false;
+            PushLocation(exp);
+
+            if (IsValidAttribute (exp.Attributes) &&
+                    ValidateCodeTypeReference (exp.Type))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeMemberField (CodeMemberField exp) {
+            bool result = false;
+            PushLocation(exp);
+
+            if (IsValidAttribute (exp.Attributes) &&
+                    IsSimpleTarget (exp.InitExpression))
+                result = true;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeMemberProperty (CodeMemberProperty exp) {
+            bool result = true;
+            PushLocation(exp);
+
+            if (!IsValidAttribute (exp.Attributes))
+                result = false;
+
+            if (exp.Parameters != null && exp.Parameters.Count > 0) {
+                PushError ("Cannot use parameters with properties.");
+                result = false;
+            }
+
+            foreach (CodeAttributeDeclaration attr in exp.CustomAttributes)
+                if (!ValidateCodeAttributeDeclaration (attr))
+                    result = false;
+
+            if (exp.ImplementationTypes.Count > 1) {
+                PushError ("ImplementationTypes may only be a collection of one type.");
+                result = false;
+            }
+
+            if (exp.PrivateImplementationType != null &&
+                    (exp.ImplementationTypes != null || exp.ImplementationTypes.Count > 0)) {
+                PushError ("Only one of ImplementationTypes and PrivateImplementationType may be declared at once.");
+                result = false;
+            }
+
+            foreach (CodeStatement stmt in exp.SetStatements) {
+                if (!ValidateCodeStatement (stmt))
+                    result = false;
+            }
+
+            foreach (CodeStatement stmt in exp.GetStatements) {
+                if (!ValidateCodeStatement (stmt))
+                    result = false;
+            }
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeSnippetTypeMember (CodeSnippetTypeMember exp) {
+            return true;
+        }
+
+        public bool ValidateCodeTypeDeclaration (CodeTypeDeclaration exp) {
+            bool result = true;
+            PushLocation(exp);
+
+            /*if (((exp.Attributes & MemberAttributes.Public) != 0 &&
+                    (exp.Attributes & MemberAttributes.Private) != 0) ||
+                    (((exp.Attributes & MemberAttributes.Public) == 0) &&
+                        (exp.Attributes & MemberAttributes.Private) == 0)) {
+                PushError ("Attributes must be either public or private.  Attributes currently are {0}.",
+                        Enum.Format (typeof (MemberAttributes), exp.Attributes, "F"));
+                result = false;
+            }*/
+
+            if ((exp.IsClass && (exp.IsEnum || exp.IsStruct || exp.IsInterface)) ||
+                    (exp.IsEnum && (exp.IsClass || exp.IsStruct || exp.IsInterface)) ||
+                    (exp.IsStruct && (exp.IsEnum || exp.IsClass || exp.IsInterface)) ||
+                    (exp.IsInterface && (exp.IsEnum || exp.IsStruct || exp.IsClass))) {
+                PushError ("Only one of IsClass, IsEnum, IsStruct, and IsInterface may be defined at any given time.");
+                result = false;
+            }
+
+            if (exp.IsEnum || exp.IsStruct) {
+                PushError ("Enumerations and structs are not in the subset.");
+                result = false;
+            }
+
+            foreach (CodeTypeMember mem in exp.Members) {
+                if (mem is CodeTypeDeclaration) {
+                    PushError ("Cannot nest type declarations.");
+                    result = false;
+                } else if (!ValidateCodeTypeMember (mem))
+                    result = false;
+            }
+
+            if (!IsValidTypeAttribute (exp.TypeAttributes))
+                result = false;
+
+            PopLocation();
+            return result;
+        }
+
+        public bool ValidateCodeTypeReference (CodeTypeReference exp){
+            bool result = true;
+            PushLocation(exp);
+
+            if (exp.ArrayRank != 0 && exp.ArrayRank != 1) {
+                PushError ("Arrays may only be single dimensional.");
+                result = false;
+            }
+
+            PopLocation();
+            return result;
+        }
+
+
+    }
+}
diff --git a/workyard/tests/codedom/CodeDomTest/TestTypes.cs b/workyard/tests/codedom/CodeDomTest/TestTypes.cs
new file mode 100755
index 0000000..cd393e4
--- /dev/null
+++ b/workyard/tests/codedom/CodeDomTest/TestTypes.cs
@@ -0,0 +1,11 @@
+
+namespace Microsoft.Samples.CodeDomTestSuite {
+    [System.Flags]
+    public enum TestTypes {
+        None           = 0x0000,
+        Subset         = 0x0001,
+        Everett        = 0x0002,
+        Whidbey        = 0x0004,
+    }
+}
+
diff --git a/workyard/tests/codedom/Program.cs b/workyard/tests/codedom/Program.cs
new file mode 100755
index 0000000..953d74f
--- /dev/null
+++ b/workyard/tests/codedom/Program.cs
@@ -0,0 +1,1142 @@
+using System;
+using System.IO;
+using System.Text;
+using System.CodeDom;
+using System.Security;
+using System.Reflection;
+using System.Collections;
+using System.Diagnostics;
+using System.Configuration;
+using System.Globalization;
+using System.CodeDom.Compiler;
+using System.Security.Permissions;
+using System.Text.RegularExpressions;
+using System.Collections.Specialized;
+using System.Runtime.InteropServices;
+
+using Microsoft.CSharp;
+using Microsoft.VisualBasic;
+using Microsoft.JScript;
+
+[assembly:ComVisible (false)]
+[assembly:CLSCompliantAttribute (true)]
+[assembly:FileIOPermission (SecurityAction.RequestMinimum)]
+namespace Microsoft.Samples.CodeDomTestSuite {
+
+#if WHIDBEY
+    public static class Program {
+#else
+    public class Program {
+#endif
+
+        // returns true if an intformational option
+        // was printed
+        static bool PrintInformationalOptions (TestTypes setType) {
+
+            // only print help if it is specified
+            if (GetOption ("help").Set) {
+                PrintUsage (true);
+                return true;
+            }
+
+            // list tests
+            if (GetOption ("list").Set) {
+                PrintTestList (setType, false);
+                return true;
+            } else if (GetOption ("listdesc").Set) {
+                PrintTestList (setType, true);
+                return true;
+            }
+            
+            // list valid sets
+            if (GetOption ("setlist").Set) {
+                Console.WriteLine ("Sets of tests:");
+                foreach (TestTypeOption opt in testTypeOptions) {
+                    Console.WriteLine ("-  " + opt.Name);
+                }
+                return true;
+            }
+
+#if !WHIDBEY
+            if (GetOption ("languagename").Set) {
+                // lang is not supported in non-Whidbey environements
+                ErrorWriteLine ("The /languagename (short: /lang) option was not compiled into this assembly, ");
+                ErrorWriteLine ("and is not supported.  Did you compile with /d:WHIDBEY?");
+                return true;
+            }
+#endif
+
+            // check for required options
+            if ((!GetOption ("codedomprovider").Set || !GetOption ("languagename").Set) &&
+                    !GetOption ("testcaselib").Set) {
+                PrintUsage (false);
+                ErrorWriteLine ();
+                ErrorWriteLine ("Missing required options.");
+                return true;
+            }
+
+            return false;
+        }
+
+        static void ProcessOptionFile () {
+            string currentFile = String.Empty;
+
+            // attempt reading the specified configuration file(s)
+            foreach (string file in GetOption ("optionfile").Values) {
+                currentFile = file;
+                using (StreamReader rdr = new StreamReader (currentFile)) {
+                    string    line  = null;
+                    ArrayList lines = new ArrayList ();
+
+                    while ((line = rdr.ReadLine ()) != null)
+                        lines.Add (line);
+
+                    if (!ParseArgs ((string[]) lines.ToArray (typeof (string)), true)) {
+                        throw new InvalidOperationException (String.Format (CultureInfo.CurrentCulture,
+                                    "Invalid options specified in '{0}'.", currentFile));
+                    }
+                }
+            }
+        }
+
+        // process the -set option
+        static TestTypes ProcessSetOption () {
+            TestTypes setType = TestTypes.None;
+            if (GetOption ("set").Set) {
+
+                // get the TestTypeOption as described by the command-line argument
+                // -set
+                string option = GetOption("set").GetSingleValue ();
+                TestTypeOption opt = null;
+
+                foreach (TestTypeOption ttopt in testTypeOptions) {
+                    if (ttopt.IsSameName (option))
+                        opt = ttopt;
+                }
+
+                if (opt == null)
+                    throw new InvalidOperationException (String.Format (CultureInfo.CurrentCulture,
+                                "Invalid set '{0}' specified.", GetOption ("set").GetSingleValue ()));
+                
+                // determine version compatibility
+                if (!opt.IsVersionCompatible (Environment.Version)) {
+                    ErrorWriteLine ("Given set of tests may not function properly because your current");
+                    ErrorWriteLine ("runtime version {0} is less than the tests' required runtime {1}.",
+                            Environment.Version, opt.RuntimeVersion);
+                }
+
+                setType = opt.Types;
+            }
+
+            return setType;
+        }
+
+        [STAThread]
+        public static void Main (string[] args) {
+
+            // parse args
+            if (ParseArgs (args, false)) {
+
+                #region Option handling
+                TestTypes setType = TestTypes.None;
+
+                try {
+                    setType = ProcessSetOption ();
+                } catch (InvalidOperationException e) {
+                    ErrorWriteLine (e.Message);
+                    Environment.ExitCode = 1;
+                    return;
+                }
+
+                if (GetOption ("optionfile").Set) {
+                    try {
+                        ProcessOptionFile ();
+                    } catch (Exception e) {
+                        ErrorWriteLine ("Error reading option files: {0}", e.Message);
+                        Environment.ExitCode = 1;
+                        return;
+                    }
+                }
+
+                if (PrintInformationalOptions (setType)) {
+                    Environment.ExitCode = 1;
+                    return;
+                }
+
+                #endregion
+
+                #region Load test CodeDomProvider assemblies
+                Assembly  cdpAssembly    = null;
+                ArrayList testAssemblies = null;
+
+                try {
+                    testAssemblies = LoadTestAssemblies ();
+                } catch (Exception e) {
+                    ErrorWriteLine ("Couldn't load test case assembly!");
+                    Console.WriteLine ("Exception stack: {0}", e.ToString ());
+                    Environment.ExitCode = 1;
+                    return;
+                }
+
+                try {
+                    cdpAssembly = LoadProviderAssembly ();
+                } catch (Exception e) {
+                    ErrorWriteLine ("Couldn't load provider assembly '{0}': {1}",
+                        GetOption ("codedomproviderlib").GetSingleValue (), e.ToString ());
+                    Environment.ExitCode = 1;
+                    return;
+                }
+
+                if ((cdpAssembly == null && !GetOption("languagename").Set) || testAssemblies == null) {
+                    ErrorWriteLine ("Couldn't load provider assembly and/or test assemblies.  Quitting.");
+                    Environment.ExitCode = 1;
+                    return;
+                }
+                #endregion
+
+                #region Create save directory if specified
+                // defaults to .\testoutput\
+                string dir = "testoutput";
+                if (GetOption ("savedirectory").Set) {
+                    dir = GetOption ("savedirectory").GetSingleValue ();
+                }
+                dir = String.Format (CultureInfo.InvariantCulture, 
+                        @"{0}\{1}", Environment.CurrentDirectory, dir);
+
+                try {
+                    if (!Directory.Exists (dir))
+                        Directory.CreateDirectory (dir);
+                } catch (Exception) {
+                    ErrorWriteLine ("Couldn't create directory '{0}'.", dir);
+                    Environment.ExitCode = 1;
+                    return;
+                }
+                #endregion
+
+                #region Find and create an instance of the given code provider
+                CodeDomProvider cdp = null;
+
+#if WHIDBEY
+                // first try to use the given string as an argument to CodeDomProvider.CreateProvider
+                // but only if we're being built in Whidbey
+                if (GetOption ("languagename").Set) {
+                    string lname = GetOption ("languagename").GetSingleValue ();
+                    try {
+                        if (lname != null)
+                            cdp = CodeDomProvider.CreateProvider (lname);
+                    } catch (Exception e) {
+                        cdp = null;
+                        ErrorWriteLine ("Tried to use CodeDomProvider.CreateProvider() to get '{0}', but failed.",
+                                lname);
+                        Console.WriteLine ("Exception stack: {0}", e.ToString ());
+                    }
+                }
+#endif
+
+                if (cdp == null && GetOption ("codedomprovider").Set) {
+                    string typeName = GetOption ("codedomprovider").GetSingleValue ();
+                    // try with the given assembly
+                    Type cdpType = cdpAssembly.GetType (typeName, false, true);
+
+                    if (cdpType != null) {
+                        if (!cdpType.IsSubclassOf (typeof (System.CodeDom.Compiler.CodeDomProvider))) {
+                            ErrorWriteLine ("{0} must be a subclass of CodeDomProvider.", typeName);
+                            Environment.ExitCode = 1;
+                            return;
+                        }
+
+                        new ReflectionPermission (ReflectionPermissionFlag.NoFlags).Demand ();
+                        cdp = (CodeDomProvider) cdpAssembly.CreateInstance (typeName, false);
+                    } else {
+                        Console.WriteLine ("Couldn't find '{0}' in assembly \"{1}\".",
+                            typeName, cdpAssembly);
+                    }
+                }
+
+                if (cdp == null) {
+                    ErrorWriteLine ("Couldn't create provider '{0}'.  Make sure ", GetOption ("codedomprovider").GetSingleValue ());
+                    ErrorWriteLine ("you supply the full type name including namespace.");
+                    Environment.ExitCode = 1;
+                    return;
+                }
+                #endregion
+
+                // load tests
+                ArrayList runTests = null;
+
+                try {
+                    runTests = LoadTests (testAssemblies, setType);
+                } catch (InvalidOperationException e) {
+                    ErrorWriteLine ();
+                    ErrorWriteLine (e.Message);
+                    Environment.ExitCode = 1;
+                    return;
+                }
+
+                if (runTests == null) {
+                    ErrorWriteLine ();
+                    ErrorWriteLine ("Error trying to load tests.");
+                    Environment.ExitCode = 1;
+                    return;
+                }
+
+                #region Run tests
+                // run tests
+                StringCollection failedTests = new StringCollection ();
+                foreach (CodeDomTest test in runTests) {
+                    try {
+                        if (RunTest(cdp, test, dir))
+                        {
+                            if (test.Comment != "")
+                                Console.WriteLine("{0} is now passing - well done!", test.Name);
+                        }
+                        else
+                            failedTests.Add(string.Format("{0} ({1})", test.Name, test.Comment == "" ? "TEST FAILED" : test.Comment));
+
+                    } catch (Exception e) {
+                        ErrorWriteLine ("Caught '{0}' while running test '{3}'{1}{2}",
+                                e.GetType(), Environment.NewLine, e.ToString (), test.Name);
+												failedTests.Add(string.Format("{0}\t\t({1})", test.Name, test.Comment == "" ? "TEST FAILED" : test.Comment));
+                    }
+                }
+                #endregion
+
+                // print the summary information if there were >1 tests run
+                if (runTests.Count > 1) {
+                    Console.WriteLine ();
+                    Console.WriteLine ("Ran {0} total tests.", runTests.Count);
+                    Console.WriteLine ("    {0} failed", failedTests.Count);
+                    Console.WriteLine ("    {0} passed", runTests.Count - failedTests.Count);
+                }
+
+                Console.WriteLine ();
+                if (failedTests.Count > 0) {
+                    if (failedTests.Count > 1) {
+                        Console.WriteLine ("We have the following failures in CodeDom tests. If a comment is shown then these are expected (CodeDom support for F# is not fully complete):");
+
+                        foreach (string failedTest in failedTests) {
+                            Console.WriteLine (" - {0}", failedTest);
+                        }
+
+                        Console.WriteLine ();
+                        Console.WriteLine ("You can find the log, source, and/or assembly files in the directory:");
+                        Console.WriteLine ("  " + dir);
+                        Console.WriteLine ("Each log, source or assembly file is called <testname>.{log|src|dll}, ");
+                        Console.WriteLine ("respectively.");
+                    } else {
+                        string failedTest = failedTests[0];
+                        Console.WriteLine ("{0} failed.", failedTest);
+                        Console.WriteLine (" Log file: {0}", dir + "\\" + failedTest + ".log");
+                        if (File.Exists (dir + "\\" + failedTest + ".src.fs"))
+                            Console.WriteLine (" Source file: {0}", dir + "\\" + failedTest + ".src.fs");
+                    }
+
+                    Console.WriteLine ();
+
+                    Environment.ExitCode = 1;
+                    Console.WriteLine ("FAILED");
+                } else {
+                    Environment.ExitCode = 100;
+                    Console.WriteLine ("PASSED");
+                }
+            } else {
+                PrintUsage (false);
+            }
+        }
+
+        // Load tests from the test case assemblies
+        static ArrayList LoadTests (ArrayList testAssemblies, TestTypes setType) {
+            // determine specific tests to run from the commandline
+            // if none are given, list.Count=0 signals to run them all
+            ArrayList runTests = new ArrayList ();
+            StringCollection specTests = GetOption ("runtestcase").Values;
+            StringCollection dontRun = GetOption ("dontruntestcase").Values;
+
+            StringCollection duplicateCheck = new StringCollection ();
+
+            // while looping through the assemblies, this will reflect
+            // whether or not a certain test was found
+            BitArray specTestFound = new BitArray (specTests.Count);
+
+            // check to see if there are any tests that were both
+            // specified to run and specified NOT to run
+            foreach (string specTest in specTests) {
+                if (StringCollectionContainsIgnoreCase (dontRun, specTest)) {
+                    throw new InvalidOperationException (String.Format (CultureInfo.CurrentCulture,
+                                "Test '{0}' was both specified to run and *not* to run. " +
+                            "This is ambiguous. Giving up.", specTest));
+                }
+            }
+
+            foreach (Assembly asm in testAssemblies) {
+                bool foundAtLeastOneTest = false;
+
+                foreach (Type type in asm.GetTypes ()) {
+                    if (!type.Equals (typeof (CodeDomTest)) &&
+                            !type.Equals (typeof (CodeDomTestTree)) &&
+                            type.IsSubclassOf (typeof (CodeDomTest))) {
+                        CodeDomTest test = null;
+                        try {
+                            ConstructorInfo cons = type.GetConstructor (new Type[0]);
+                            test = (CodeDomTest) cons.Invoke (new Object[0]);
+                        } catch (Exception e) {
+                            throw new InvalidOperationException (String.Format (CultureInfo.CurrentCulture,
+                                        "Couldn't create instance of '{0}': {1}", type, e.Message));
+                        }
+
+                        // check for duplicate names
+                        if (test != null && StringCollectionContainsIgnoreCase (duplicateCheck, test.Name)) {
+                            throw new InvalidOperationException (String.Format (CultureInfo.CurrentCulture,
+                                        " *** Found a duplicate test name '{0}' among test case assemblies. Check your test cases.", test.Name));
+                        } else if (test != null) {
+                            duplicateCheck.Add (test.Name);
+                        }
+
+                        // if we got here, we found at least one type that inherits
+                        // from CodeDomTest and we were able to instantiate it
+                        if (test != null)
+                            foundAtLeastOneTest = true;
+
+                        // if certain tests were specified attempt to find them
+                        // NOTE: All test cases that match the given name will be
+                        //       picked up for running.  This includes test cases
+                        //       that share the same name
+                        if (test != null && (GetOption ("set").Set ?
+                                (test.TestType & setType) > 0 : true) &&
+                                !StringCollectionContainsIgnoreCase (dontRun, test.Name)) {
+                            if (specTests.Count > 0) {
+
+                                int index = -1;
+                                for (int i = 0; i < specTests.Count; i++)
+                                    if (String.Compare ((string) specTests[i], test.Name, true, CultureInfo.InvariantCulture) == 0) {
+                                        index = i;
+                                        break;
+                                    }
+
+                                if (index >= 0) {
+                                    specTestFound[index] = true;
+                                    runTests.Add (test);
+                                }
+                            } else {
+                                // run them all
+                                runTests.Add (test);
+                            }
+                        }
+                    }
+                }
+
+                if (!foundAtLeastOneTest) {
+                    ErrorWriteLine ("Couldn't find at least one type that inherits from CodeDomTest in");
+                    ErrorWriteLine (asm.CodeBase);
+                    ErrorWriteLine ("Make sure your test case assembly references the same CodeDomTest.dll");
+                    ErrorWriteLine ("that the current program ({0}) does.", (Environment.GetCommandLineArgs ())[0]);
+                    ErrorWriteLine ("Continuing...");
+                }
+            }
+
+            if (specTests.Count > 0) {
+                // check if any specified tests weren't found
+                for (int i = 0; i < specTestFound.Count; i++) {
+                    if (!specTestFound[i]) {
+                        PrintTestList (setType, false);
+                        if (GetOption ("set").Set) {
+                            throw new InvalidOperationException (String.Format (CultureInfo.CurrentCulture,
+                                        "Can't find test '{0}' in the set '{1}'." +
+                                        " Above is the list of available test cases.",
+                                        specTests[i], GetOption ("set").GetSingleValue ()));
+                        } else {
+                            throw new InvalidOperationException (String.Format (CultureInfo.CurrentCulture,
+                                        "Can't find test '{0}' in any test case assemblies. " +
+                                        " Above is the list of available test cases.", specTests[i]));
+                        }
+                    }
+                }
+            }
+
+            return runTests;
+        }
+
+        static void PrintTestList (TestTypes setType, bool printDescriptions) {
+            // check for required option
+            if (!GetOption ("testcaselib").Set) {
+                ErrorWriteLine ("You must specify a test case library to list available tests.");
+                ErrorWriteLine ();
+                return;
+            }
+
+            if (GetOption ("set").Set)
+                Console.WriteLine ("Available tests in {0}:", setType);
+            else
+                Console.WriteLine ("Available tests:");
+
+            if (!printDescriptions)
+                Console.WriteLine (" (Use -listdesc to get a full description for each test.)");
+
+            Console.WriteLine ();
+
+            foreach (Assembly asm in LoadTestAssemblies ()) {
+                bool foundAtLeastOne = false;
+
+                foreach (Type type in asm.GetTypes ())
+                    if (type.IsSubclassOf (typeof (CodeDomTest))) {
+
+                        // instantiate the test to get the name, description
+                        // and type
+                        CodeDomTest test = null;
+                        try {
+                            ConstructorInfo cons = type.GetConstructor (new Type[0]);
+                            test = (CodeDomTest) cons.Invoke (new Object[0]);
+                        } catch (Exception e) {
+                            ErrorWriteLine ("Couldn't create instance of '{0}'.", type);
+                            ErrorWriteLine ("Exception stack: {0}", e.ToString ());
+                            return;
+                        }
+
+                        foundAtLeastOne = true;
+
+                        if (test != null && (GetOption ("set").Set ? (test.TestType & setType) > 0 : true))
+                            if (printDescriptions)
+                                Console.WriteLine (" {0}{1}   * Set: {3}{1}    {2}{1}", test.Name,
+                                    Environment.NewLine, test.Description,
+                                    Enum.Format (typeof (TestTypes), test.TestType, "F"));
+                            else
+                                Console.WriteLine (" - {0}", test.Name);
+                    }
+
+                if (!foundAtLeastOne) {
+                    ErrorWriteLine ("Couldn't find at least one type that inherits from CodeDomTest in");
+                    ErrorWriteLine (asm.CodeBase);
+                    ErrorWriteLine ("Make sure your test case assembly references the same CodeDomTest.dll");
+                    ErrorWriteLine ("that the current program ({0}) does.", (Environment.GetCommandLineArgs ())[0]);
+                }
+            }
+        }
+
+        static ArrayList LoadTestAssemblies () {
+            ArrayList testAssemblies = new ArrayList ();
+            StringCollection values = GetOption ("testcaselib").Values;
+            foreach (string val in values)
+                testAssemblies.Add (Assembly.LoadFrom (val));
+
+            return testAssemblies;
+        }
+
+        static Assembly LoadProviderAssembly () {
+            Assembly cdpAssembly = null;
+
+            // load from our assemblies if the user provides
+            // one of the "standard" code dom providers.  this allows
+            // (provider is BlahCodeProvider) to work in the test cases
+            if (GetOption ("codedomprovider").Set) {
+                switch (GetOption ("codedomprovider").GetSingleValue ().ToLower (CultureInfo.InvariantCulture)) {
+                    case "microsoft.jscript.jscriptcodeprovider":
+                        cdpAssembly = Assembly.GetAssembly (typeof (JScriptCodeProvider));
+                        break;
+
+                    case "microsoft.visualbasic.vbcodeprovider":
+                        cdpAssembly = Assembly.GetAssembly (typeof (VBCodeProvider));
+                        break;
+
+                    case "microsoft.csharp.csharpcodeprovider":
+                        cdpAssembly = Assembly.GetAssembly (typeof (CSharpCodeProvider));
+                        break;
+                }
+            }
+
+            if (cdpAssembly == null && GetOption ("codedomproviderlib").Set) {
+                string asmName = GetOption ("codedomproviderlib").GetSingleValue ();
+
+                if (File.Exists (asmName)) {
+                    // valid file, load from and get the strong name so we
+                    // can then do a 'strong load'
+                    cdpAssembly = Assembly.LoadFrom (asmName);
+                } else {
+                    // attempt to load from a strong name
+                    cdpAssembly = Assembly.Load (asmName);
+                }
+            }
+
+            return cdpAssembly;
+        }
+
+        /// <summary>
+        /// Runs a given CodeDom test case against the given
+        /// provider.  If the test case succeeds, true is returned.
+        /// False otherwise.
+        /// </summary>
+        /// <param name="provider">The provider to test against.</param>
+        /// <param name="test">The test case.</param>
+        /// <param name="outDir">The output directory for assemblies, logs and source files.</param>
+        /// <returns></returns>
+        static bool RunTest (CodeDomProvider provider, CodeDomTest test, string outDir) {
+
+            bool   success    = false;
+            string filePrefix = String.Format(CultureInfo.InvariantCulture, @"{0}\{1}", outDir, test.Name);
+
+            if (test.TestType == TestTypes.Whidbey && Environment.Version.Major < 2) {
+                ErrorWriteLine ("Test '{0}' will not run properly on a pre-Whidbey runtime version.",
+                        test.Name);
+                ErrorWriteLine ("Succeeding this test without running it.");
+                return true;
+            }
+
+            // create the log file
+            StreamWriter log = null;
+            log = new StreamWriter (filePrefix + ".log");
+
+            // give the test case somewhere to write
+            test.LogStream = log;
+
+            // if -verbose, echo everything to the console
+            test.EchoToConsole = GetOption ("verbose").Set;
+
+            try {
+                test.LogMessage ("");
+                test.LogMessage ("* Running test case '{0}'", test.Name);
+                test.LogMessage ("- {0}", test.Description);
+
+                // if the test is a specialized version of the test tree
+                // set the options so that the source and assembly files
+                // can be saved properly by the Run method
+                if (test.GetType ().IsSubclassOf (typeof (CodeDomTestTree))) {
+                    CodeDomTestTree ttree = (CodeDomTestTree) test;
+                    ttree.SourceFileName = filePrefix + ".src.fs";
+                    ttree.AssemblyFileName = GetOption ("saveassemblies").Set ?
+                        filePrefix + ".dll" : String.Empty;
+
+                    try {
+                        // delete any files of with these names
+                        if (ttree.SourceFileName.Length > 0 &&
+                                File.Exists (ttree.SourceFileName))
+                            File.Delete (ttree.SourceFileName);
+                        if (ttree.AssemblyFileName.Length > 0 &&
+                                File.Exists (ttree.AssemblyFileName))
+                            File.Delete (ttree.AssemblyFileName);
+
+                    // ignore file in use and argument exceptions
+                    } catch (IOException) {
+                    } catch (ArgumentException) {
+                    }
+                }
+
+                success = test.Run (provider);
+
+            } catch (ScenarioException e) {
+                // A scenario exception happened.  This means the test case has
+                // some internal inconsistencies.
+                ErrorWriteLine ("! Scenario exception: " + e.Message);
+                ErrorWriteLine ("! This is a problem with the test case, not the provider.");
+                
+                // repeat for the log file
+                log.WriteLine ("---------------------------------------------------------");
+                log.WriteLine ("! Scenario exception: " + e.Message);
+                log.WriteLine ("! This is a problem with the test case, not the provider.");
+
+                success = false;
+            } catch (Exception e) {
+                ErrorWriteLine ("! Exception occurred while running test '{0}'.", test.Name);
+                ErrorWriteLine ("! Stack: {0}", e.ToString ());
+
+                // repeat for the log file
+                log.WriteLine ("---------------------------------------------------------");
+                log.WriteLine ("! Exception occurred while running test '{0}'.", test.Name);
+                log.WriteLine ("! Stack: {0}", e.ToString ());
+
+                success = false;
+            } finally {
+                // remove the log listener
+                log.Close ();
+            }
+
+            if (success) {
+                // on test case success, we need to clean up the log and
+                // source files we generated
+                try {
+                    if (!GetOption ("savesources").Set)
+                        File.Delete (filePrefix + ".src.fs");
+                    if (!GetOption ("savelogs").Set)
+                        File.Delete (filePrefix + ".log");
+                } catch (Exception e) {
+                    ErrorWriteLine ("Error trying to delete a file.");
+                    ErrorWriteLine ("Exception stack: " + e.ToString ());
+                }
+            } else {
+                if (GetOption ("dump").Set) {
+                    // the test failed, so we should write the log and source if
+                    // dump is specified
+                    try {
+                        // if verbose was given, the log file will have already been
+                        // shown on the console
+                        if (!GetOption ("verbose").Set) {
+                            Console.WriteLine ("-------------- LOG (test case: {0}) --------------", test.Name);
+                            using (StreamReader rLog = new StreamReader (filePrefix + ".log")) {
+                                Console.WriteLine (rLog.ReadToEnd ());
+                            }
+                            Console.WriteLine ("-------------- END LOG (test case: {0}) --------------", test.Name);
+                        }
+
+                        // src file may not exist
+                        if (File.Exists (filePrefix + ".src.fs")) {
+                            Console.WriteLine ("-------------- SOURCE (test case: {0}) --------------", test.Name);
+                            using (StreamReader rSrc = new StreamReader (filePrefix + ".src.fs")) {
+                                Console.WriteLine (rSrc.ReadToEnd ());
+                            }
+                            Console.WriteLine ("-------------- END SOURCE (test case: {0}) --------------", test.Name);
+                        }
+
+                    } catch (Exception e) {
+                        ErrorWriteLine ("Error reading files!");
+                        ErrorWriteLine ("Exception stack:");
+                        ErrorWriteLine (e.ToString ());
+                    }
+                }
+            }
+
+            // return true on success, false on failure
+            return success;
+        }
+
+        /// <summary>
+        /// Retrieves the given option name from the list of options.  If no
+        /// option with the given name is found, and exception is thrown.
+        /// </summary>
+        /// <param name="name">The option name to retrieve.</param>
+        /// <returns>The Option object corresponding to the given name.</returns>
+        static Option GetOption (string name) {
+            foreach (Option opt in options) {
+                if (String.Compare (opt.Name, name, false,
+                    CultureInfo.InvariantCulture) == 0)
+                    return opt;
+            }
+
+            throw new ArgumentException (String.Format(CultureInfo.InvariantCulture, "Option name '{0}' doesn't exist.", name));
+        }
+
+        /// <summary>
+        /// Prints the usage of this program to the console.
+        /// </summary>
+        static void PrintUsage (bool showDescriptions) {
+
+            Console.WriteLine (Header);
+            Console.WriteLine ();
+
+            Console.WriteLine ("Usage:");
+            Console.WriteLine ();
+
+            string name = (Environment.GetCommandLineArgs ())[0];
+            string pad  = new String (' ', name.Length + 1);
+
+#if WHIDBEY
+            Console.WriteLine ("{0} /langname:<language name as specified in machine.config>", name);
+            Console.WriteLine ("{0}/testcaselib:<assem> [[/testcaselib:<assem2>] ... ]", pad);
+            Console.WriteLine ();
+            Console.WriteLine ("  -- alternatively --");
+            Console.WriteLine ();
+#endif
+            Console.WriteLine ("{0} /codedomprovider:<full name>", name);
+            Console.WriteLine ("{0}/testcaselib:<assem> [[/testcaselib:<assem2>] ... ]", pad);
+            Console.WriteLine ("{0}[/codedomproviderlib:<library file or strong name>]", pad);
+
+            Console.WriteLine ();
+#if WHIDBEY
+            Console.Write ("** /codedomprovider and /testcaselib");
+            Console.WriteLine (" -- OR -- /langname and /testcaselib");
+            Console.WriteLine ("   are required.");
+#else
+            Console.Write ("** /codedomprovider and /testcaselib are required.");
+#endif
+            Console.WriteLine ();
+            Console.WriteLine ("Options are case insensitive. You may also specify options with a '-'.");
+            Console.WriteLine ("Use /help to show full descriptions.");
+            Console.WriteLine ();
+
+
+            // Loop through every option and output its usage.
+            foreach (Option opt in options) {
+                Console.WriteLine (opt.GetUsage (showDescriptions));
+            }
+        }
+
+        /// <summary>
+        /// Parses the given string array as arguments, and saves the results of the parse
+        /// to the Options array stored in this class.
+        /// </summary>
+        /// <param name="args">The arguments to parse.</param>
+        /// <param name="ignoreDash">Whether or not to ignore dashes in the beginning of each option.</param>
+        /// <returns></returns>
+        static bool ParseArgs (string[] args, bool ignoreDash) {
+            bool success = true;
+
+            if (args.Length > 0) {
+                foreach (string arg in args) {
+                    // no matches for this argument
+                    bool nomatches = true;
+
+                    foreach (Option opt in options) {
+                        Option.OptionParseResult result = opt.Parse (arg, ignoreDash);
+
+                        if (result == Option.OptionParseResult.Malformed) {
+                            success = false;
+                            ErrorWriteLine ("Option '{0}' not specified correctly.", arg);
+                            break;
+                        } else if (result == Option.OptionParseResult.Match)
+                            nomatches = false;
+                    }
+
+                    // none of the options matched the given argument
+                    // error out
+                    if (success && nomatches) {
+                        success = false;
+                        ErrorWriteLine ("Option '{0}' is not valid.", arg);
+                        ErrorWriteLine ();
+                        break;
+                    }
+                }
+            } else {
+                success = false;
+            }
+
+            return success;
+        }
+
+        static bool StringCollectionContainsIgnoreCase (StringCollection collect, string find) {
+            foreach (string s in collect) {
+                if (String.Compare (s, find, true, CultureInfo.InvariantCulture) == 0)
+                    return true;
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// Private option class that describes an option.
+        /// </summary>
+        private class Option {
+            string    name        = null;
+            string[]  shortnames  = null;
+            string    description = null;
+            bool      hasArg      = false;
+            bool      wasSet      = false;
+            StringCollection values      = new StringCollection ();
+
+            public enum OptionParseResult {
+                Malformed,
+                NoMatch,
+                Match
+            }
+
+            public Option (string name, string[] shortnames, string description, bool hasArg) {
+                if (name == null)
+                    throw new ArgumentNullException ("name");
+
+                if (shortnames == null)
+                    throw new ArgumentNullException ("shortnames");
+
+                if (description == null)
+                    throw new ArgumentNullException ("description");
+
+                this.name = name;
+                this.shortnames = shortnames;
+                this.description = description;
+                this.hasArg = hasArg;
+
+                this.wasSet = false;
+            }
+
+            public bool Set {
+                get { return wasSet; }
+            }
+
+            public string Name {
+                get { return name; }
+            }
+
+            public StringCollection Values {
+                get { return values; }
+            }
+
+            public OptionParseResult Parse (string arg, bool ignoreDash) {
+                OptionParseResult res = OptionParseResult.NoMatch;
+
+                StringBuilder sb = new StringBuilder ();
+
+                // generate a regex from the given options
+                sb.Append ("^");
+                if (!ignoreDash)
+                    sb.Append ("[-/]");
+
+                sb.AppendFormat ("({0}", Regex.Escape (name));
+
+                foreach (string sn in shortnames)
+                    sb.AppendFormat ("|{0}", Regex.Escape (sn));
+                sb.Append (")");
+                if (hasArg)
+                    sb.Append (":\"?([^\"]*)\"?$");
+                else
+                    sb.Append ("$");
+
+                Regex rx = new Regex (sb.ToString (),
+                    RegexOptions.IgnoreCase);
+
+                // attempt a match
+                Match m = rx.Match (arg);
+
+                if (m.Success) {
+                    res = OptionParseResult.Match;
+                    wasSet = true;
+
+                    // parse any args if there are
+                    // any to parse
+                    if (hasArg) {
+                        if (m.Groups.Count > 1) {
+                            if (!values.Contains (m.Groups[2].Value))
+                                values.Add (m.Groups[2].Value);
+                        } else {
+                            res = OptionParseResult.Malformed;
+                            wasSet = false;
+                        }
+                    }
+                }
+
+                return res;
+            }
+
+            public string GetSingleValue () {
+                if (values.Count >= 1)
+                    return (string) values[0];
+                return null;
+            }
+
+            public String GetUsage (bool showDescriptions) {
+                StringBuilder sb = new StringBuilder ();
+
+                sb.AppendFormat (" /{0}{1}", name, hasArg ? ":<value>" : String.Empty);
+                foreach (string sn in shortnames) {
+                    sb.AppendFormat (" or /{0}{1}", sn, hasArg ? ":<value>" : String.Empty);
+                }
+
+                if (showDescriptions) {
+                    sb.Append (Environment.NewLine);
+
+                    // wrap long lines
+                    int currentLength = 0;
+                    foreach (string word in description.Split (' ')) {
+                        if (currentLength >= 55) {
+                            sb.Append (Environment.NewLine);
+                            currentLength = 0;
+                        }
+
+                        if (currentLength == 0) {
+                            sb.AppendFormat ("    {0} ", word);
+                            currentLength += word.Length + 4;
+                        } else {
+                            sb.AppendFormat ("{0} ", word);
+                            currentLength += word.Length;
+                        }
+                    }
+                    sb.Append (Environment.NewLine);
+                }
+
+                return sb.ToString ();
+            }
+
+            public override String ToString () {
+                StringBuilder sb = new StringBuilder ();
+                sb.AppendFormat ("name={0}", name);
+                sb.AppendFormat (",description={0}", description);
+                sb.AppendFormat (",set={0}", wasSet);
+                foreach (string val in values)
+                    sb.AppendFormat (",val={0}", val);
+
+                return sb.ToString ();
+            }
+        }
+
+        /// <summary>
+        /// Describes how test type options are handled.  This is specified
+        /// as -set on the command-line.
+        /// </summary>
+        private class TestTypeOption {
+            string    optionName;
+            TestTypes types;
+            Version   runtimeVersion;
+
+            public TestTypeOption (string optionName, TestTypes types, Version runtimeVersion) {
+                if (optionName == null)
+                    throw new ArgumentNullException ("optionName");
+                if (runtimeVersion == null)
+                    throw new ArgumentNullException ("runtimeVersion");
+
+                this.optionName = optionName;
+                this.types = types;
+                this.runtimeVersion = runtimeVersion;
+            }
+
+            public string Name {
+                get { return optionName; }
+            }
+
+            public TestTypes Types {
+                get { return types; }
+            }
+
+            public Version RuntimeVersion {
+                get { return runtimeVersion; }
+            }
+
+            public bool IsSameName (string name) {
+                return String.Compare (name, optionName, true,
+                        CultureInfo.InvariantCulture) == 0;
+            }
+
+            public bool IsVersionCompatible (Version ver) {
+                return runtimeVersion <= ver;
+            }
+        }
+
+        /// <summary>
+        /// Obligatory header information.
+        /// </summary>
+        /// <returns>A short description of this program.</returns>
+        static string Header {
+            get {
+                return "Microsoft (R) CodeDom test suite" + Environment.NewLine +
+                    ".NET Version " + Environment.Version + Environment.NewLine +
+                    "Copyright (C) Microsoft Corp. 2004.  All rights reserved.";
+            }
+        }
+
+        /// <summary>
+        /// Listed below are the names of each test classification, the types
+        /// of tests they cover and the CLR version they will run on.
+        /// </summary>
+        static TestTypeOption [] testTypeOptions = new TestTypeOption [] {
+                new TestTypeOption ("Subset", TestTypes.Subset, new Version (1, 0, 0)),
+                new TestTypeOption ("Everett", TestTypes.Subset | TestTypes.Everett, new Version (1, 0, 0)),
+                new TestTypeOption ("Whidbey", TestTypes.Subset | TestTypes.Everett | TestTypes.Whidbey, new Version (2, 0, 0))
+        };
+
+        /// <summary>
+        /// The options and their descriptions.  The boolean value specifies whether the
+        /// option takes an argument or not.
+        /// </summary>
+        static Option[] options = new Option[] {
+                new Option ("help", new string[] {"?", "h"},
+                "Shows this usage description.",
+                false
+                ),
+                new Option ("codedomprovider", new string[] {"p"},
+                "** Either this or languagename required ** CodeDomProvider you wish to use to run the test cases. " +
+                "This should be specified using the full name. You should also specify the codedomproviderlib option " +
+                "if this provider is not in an assembly in the GAC. " +
+                "If both languagename and codedomprovider options are specified, languagename is taken in favor of " +
+                "the two.",
+                true
+                ),
+                new Option ("languagename", new string[] {"lang"},
+                "** Either this or languagename required ** The language to run the test " +
+                "cases against. This is the name given to CodeDomProvider.CreateProvider(). " +
+                "This only works in CLR versions >= 2.0. If both languagename and codedomprovider " +
+                "options are specified, languagename is taken in favor of the two.",
+                true
+                ),
+                new Option ("testcaselib", new string[] {"tl"},
+                "**required** Test case assembly that stores the test cases you wish to " +
+                "test against. You may specify more than one.",
+                true
+                ),
+                new Option ("codedomproviderlib", new string[] {"pl"},
+                "The assembly where the CodeDomProvider lives. This should " +
+                "be specified either by file name or the strong name. If this " +
+                "option is not specified, the current assembly is used.",
+                true
+                ),
+                new Option ("list", new string[] {"l"},
+                "Lists available tests. Use -listdesc to get descriptions. Note " +
+                "you must pass in valid test assemblies in order for this to print anything.",
+                false
+                ),
+                new Option ("listdesc", new string[] {"ld"},
+                "Lists available tests and their descriptions. Note " +
+                "you must pass in valid test assemblies for this to print anything.",
+                false
+                ),
+                new Option ("set", new string[] {"s"},
+                "The set of tests to run. Only those matching the given " +
+                "option will be run. See -setlist for a list of valid set names.",
+                true
+                ),
+                new Option ("setlist", new string[] {"sls"},
+                "The list of test sets you may run.",
+                false
+                ),
+                new Option ("optionfile", new string[] {"of"},
+                "Path to a option file(s) that lists these options " +
+                "one per line. Options specified in these file will 'add to' " +
+                "those also specified on the command-line. This is similar to " +
+                "the CSharp compiler's response file except options should not have " +
+                "'-' or '/' prepended before them.",
+                true
+                ),
+                new Option ("runtestcase", new string[] {"t"},
+                "Select specific test case(s) to run. You may specify more " +
+                "than one.",
+                true
+                ),
+                new Option ("dontruntestcase", new string[] {"n"},
+                "Select specific test case(s) *NOT* to run. You may specify more " +
+                "than one.",
+                true
+                ),
+                new Option ("savedirectory", new string[] {"dir", "savedir"},
+                "The directory to save all logs, assemblies and source files.",
+                true
+                ),
+                new Option ("savesources", new string[] {"ss"},
+                "Save the sources even if all tests pass.",
+                false
+                ),
+                new Option ("saveassemblies", new string[] {"sa"},
+                "Save the generated assemblies even if all tests pass.  Note that only " +
+                "test cases that derive from CodeDomTestTree have the ability to save " +
+                "assemblies.",
+                false
+                ),
+                new Option ("savelogs", new string[] {"sl"},
+                "Save the generated logs even if all tests pass.",
+                false
+                ),
+                new Option ("verbose", new string[] {"v"},
+                "Be verbose. All test case output is written to the console. " +
+                "If this is not given, no output is given unless the " +
+                "test case fails.",
+                false
+                ),
+                new Option ("dump", new string[] {"d"},
+                "If during the run a test case fails, dump the log and source " +
+                "file to the console for that test case.",
+                false
+                )
+            };
+
+        static void ErrorWriteLine () {
+            ErrorWriteLine (String.Empty);
+        }
+
+        static void ErrorWriteLine (string msg) {
+            ErrorWriteLine (msg, String.Empty);
+        }
+
+        static void ErrorWriteLine (string msg, params object [] oparms) {
+#if WHIDBEY
+           Console.ForegroundColor = ConsoleColor.Red;
+#endif
+           //if (!GetOption ("verbose").Set)
+           Console.Error.WriteLine (String.Format (CultureInfo.InvariantCulture, msg, oparms));
+#if WHIDBEY
+           Console.ResetColor ();
+#endif
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/README.html b/workyard/tests/codedom/README.html
new file mode 100755
index 0000000..b248dfa
--- /dev/null
+++ b/workyard/tests/codedom/README.html
@@ -0,0 +1,478 @@
+<html>
+<style>
+    body {
+        margin-left: 5%;
+        margin-right: 5%;
+    }
+    h1,h2,h3 {
+        font-family: Arial, Helvetica, sans-serif;
+    }
+    .note {
+        padding: 0.5em 1em 0.5em 1em;
+        border: dashed 2px red;
+        background-color: #ecc;
+    }
+    p.optdesc {
+        margin-left: 2em;
+    }
+    div.usagescenario {
+        margin-top: 2em;
+        padding: 0.5em 1em 0.5em 1em;
+        border: solid 1px black;
+        background-color: #eee;
+    }
+    a {
+        color: #666;
+    }
+    a:visited {
+        color: #333;
+    }
+    table#testdesc {
+        font-size: 10pt;
+        font-family: Arial, Helvetica, sans-serif;
+        border-collapse: collapse;
+        border: solid 2px black;
+    }
+    table#testdesc th {
+        text-align: left;
+        border-right: solid 1px black;
+        border-bottom: solid 3px black;
+        background-color: #333;
+        color: white;
+    }
+    table#testdesc td {
+        padding: 0.2em 1em 0.2em 0.2em;
+        margin: 0 0 0 0;
+        border-right: solid 1px black;
+    }
+
+    table#testdesc .cls_subset {
+        background-color: #eee;
+    }
+
+    table#testdesc .cls_everett {
+        background-color: #ddd;
+    }
+
+    table#testdesc .cls_whidbey {
+        background-color: #ccc;
+    }
+</style>
+<head><title>CodeDom Test Suite Readme</title></head>
+<body>
+
+<h1>CodeDom Test Suite Readme</h1>
+Copyright (C) Microsoft Corp. 2004.  All rights reserved.
+
+<h2>Introduction</h2>
+
+
+<p>
+The CodeDom test suite is a collection of tests that enables custom
+code providers a way to verify that they are generating and compiling code
+from their provider properly.  Each test takes a pre-built CodeDom tree
+and generates and compiles the tree using the provider supplied to it on
+the command line.  The tests then verify the assembly generated from the
+code provider through reflection.
+</p>
+
+<p>
+The pre-built CodeDom trees are listed in the <code>BuildTree</code> methods
+of each test located in the <code>tests\</code> directory.  The generated
+C# code is listed above the CodeDom code that generates it.  Even if you
+don't have a CodeDom provider to test, you can browse through these tests
+and get a feel for the constructs that are required to generate certain
+kinds of code.
+</p>
+
+<p class="note">You must have one of the SDK versions of the runtime installed
+on your machine to use this test suite.  These are freely available on 
+MSDN.
+</p>
+
+<p>To get started, <a href="#scenarios">refer to common
+    usage scenarios</a>.
+
+<p>Test case writers may want to refer to the
+<a href="notesfortestcasewriters.html">Writing Test Cases for the Test Suite</a>
+document also located in this collection.</p>
+
+<h2>Usage</h2>
+
+<p>
+The test suite takes the following command line arguments two of which
+are required.  Below are common usage scenarios, and below that are the full
+usage descriptions.
+</p>
+
+<h3>Compiling</h3>
+
+<p>A Visual Studio .NET 2005 Beta1 solution file has been included.  Please upgrade to
+Whidbey Beta1 of the runtime if you haven't already.  A batch file
+named <code>build.bat</code> is included for those that wish to build the
+test suite against v1.0 or v1.1 of the runtime, or for those preferring to
+build from the commandline.
+</p>
+
+<p>
+If you would like to use this batch file to build for v1.0 or v1.1 of the
+runtime, simply run it as is.  Those users wanting to use the batch file for
+Whidbey must set the environment variable located in the script called
+<code>IS_WHIDBEY</code> to <code>1</code>.
+</p>
+
+<p class="note">It is recommended that you compile using the "Debug"
+release version in Visual Studio .NET or compile with the /debug+ switch on the command line.
+This will enhance your ability to troubleshoot problems with your provider
+while running the test cases.
+</p>
+
+<a name="scenarios"></a>
+<h3>Common Usage Scenarios</h3>
+
+<div class="usagescenario">
+<p>
+Test Microsoft's CSharpCodeProvider against all test cases in the library
+"tests.dll."  Also be verbose.
+</p>
+<pre>
+   > cdtsuite <code>/p</code>:Microsoft.CSharp.CSharpCodeProvider <code>/tl</code>:tests.dll <code>/v</code>
+</pre>
+</div>
+
+<div class="usagescenario">
+<p>
+Test MyCodeProvider located in "MyDll.dll" against all test cases in the
+library "tests.dll."  Also, be verbose, and save all assemblies, logs
+and source files during the test.
+</p>
+<pre>
+   > cdtsuite <code>/p</code>:MyCodeProvider <code>/pl</code>:MyDll.dll <code>/tl</code>:tests.dll <code>/v</code> <code>/sl</code> <code>/sa</code> <code>/ss</code>
+</pre>
+</div>
+
+<div class="usagescenario">
+<p>
+Test MyCodeProvider located in "MyDll.dll" against the test cases named
+"ArrayTest" and "ParamsTest" in the library "tests.dll."
+</p>
+<pre>
+   > cdtsuite <code>/p</code>:MyCodeProvider <code>/pl</code>:MyDll.dll <code>/tl</code>:tests.dll <code>/t</code>:ArrayTest <code>/t</code>:ParamsTest
+</pre>
+</div>
+
+<div class="usagescenario">
+<p>
+Test MyCodeProvider located in "MyDll.dll" against all test cases that are
+of the class "Subset" in the library "tests.dll."
+</p>
+<pre>
+   > cdtsuite <code>/p</code>:MyCodeProvider <code>/pl</code>:MyDll.dll <code>/tl</code>:tests.dll <code>/set</code>:Subset
+</pre>
+</div>
+
+<div class="usagescenario">
+<p>
+Test Microsoft's VBCodeProvider against the test case library "tests.dll."
+Also, be verbose, and save all assemblies, logs and source files during the test.
+</p>
+<pre>
+   > cdtsuite <code>/p</code>:Microsoft.VisualBasic.VBCodeProvider <code>/tl</code>:c:\tests.dll
+</pre>
+</div>
+
+<div class="usagescenario">
+<p>
+Test Microsoft's JScriptCodeProvider against the test case library "tests.dll."
+The <code><code>/lang</code></code> option makes the test suite use the the language name to
+get the provider.  Also, dump logs and source files for failing test cases.
+</p>
+<pre>
+   > cdtsuite <code>/lang</code>:js <code>/tl</code>:c:\tests.dll <code>/dump</code>
+</pre>
+</div>
+
+<h3>Full Usage Descriptions</h3>
+
+<p>
+Options are case insensitive. You may also specify options with a '-'.
+</p>
+
+<code>/help</code> or <code>/?</code> or <code>/h</code>
+<p class="optdesc">
+    Shows the usage description. 
+</p>
+
+<code>/codedomprovider:<value></code> or <code>/p:<value></code>
+<p class="optdesc">
+<b>Either this or languagename required.</b> CodeDomProvider 
+    you wish to use to run the test cases. This should be specified 
+    using the full name. You should also specify the codedomproviderlib 
+    option if this provider is not in an assembly in the GAC. If both 
+    languagename and codedomprovider options are specified, languagename 
+    is taken in favor of the two. 
+</p>
+
+ <code>/languagename:<value></code> or <code>/lang:<value></code>
+<p class="optdesc">
+<b>Either this or languagename required.</b> The language to run 
+    the test cases against. This is the name given to CreateProvider(). 
+    This only works in CLR versions >= 2.0. If both languagename and 
+    codedomprovider options are specified, languagename is taken 
+    in favor of the two. 
+</p>
+
+ <code>/testcaselib:<value></code> or <code>/tl:<value></code>
+<p class="optdesc">
+<b>Required.</b> Test case assembly that stores the test cases you 
+    wish to test against. You may specify more than one. 
+</p>
+
+ <code>/codedomproviderlib:<value></code> or <code>/pl:<value></code>
+<p class="optdesc">
+    The assembly where the CodeDomProvider lives. This should be 
+    specified either by file name or the strong name. If this option 
+    is not specified, the current assembly is used. 
+</p>
+
+ <code>/list</code> or <code>/l</code>
+<p class="optdesc">
+    Lists available tests. Use -listdesc to get descriptions. Note 
+    you must pass in valid test assemblies in order for this to print 
+    anything. 
+</p>
+
+ <code>/listdesc</code> or <code>/ld</code>
+<p class="optdesc">
+    Lists available tests and their descriptions. Note you must 
+    pass in valid test assemblies for this to print anything. 
+</p>
+
+ <code>/set:<value></code> or <code>/s:<value></code>
+<p class="optdesc">
+    The set of tests to run. Only those matching the given option will 
+    be run. See -setlist for a list of valid set names. 
+</p>
+
+ <code>/setlist</code> or <code>/sls</code>
+<p class="optdesc">
+    The list of test sets you may run. 
+</p>
+
+ <code>/optionfile:<value></code> or <code>/of:<value></code>
+<p class="optdesc">
+    Path to a option file(s) that lists these options one per line. 
+    Options specified in these file will 'add to' those also specified 
+    on the command-line. This is similar to the CSharp compiler's 
+    response file except options should not have '-' or '/' prepended 
+    before them. 
+</p>
+
+ <code>/runtestcase:<value></code> or <code>/t:<value></code>
+<p class="optdesc">
+    Select specific test case(s) to run. You may specify more than 
+    one. 
+</p>
+
+ <code>/dontruntestcase:<value></code> or <code>/n:<value></code>
+<p class="optdesc">
+    Select specific test case(s) *NOT* to run. You may specify more 
+    than one. 
+</p>
+
+<code>/savedirectory:<value></code> or <code>/dir:<value></code> or <code>/savedir:<value></code>
+<p class="optdesc">
+    The directory to save all logs, assemblies and source files. 
+</p>
+
+<code>/savesources</code> or <code>/ss</code>
+<p class="optdesc">
+    Save the sources even if all tests pass. 
+</p>
+
+ <code>/saveassemblies</code> or <code>/sa</code>
+<p class="optdesc">
+    Save the generated assemblies even if all tests pass. 
+</p>
+
+ <code>/savelogs</code> or <code>/sl</code>
+<p class="optdesc">
+    Save the generated logs even if all tests pass. 
+</p>
+
+ <code>/verbose</code> or <code>/v</code>
+<p class="optdesc">
+    Be verbose. All test case output is written to the console. If 
+    this is not given, no output is given unless the test case fails. 
+</p>
+
+ <code>/dump</code> or <code>/d</code>
+<p class="optdesc">
+    If during the run a test case fails, dump the log and source file 
+    to the console for that test case. 
+</p>
+
+<h2>Layout</h2>
+
+<p>
+The suite consists of a single command-line program called <code>cdtsuite</code>,
+a <code>CodeDomTest.dll</code> assembly that contains some utility classes and
+base types, and an assembly that contains a base line test suite.
+The tests in this assembly all derive from the class CodeDomTestTree
+as provided in <code>CodeDomTest.dll</code>.
+</p>
+
+<p>
+Every test case derives from the base type CodeDomTest, and <code>cdtsuite</code>
+uses virtual methods on this type to run each test.  The tests
+provided in the accompanying base line test case assembly (<code>tests.dll</code>),
+each exercise some part of a CodeDomProvider's ability to generate
+and compile CodeDom trees.  These tests and a short description are
+given in the <a href="#testcasedescription">Test Case Description</a>
+section.
+</p>
+
+
+<h3>Test Classification (Buckets)</h3>
+<p>
+These base line tests are classified into three buckets: Subset,
+Everett and Whidbey.  Subset tests generate and test CodeDom trees
+that generate the absolute minimally required parts of CodeDom.
+Everett and Whidbey tests generate trees that fall outside of this
+subset but within the feature areas of each classification (i.e.
+Everett tests don't test generics while Whidbey tests do).</p>
+
+<p>When
+you specify the classification on the command-line, every test in
+or below that classification will be tested.  So if you specify
+<code>Everett</code> on the command-line, every test with the
+classification of
+<code>Subset</code> and <code>Everett</code> will be tested, but
+no test from <code>Whidbey</code> will be run.
+</p>
+
+<p class="note">The CodeDom subset is a moving target.  Currently, the official
+document is being reviewed and finalized.  Look for its release on MSDN
+"in the near future."</p>
+
+<h2>Output</h2>
+
+<p>
+<code>cdtsuite</code> generates .log files for every test it runs.  This log
+file contains messages that each test case prints while it is
+running and is saved to <code>(output_dir)\(test_name).log</code>.  If no
+output directory is specified with <code>/savedir</code>:, this directory
+defaults to <code>(current_dir)\testoutput</code>.  Unless <code>/savelogs</code> is
+given, log files for passing test cases will be deleted.
+</p>
+
+<h3>Source File Generation</h3>
+<p>
+If a test case derives from CodeDomTestTree, a source file may
+be saved in the same directory as <code>(test_name).src</code>.  As with
+.log files, .src files are deleted if the test case passes
+(unless <code>/savesources</code> is given).
+</p>
+
+<h3>Assembly File Generation</h3>
+<p>
+Assemblies generated from these tests may also be saved by
+specifying the <code>/saveassemblies</code> option on the command-line.  Only
+test cases deriving from CodeDomTestTree will save these files.
+Since assemblies are only generated if specified on the command
+line, these will not be deleted even if test cases pass.
+</p>
+
+<h3>Console Output</h3>
+<p>
+<code>cdtsuite</code>'s console output can be controlled with two arguments: <code>/verbose</code>
+and <code>/dump</code>.  There are four combinations of these arguments; these
+are listed below along with how they change <code>cdtsuite</code>'s behavior.
+</p>
+
+<em>no arguments</em>
+<p>
+  Nothing is printed, and only a summary is given after all test
+  cases are run.  The summary lists the test cases that failed
+  and where to find the log and source files for these failed
+  cases are located.
+</p>
+
+<code>/verbose</code> only
+<p>
+  As test cases are run, the output that would normally only go
+  to the log file is printed on the console.  This includes
+  test cases that have succeeded.  The summary is still given
+  at the end of the run.
+</p>
+
+<code>/dump</code> only
+<p>
+  Nothing is printed for successful test cases, but on failed
+  cases, both the log and source files are printed to the console.
+  A summary is given at the end of the test case run.
+</p>
+
+<code>/dump</code> and <code>/verbose</code>
+<p>
+  Output is printed to the console as test cases are run as in
+  <code>/verbose</code> mode, but also source files are printed for failed
+  cases.  As always, a summary is given at the end of all test
+  case runs.
+</p>
+
+<a style="color: black;" name="testcasedescription">
+<h2>Test Cases and their Descriptions</h2>
+</a>
+
+<table id="testdesc">
+<tr><th>Test Name</th><th>Bucket</th><th>Test Description</th></tr>
+<tr class="cls_subset"><td>CallMethodTest</td><td><em>Subset</em></td><td>Tests calling methods.</td></tr>
+<tr class="cls_subset"><td>CastingCodeDom</td><td><em>Subset</em></td><td>Tests casting</td></tr>
+<tr class="cls_subset"><td>CreateObjectTest</td><td><em>Subset</em></td><td>Tests object creation.</td></tr>
+<tr class="cls_subset"><td>DelegateTest</td><td><em>Subset</em></td><td>Tests delegates.</td></tr>
+<tr class="cls_subset"><td>EventTest</td><td><em>Subset</em></td><td>Tests events.</td></tr>
+<tr class="cls_subset"><td>IterationsTest</td><td><em>Subset</em></td><td>Tests iterations.</td></tr>
+<tr class="cls_subset"><td>NamespaceTest</td><td><em>Subset</em></td><td>Tests namespaces.</td></tr>
+<tr class="cls_subset"><td>OverloadTest</td><td><em>Subset</em></td><td>Tests method overloading.</td></tr>
+<tr class="cls_subset"><td>SubsetArrayTest</td><td><em>Subset</em></td><td>Tests arrays while conforming to the subset.</td></tr>
+<tr class="cls_subset"><td>SubsetAttributesTest</td><td><em>Subset</em></td><td>Tests metadata attributes while staying in the subset.</td></tr>
+<tr class="cls_subset"><td>SubsetBinaryOperatorsTest</td><td><em>Subset</em></td><td>Tests binary operators while staying within the subset spec.</td></tr>
+<tr class="cls_subset"><td>SubsetFieldsTest</td><td><em>Subset</em></td><td>Subset compatible test of calling fields.</td></tr>
+<tr class="cls_subset"><td>PropertiesTest</td><td><em>Subset</em></td><td>Tests properties</td></tr>
+<tr class="cls_subset"><td>TypeOfTest</td><td><em>Subset</em></td><td>Tests typeof statements.</td></tr>
+<tr class="cls_everett"><td>ArrayTest</td><td><em>Everett</em></td><td>Tests arrays.</td></tr>
+<tr class="cls_everett"><td>AttributesTest</td><td><em>Everett</em></td><td>Tests metadata attributes.</td></tr>
+<tr class="cls_everett"><td>BinaryOperatorsTest</td><td><em>Everett</em></td><td>Tests binary operators.</td></tr>
+<tr class="cls_everett"><td>CallingFieldTest</td><td><em>Everett</em></td><td>Tests calling fields.</td></tr>
+<tr class="cls_everett"><td>CallMethodWDirect</td><td><em>Everett</em></td><td>Call a method with a direction</td></tr>
+<tr class="cls_everett"><td>ClassTest</td><td><em>Everett</em></td><td>Tests classes.</td></tr>
+<tr class="cls_everett"><td>CodePrimitiveExpressionTest</td><td><em>Everett</em></td><td>Tests coding primitive expressions.</td></tr>
+<tr class="cls_everett"><td>CodeSnippetTest</td><td><em>Everett</em></td><td>Tests code snippets.</td></tr>
+<tr class="cls_everett"><td>CommentTest</td><td><em>Everett</em></td><td>Tests comment statements.</td></tr>
+<tr class="cls_everett"><td>ConditionalStatementTest</td><td><em>Everett</em></td><td>Tests conditional statements.</td></tr>
+<tr class="cls_everett"><td>ConstructorTest</td><td><em>Everett</em></td><td>Tests constructors.</td></tr>
+<tr class="cls_everett"><td>DeclareField</td><td><em>Everett</em></td><td>Tests declarations of fields.</td></tr>
+<tr class="cls_everett"><td>DeclareMethod</td><td><em>Everett</em></td><td>Tests declaration of methods.</td></tr>
+<tr class="cls_everett"><td>EnumTest</td><td><em>Everett</em></td><td>Test enumerations</td></tr>
+<tr class="cls_everett"><td>GeneratorSupportsTest</td><td><em>Everett</em></td><td>Tests GeneratorSupport enumeration.</td></tr>
+<tr class="cls_everett"><td>GoToTest</td><td><em>Everett</em></td><td>Tests goto statements</td></tr>
+<tr class="cls_everett"><td>ImplementingStructsTest</td><td><em>Everett</em></td><td>Tests structs that implement other things.</td></tr>
+<tr class="cls_everett"><td>IndexersTest</td><td><em>Everett</em></td><td>Tests indexers.</td></tr>
+<tr class="cls_everett"><td>LinePragmaTest</td><td><em>Everett</em></td><td>Tests CodeLinePragma.</td></tr>
+<tr class="cls_everett"><td>StructTest</td><td><em>Everett</em></td><td>Tests structs</td></tr>
+<tr class="cls_everett"><td>TryCatchTest</td><td><em>Everett</em></td><td>Tests try/catch/finally statements.</td></tr>
+<tr class="cls_everett"><td>TypeTest</td><td><em>Everett</em></td><td>Tests generating and using objects of different types.</td></tr>
+<tr class="cls_everett"><td>UnicodeCharEscapeTest</td><td><em>Subset</em></td><td>Test All the Unicode characters for escaping</td></tr>
+<tr class="cls_whidbey"><td>CheckSumTest</td><td><em>Whidbey</em></td><td>Checksum testing.</td></tr>
+<tr class="cls_whidbey"><td>GenericsTest</td><td><em>Whidbey</em></td><td>Tests generating generics from CodeDom.</td></tr>
+<tr class="cls_whidbey"><td>GlobalKeywordTest</td><td><em>Whidbey</em></td><td>Test the global keyword used to differentiate global namespaces from local ones.</td></tr>
+<tr class="cls_whidbey"><td>ParamsTest</td><td><em>Everett</em></td><td>Tests variable method parameters.</td></tr>
+<tr class="cls_whidbey"><td>PartialClassTest</td><td><em>Whidbey</em></td><td>Tests partial classes.</td></tr>
+<tr class="cls_whidbey"><td>RegionDirectiveTest</td><td><em>Whidbey</em></td><td>Tests region directives on various code constructs.</td></tr>
+<tr class="cls_whidbey"><td>VerbatimOrderingTest</td><td><em>Whidbey</em></td><td>Tests if types and members are generated in the order they are specified in the tree.</td></tr>
+</table>
+ 
+</body>
+</html>
+
diff --git a/workyard/tests/codedom/build.bat b/workyard/tests/codedom/build.bat
new file mode 100755
index 0000000..e7bd219
--- /dev/null
+++ b/workyard/tests/codedom/build.bat
@@ -0,0 +1,54 @@
+ at if "%_echo%"=="" echo off
+
+setlocal
+if EXIST build.ok DEL /f /q build.ok
+
+call %~d0%~p0..\..\..\config.bat
+
+REM NOTE that this test does not call FSC.
+REM PEVERIFY not needed
+
+
+REM build C# projects
+del /s /q cdtsuite.exe > NUL 2>&1
+del /s /q test.out > NUL 2>&1
+del /s /q test.err > NUL 2>&1
+
+REM ==
+REM == Invoke resgen to create .cs files out of .resx
+REM ==
+%RESGEN% tests\Properties\Resources.resx    /str:cs,tests.Properties,Resources,tests\Properties\Resources.Designer.cs
+%RESGEN% CodeDomTest\Properties\Resources.resx /str:cs,CodeDomTest.Properties,Resources,CodeDomTest\Properties\Resources.Designer.cs
+
+%MSBUILDTOOLSPATH%\msbuild.exe CodeDomTest\CodeDOM.TestCore.csproj
+%MSBUILDTOOLSPATH%\msbuild.exe tests\CodeDOM.Tests.csproj
+%MSBUILDTOOLSPATH%\msbuild.exe CodeDOM.TestSuite.csproj
+
+REM Run the tests
+
+if not exist bin\Debug\CdtSuite.exe goto Error
+
+bin\Debug\CdtSuite.exe /testcaselib:bin\Debug\tests.dll /codedomproviderlib:%FSCBinPath%\fsharp.compiler.codedom.dll /codedomprovider:Microsoft.FSharp.Compiler.CodeDom.FSharpCodeProvider > test.out
+REM Do Not test ERRORLEVEL here, as the failures might be known.
+
+if not exist test.out goto Error
+type test.out
+
+type test.out | find /C "TEST FAILED" > test.err
+for /f %%c IN (test.err) do (if NOT "%%c"=="0" (
+   echo Error: CodeDom TEST FAILURES DETECTED IN TESTS PREVIOUSLY KNOWN TO PASS!
+   type test.out | find "TEST FAILED"
+   set NonexistentErrorLevel 2> nul
+   goto Error)
+)
+
+echo Ran fsharp CodeDom tests OK
+:Ok
+echo. > build.ok
+endlocal
+exit /b 0
+
+:Error
+call %SCRIPT_ROOT%\ChompErr.bat %ERRORLEVEL% %~f0
+endlocal
+exit /b %ERRORLEVEL%
\ No newline at end of file
diff --git a/workyard/tests/codedom/notesfortestcasewriters.html b/workyard/tests/codedom/notesfortestcasewriters.html
new file mode 100755
index 0000000..a2ccb22
--- /dev/null
+++ b/workyard/tests/codedom/notesfortestcasewriters.html
@@ -0,0 +1,191 @@
+<html>
+<style>
+    body {
+        margin-left: 5%;
+        margin-right: 5%;
+    }
+    h1,h2,h3 {
+        font-family: Arial, Helvetica, sans-serif;
+    }
+    p.optdesc {
+        margin-left: 2em;
+    }
+    div.usagescenario {
+        margin-top: 2em;
+        padding: 0.5em 1em 0.5em 1em;
+        border: solid 1px black;
+        background-color: #eee;
+    }
+    .note {
+        padding: 0.5em 1em 0.5em 1em;
+        border: dashed 2px red;
+        background-color: #ecc;
+    }
+    a {
+        color: #666;
+    }
+    a:visited {
+        color: #333;
+    }
+    table#testdesc {
+        font-size: 10pt;
+        font-family: Arial, Helvetica, sans-serif;
+        border-collapse: collapse;
+        border: solid 2px black;
+    }
+    table#testdesc th {
+        text-align: left;
+        border-right: solid 1px black;
+    }
+    table#testdesc td {
+        padding: 0.2em 1em 0.2em 0.2em;
+        margin: 0 0 0 0;
+        border-right: solid 1px black;
+    }
+
+    table#testdesc .cls_subset {
+        background-color: #6c9;
+    }
+
+    table#testdesc .cls_everett {
+        background-color: #69c;
+    }
+
+    table#testdesc .cls_whidbey {
+        background-color: #cc9;
+    }
+
+    code.type {
+        font-family: monospace;
+        color: blue;
+    }
+</style>
+<head><title>CodeDom Test Suite Readme</title></head>
+<body>
+
+<h1>Writing Test Cases for the CodeDom Test Suite</h1>
+Copyright (C) Microsoft Corp. 2004.  All rights reserved.
+
+<h2>Introduction</h2>
+
+<p style="color: red">Test suite <b>users</b> may want to refer to the
+<a href="README.html">CodeDom Test Suite Readme</a>
+document also located in this collection.  This document is for
+those who want to extend the test suite with their own test cases.</p>
+
+<p>
+The CodeDom test suite allows you to write and build test cases independent
+of the ones provided with the test suite.  These test cases all must derive
+from the class <code>CodeDomTest</code> (or its subtypes) located in
+<code>CodeDomTest.dll</code>.  This class provides the test suite a single
+interface with which to call and handle your test.  There is a subtype
+of <code>CodeDomTest</code>, namely <code>CodeDomTestTree</code>, that takes
+care of more details for you.  The differences between the two are described
+below.
+</p>
+
+<h2>Writing a Test Case</h2>
+
+<p class="note">Note in order to take advantage of the passed in options:
+saveassemblies and savesources, you must override CodeDomTestTree.</p>
+
+<p>The <code>CodeDomTest</code> class requires you to override the following
+properties and methods:</p>
+
+<ul>
+    <li><code class="type">TestTypes</code> TestType
+    <p>
+    Should return one of the following values from the <code class="type">TestTypes</code>
+    enum: <code class="identifier">Subset</code>, <code class="identifier">Everett</code>,
+    <code class="identifier">Whidbey</code>.  Refer to the <a href="README.html">readme</a>
+    for more information about these classifications.
+    </p>
+
+    <li><code class="type">string</code> Name
+    <p>
+    Returns the name of the test.  If you compile many tests into a single assembly,
+    the names should be unique otherwise the test suite will detect multiple names
+    and abort any test runs.
+    </p>
+
+    <li><code class="type">string</code> Description
+    <p>
+    Returns a short description of the test.  It is recommended that this be no longer
+    than one or two lines on the console window.
+    </p>
+
+    <li><code class="type">bool</code> Run (<code class="type">CodeDomProvider</code> provider)
+    <p>
+    This method does all the testing on the given provider.  The
+    <code class="type">CodeDomTestTree</code> implements this for you.  Returning
+    <code class="identifier">true</code> from this method signifies a test case pass.
+    <code class="identifier">false</code> signifies a fail.
+    </p>
+</ul>
+
+<h2>Using <code class="identifier">CodeDomTestTree</code></h2>
+
+<p>Many CodeDom provider tests do the same kind of verification test.  That is they:</p>
+
+<ol>
+    <li>Build a CodeDom tree,
+    <li>Generate and compile code from it using the provider,
+    <li>then verify it using reflection or some other mechanism.
+</ol>
+
+<p>The <code class="identifier">CodeDomTestTree</code> automates these three steps
+allowing you to focus on writing the test tree and verification.  It also provides
+sub-scenario verification.</p>
+
+<p>With these steps in mind, if you override <code class="identifier">CodeDomTestTree</code>, the
+following methods should be implemented (note that you must still implement
+the three TestType, Name and Description properties):</p>
+
+<ul>
+    <li><code class="type">bool</code> ShouldCompile
+    <p>
+    Signifies whether or not the generated CodeDom tree (from BuildTree) should compile.
+    </p>
+
+    <li><code class="type">bool</code> ShouldVerify
+    <p>
+    Signifies whether or not the compiled code from your CodeDom tree should be verified.
+    </p>
+
+    <li><code class="type">bool</code> ShouldSearch
+    <p>
+    Signifies whether or not the generated code from your CodeDom tree should be searched using
+    the provided <code class="identifier">Search</code> function.
+    </p>
+
+    <li><code class="type">void</code> BuildTree (<code class="type">CodeDomProvider</code> provider,
+    <code class="type">CodeCompileUnit</code> cu)
+    <p>
+        Takes the given provider and generates a tree in the given CodeCompileUnit.
+        This is where the bulk of your test case should reside.  You may use AddScenario()
+    </p>
+
+    <li><code class="type">void</code> VerifyAssembly (<code class="type">CodeDomProvider</code> provider,
+    <code class="type">Assembly</code> builtAssembly)
+    <p>
+        Runs verification of the compiled source code emitted by the provider.  The
+        source code is generated from the tree you built in BuildTree().  You should
+        use VerifyScenario() to verify any scenarios defined in BuildTree().  You may
+        also add new scenarios as long as they are also verified by the end of
+        VerifyAssembly()'s execution.  Refer to the accompanying documentation for
+        more information on how to write a test case.
+    </p>
+
+    <li><code class="type">void</code> Search (<code class="type">CodeDomProvider</code> provider
+    <code class="type">string</code> source)
+    <p>
+        Searches the given code output as you define.  The given string will
+        be the source code emitted by the given provider that was generated
+        from the tree defined in BuildTree().  You should use VerifyScenario()
+        as in VerifyAssembly() to match any successful scenarios.
+    </p>
+</ul>
+
+</body>
+</html>
+
diff --git a/workyard/tests/codedom/tests/CodeDOM.Tests.csproj b/workyard/tests/codedom/tests/CodeDOM.Tests.csproj
new file mode 100755
index 0000000..c6692ca
--- /dev/null
+++ b/workyard/tests/codedom/tests/CodeDOM.Tests.csproj
@@ -0,0 +1,105 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{096BAAF6-18DA-423B-AB9A-0A1E01A87A9D}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>tests</RootNamespace>
+    <AssemblyName>tests</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>2.0</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE;WHIDBEY</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugSymbols>false</DebugSymbols>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\</OutputPath>
+    <DefineConstants>TRACE;WHIDBEY</DefineConstants>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.JScript" />
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="arraytest.cs" />
+    <Compile Include="attributestest.cs" />
+    <Compile Include="binaryoperatorstest.cs" />
+    <Compile Include="callingfieldtest.cs" />
+    <Compile Include="callmethodtest.cs" />
+    <Compile Include="callmethodwdirect.cs" />
+    <Compile Include="castingcodedom.cs" />
+    <Compile Include="checksumtest.cs" />
+    <Compile Include="classtest.cs" />
+    <Compile Include="codeprimitiveexpressiontest.cs" />
+    <Compile Include="codesnippettest.cs" />
+    <Compile Include="commenttest.cs" />
+    <Compile Include="conditionalstatementtest.cs" />
+    <Compile Include="constructortest.cs" />
+    <Compile Include="createobjecttest.cs" />
+    <Compile Include="declarefield.cs" />
+    <Compile Include="declaremethod.cs" />
+    <Compile Include="delegatetest.cs" />
+    <Compile Include="enumtest.cs" />
+    <Compile Include="eventtest.cs" />
+    <Compile Include="generatorsupportstest.cs" />
+    <Compile Include="genericstest.cs" />
+    <Compile Include="globalkeywordtest.cs" />
+    <Compile Include="gototest.cs" />
+    <Compile Include="implementingstructstest.cs" />
+    <Compile Include="indexerstest.cs" />
+    <Compile Include="iterationstest.cs" />
+    <Compile Include="linepragmatest.cs" />
+    <Compile Include="namespacetest.cs" />
+    <Compile Include="overloadtest.cs" />
+    <Compile Include="paramstest.cs" />
+    <Compile Include="partialclasstest.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="propertiestest.cs" />
+    <Compile Include="regiondirectivetest.cs" />
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="structtest.cs" />
+    <Compile Include="subsetarraytest.cs" />
+    <Compile Include="subsetattributestest.cs" />
+    <Compile Include="subsetbinaryoperatorstest.cs" />
+    <Compile Include="subsetfieldstest.cs" />
+    <Compile Include="trycatchtest.cs" />
+    <Compile Include="typeoftest.cs" />
+    <Compile Include="typetest.cs" />
+    <Compile Include="unicodecharescapetest.cs" />
+    <Compile Include="verbatimorderingtest.cs" />
+    <AppDesigner Include="Properties\" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\CodeDomTest\CodeDOM.TestCore.csproj">
+      <Project>{09E715E3-DCEF-4A52-B784-33C52A452117}</Project>
+      <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
+      <Name>CodeDOM.TestCore</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+</Project>
\ No newline at end of file
diff --git a/workyard/tests/codedom/tests/CodeDOM.Tests.csproj.user b/workyard/tests/codedom/tests/CodeDOM.Tests.csproj.user
new file mode 100755
index 0000000..a2ec83c
--- /dev/null
+++ b/workyard/tests/codedom/tests/CodeDOM.Tests.csproj.user
@@ -0,0 +1,7 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="">
+    <LastOpenVersion>8.0.40607</LastOpenVersion>
+    <ProjectView>ProjectFiles</ProjectView>
+    <ProjectTrust>0</ProjectTrust>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/workyard/tests/codedom/tests/Properties/AssemblyInfo.cs b/workyard/tests/codedom/tests/Properties/AssemblyInfo.cs
new file mode 100755
index 0000000..9ce04a0
--- /dev/null
+++ b/workyard/tests/codedom/tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+#region Using directives
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+#endregion
+
+// 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("tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("tests")]
+[assembly: AssemblyCopyright("Copyright @ Microsoft 2004")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.*")]
diff --git a/workyard/tests/codedom/tests/Properties/Resources.resx b/workyard/tests/codedom/tests/Properties/Resources.resx
new file mode 100755
index 0000000..a814449
--- /dev/null
+++ b/workyard/tests/codedom/tests/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?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.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="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" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/workyard/tests/codedom/tests/Properties/Settings.settings b/workyard/tests/codedom/tests/Properties/Settings.settings
new file mode 100755
index 0000000..c7fa9fb
--- /dev/null
+++ b/workyard/tests/codedom/tests/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='iso-8859-1'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>
\ No newline at end of file
diff --git a/workyard/tests/codedom/tests/arraytest.cs b/workyard/tests/codedom/tests/arraytest.cs
new file mode 100755
index 0000000..5387d44
--- /dev/null
+++ b/workyard/tests/codedom/tests/arraytest.cs
@@ -0,0 +1,288 @@
+// F#: test originally generated: (a:int[]).[0] + (b:int64[]).[0] 
+//     which is incorrect, so I changed all numerical types to int
+
+using System;
+using System.IO;
+using System.CodeDom;
+using System.Reflection;
+using System.Collections;
+using System.CodeDom.Compiler;
+using System.Collections.Specialized;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.VisualBasic;
+
+public class ArrayTest : CodeDomTestTree {
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "ArrayTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests arrays.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+        CodeNamespace ns = new CodeNamespace ("Namespace1");
+        cu.Namespaces.Add (ns);
+
+        // GENERATES (C#):
+        //    public class Class2 {
+        //            public int number;
+        //        }
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ("Class2");
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        CodeMemberField field = new CodeMemberField (typeof (int), "number");
+        field.Attributes = MemberAttributes.Final | MemberAttributes.Public;
+        class1.Members.Add (field);
+
+        class1 = new CodeTypeDeclaration ();
+        class1.Name = "Class1";
+        class1.BaseTypes.Add (new CodeTypeReference (typeof (object)));
+        ns.Types.Add (class1);
+
+
+        // the following method tests sized arrays, initialized arrays, standard arrays of small size
+        // GENERATES (C#):
+        //       public long ArrayMethod(int parameter) {
+        //                int arraySize = 3;
+        //                int[] array1;
+        //                int[] array2 = new int[3];
+        //                int[] array3 = new int[] {1,
+        //                        4,
+        //                        9};
+        //                array1 = new int[arraySize];
+        //                long retValue = 0;
+        //                int i;
+        //                for (i = 0; (i < array1.Length); i = (i + 1)) {
+        //                    array1[i] = (i * i);
+        //                    array2[i] = (array1[i] - i);
+        //                    retValue = (retValue 
+        //                                + (array1[i] 
+        //                                + (array2[i] + array3[i])));
+        //                }
+        //                return retValue;
+        //            }
+
+        AddScenario ("CallArrayMethod", "Call and check the return value of ArrayMethod()");
+        CodeMemberMethod arrayMethod = new CodeMemberMethod ();
+        arrayMethod.Name = "ArrayMethod";
+        arrayMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "parameter"));
+        arrayMethod.Attributes = (arrayMethod.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        arrayMethod.ReturnType = new CodeTypeReference (typeof (System.Int32));
+
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (typeof (int), "arraySize", new CodePrimitiveExpression (3)));
+
+        // dummy array creates
+        arrayMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (int[]),
+                    "dummyArray1", new CodeArrayCreateExpression (typeof (int[]), 10)));
+        arrayMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (int[]),
+                    "dummyArray2", new CodeArrayCreateExpression (typeof (int[]),
+                        new CodeVariableReferenceExpression ("arraySize"))));
+
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (typeof (int[]), "array1"));
+
+        CodeArrayCreateExpression creatExp = new CodeArrayCreateExpression ();
+        creatExp.CreateType = new CodeTypeReference (typeof (int[]));
+        creatExp.Size = 3;
+
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (
+            new CodeTypeReference ("System.Int32", 1),
+            "array2",
+            creatExp));
+
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (
+            new CodeTypeReference ("System.Int32", 1),
+            "array3",
+            new CodeArrayCreateExpression (
+            new CodeTypeReference ("System.Int32", 1),
+            new CodeExpression[] {
+                new CodePrimitiveExpression ((int)1), 
+                new CodePrimitiveExpression ((int)4),
+                new CodePrimitiveExpression ((int)9), })));
+
+        creatExp = new CodeArrayCreateExpression ();
+        creatExp.CreateType = new CodeTypeReference (typeof (int[]));
+        creatExp.SizeExpression = new CodeVariableReferenceExpression ("arraySize");
+
+        arrayMethod.Statements.Add (new CodeAssignStatement (new CodeVariableReferenceExpression ("array1"), creatExp));
+        
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (typeof (System.Int32), "retValue", new CodePrimitiveExpression ((int)0))); 
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (typeof (int), "i"));
+        arrayMethod.Statements.Add (
+            new CodeIterationStatement (
+            new CodeAssignStatement (new CodeVariableReferenceExpression ("i"), new CodePrimitiveExpression (0)),
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("i"),
+            CodeBinaryOperatorType.LessThan,
+            new CodePropertyReferenceExpression (
+            new CodeVariableReferenceExpression ("array1"),
+            "Length")),
+            new CodeAssignStatement (
+            new CodeVariableReferenceExpression ("i"),
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("i"),
+            CodeBinaryOperatorType.Add,
+            new CodePrimitiveExpression (1))),
+            new CodeAssignStatement (
+            new CodeArrayIndexerExpression (
+            new CodeVariableReferenceExpression ("array1"),
+            new CodeVariableReferenceExpression ("i")),
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("i"),
+            CodeBinaryOperatorType.Multiply,
+            new CodeVariableReferenceExpression ("i"))),
+            new CodeAssignStatement (
+            new CodeArrayIndexerExpression (
+            new CodeVariableReferenceExpression ("array2"),
+            new CodeVariableReferenceExpression ("i")),
+            new CodeBinaryOperatorExpression (
+            new CodeArrayIndexerExpression (
+            new CodeVariableReferenceExpression ("array1"),
+            new CodeVariableReferenceExpression ("i")),
+            CodeBinaryOperatorType.Subtract,
+            new CodeVariableReferenceExpression ("i"))),
+            new CodeAssignStatement(
+            new CodeVariableReferenceExpression("retValue"),
+            new CodeBinaryOperatorExpression(
+            new CodeVariableReferenceExpression("retValue"),
+            CodeBinaryOperatorType.Add,
+            new CodeBinaryOperatorExpression(
+            new CodeArrayIndexerExpression(
+            new CodeVariableReferenceExpression("array1"),
+            new CodeVariableReferenceExpression("i")),
+            CodeBinaryOperatorType.Add,
+            new CodeBinaryOperatorExpression(
+            new CodeArrayIndexerExpression(
+            new CodeVariableReferenceExpression("array2"),
+            new CodeVariableReferenceExpression("i")),
+            CodeBinaryOperatorType.Add,
+            new CodeArrayIndexerExpression(
+            new CodeVariableReferenceExpression("array3"),
+            new CodeVariableReferenceExpression("i"))))))));
+        arrayMethod.Statements.Add(
+            new CodeMethodReturnStatement (new CodeVariableReferenceExpression ("retValue")));
+        class1.Members.Add (arrayMethod);
+
+
+        // GENERATES (C#):
+        //        public int MoreArrayTests(int i) {
+        //                int[][] arrayOfArrays = new int[][] {new int[] {3,
+        //                                4},
+        //                        new int[1],
+        //                        new int[0]};
+        //                int[] array2 = new int[0];
+        //                Class2[] arrayType = new Class2[2];
+        //                arrayType[1] = new Class2();
+        //                arrayType[1].number = (arrayOfArrays[0][1] + i);
+        //                return arrayType[1].number;
+        //            }
+
+        AddScenario ("CallMoreArrayTests", "Call and check the return value of MoreArrayTests()");
+        CodeMemberMethod secondMethod = new CodeMemberMethod ();
+        secondMethod.Name = "MoreArrayTests";
+        secondMethod.Attributes = (arrayMethod.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        secondMethod.ReturnType = new CodeTypeReference (typeof (int));
+        secondMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+
+        // array of arrays
+        // in Everett, VB doesn't support array of array initialization
+        if (Supports (provider, GeneratorSupport.ArraysOfArrays) && !(provider is VBCodeProvider)) {
+            secondMethod.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int[][])),
+                "arrayOfArrays", new CodeArrayCreateExpression (typeof (int[][]),
+                new CodeArrayCreateExpression (typeof (int[]), new CodePrimitiveExpression (3), new CodePrimitiveExpression (4)),
+                new CodeArrayCreateExpression (typeof (int[]), new CodePrimitiveExpression (1)), new CodeArrayCreateExpression (typeof (int[])))));
+        }
+
+        //empty array
+        secondMethod.Statements.Add (new CodeVariableDeclarationStatement (
+            new CodeTypeReference ("System.Int32", 1), "array2",
+            new CodeArrayCreateExpression (typeof (int[]), new CodePrimitiveExpression (0))));
+
+        // array of nonprimitive type
+        secondMethod.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference ("Class2", 1),
+            "arrayType", new CodeArrayCreateExpression (new CodeTypeReference ("Class2", 1), new CodePrimitiveExpression (2))));
+        secondMethod.Statements.Add (new CodeAssignStatement (new CodeArrayIndexerExpression (new CodeVariableReferenceExpression ("arrayType"),
+            new CodePrimitiveExpression (1)), new CodeObjectCreateExpression (new CodeTypeReference ("Class2"))));
+
+        // in Everett, VB doesn't support array of array initialization
+        if (Supports (provider, GeneratorSupport.ArraysOfArrays) && !(provider is VBCodeProvider)) {
+            secondMethod.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression
+                (new CodeArrayIndexerExpression (new CodeVariableReferenceExpression ("arrayType"),
+                new CodePrimitiveExpression (1)), "number"),
+                new CodeBinaryOperatorExpression (new CodeArrayIndexerExpression (
+                new CodeArrayIndexerExpression (new CodeVariableReferenceExpression ("arrayOfArrays"), new CodePrimitiveExpression (0))
+                , new CodePrimitiveExpression (1)),
+                CodeBinaryOperatorType.Add, new CodeArgumentReferenceExpression ("i"))));
+        }
+        else {
+            // If the code provider doesn't support ArrayOfArrays this is generated:
+            //   arrayType[1].number = i;
+            secondMethod.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression
+                (new CodeArrayIndexerExpression (new CodeVariableReferenceExpression ("arrayType"),
+                new CodePrimitiveExpression (1)), "number"),
+                new CodeArgumentReferenceExpression ("i")));
+
+        }
+        secondMethod.Statements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression
+            (new CodeArrayIndexerExpression (new CodeVariableReferenceExpression ("arrayType"),
+            new CodePrimitiveExpression (1)), "number")));
+
+        class1.Members.Add (secondMethod);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateClass1", "Find and instantiate Class1");
+        if (!FindAndInstantiate ("Namespace1.Class1", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClass1");
+
+        // Verify Array Operations
+        if (VerifyMethod (genType, genObject, "ArrayMethod", new object[] {0}, 21)) {
+            VerifyScenario ("CallArrayMethod");
+        }
+
+        // in Everett, VB doesn't support array of array initialization
+        if (Supports (provider, GeneratorSupport.ArraysOfArrays) && !(provider is VBCodeProvider)) {
+            if (VerifyMethod (genType, genObject, "MoreArrayTests", new object[] {43}, 47))
+                VerifyScenario ("CallMoreArrayTests");
+        }
+        else {
+            if (VerifyMethod (genType, genObject, "MoreArrayTests", new object[] {43}, 43))
+                VerifyScenario ("CallMoreArrayTests");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/attributestest.cs b/workyard/tests/codedom/tests/attributestest.cs
new file mode 100755
index 0000000..1669e02
--- /dev/null
+++ b/workyard/tests/codedom/tests/attributestest.cs
@@ -0,0 +1,506 @@
+// F#: The CodeDOM provider ignores type constructors (static constructors), 
+//     but this is handled because test suite checks for "Supports" flags
+//
+//     Next issue is that F# generates properties instead of fields (modified lookup in the test)
+
+using System;
+using System.IO;
+using System.CodeDom;
+using System.Reflection;
+using System.Collections;
+using System.CodeDom.Compiler;
+using System.Xml.Serialization;
+using System.Collections.Specialized;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.CSharp;
+using Microsoft.VisualBasic;
+using Microsoft.JScript;
+
+public class AttributesTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "AttributesTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests metadata attributes.";
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override CompilerParameters GetCompilerParameters (CodeDomProvider provider) {
+        CompilerParameters parms = base.GetCompilerParameters (provider);
+
+        // some languages don't compile correctly if no executable is
+        // generated and an entry point is defined
+        if (Supports (provider, GeneratorSupport.EntryPointMethod)) {
+            parms.GenerateExecutable = true;
+        }
+        return parms;
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // GENERATES (C#):
+        // [assembly: System.Reflection.AssemblyTitle("MyAssembly")]
+        // [assembly: System.Reflection.AssemblyVersion("1.0.6.2")]
+        // [assembly: System.CLSCompliantAttribute(false)]
+        // 
+        // namespace MyNamespace {
+        //     using System;
+        //     using System.Drawing;
+        //     using System.Windows.Forms;
+        //     using System.ComponentModel;
+        //
+        CodeNamespace ns = new CodeNamespace ();
+        ns.Name = "MyNamespace";
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        ns.Imports.Add (new CodeNamespaceImport ("System.Drawing"));
+        ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+        ns.Imports.Add (new CodeNamespaceImport ("System.ComponentModel"));
+        cu.Namespaces.Add (ns);
+
+        cu.ReferencedAssemblies.Add ("System.Xml.dll");
+        cu.ReferencedAssemblies.Add ("System.Drawing.dll");
+        cu.ReferencedAssemblies.Add ("System.Windows.Forms.dll");
+
+        // Assembly Attributes
+        if (Supports (provider, GeneratorSupport.AssemblyAttributes)) {
+            AddScenario ("CheckAssemblyAttributes", "Check that assembly attributes get generated properly.");
+            CodeAttributeDeclarationCollection attrs = cu.AssemblyCustomAttributes;
+            attrs.Add (new CodeAttributeDeclaration ("System.Reflection.AssemblyTitle", new
+                CodeAttributeArgument (new CodePrimitiveExpression ("MyAssembly"))));
+            attrs.Add (new CodeAttributeDeclaration ("System.Reflection.AssemblyVersion", new
+                CodeAttributeArgument (new CodePrimitiveExpression ("1.0.6.2"))));
+            attrs.Add (new CodeAttributeDeclaration ("System.CLSCompliantAttribute", new
+                CodeAttributeArgument (new CodePrimitiveExpression (false))));
+        }
+
+        // GENERATES (C#):
+        //     [System.Serializable()]
+        //     [System.Obsolete("Don\'t use this Class")]
+        //     [System.Windows.Forms.AxHost.ClsidAttribute("Class.ID")]
+        //     public class MyClass {
+        //
+#if !WHIDBEY
+        // Everett versions of C# and VB code providers will never have these generated properly
+        if (!(provider is CSharpCodeProvider) && !(provider is VBCodeProvider) && !(provider is JScriptCodeProvider))
+            AddScenario ("CheckClassAttributes", "Check that class attributes get generated properly.");
+#else
+        AddScenario ("CheckClassAttributes", "Check that class attributes get generated properly.");
+#endif
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "MyClass";
+        class1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Serializable"));
+        class1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+            CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Class"))));
+        class1.CustomAttributes.Add (new
+            CodeAttributeDeclaration (typeof (System.Windows.Forms.AxHost.ClsidAttribute).FullName,
+            new CodeAttributeArgument (new CodePrimitiveExpression ("Class.ID"))));
+        ns.Types.Add (class1);
+
+        // GENERATES (C#):
+        //         [System.Serializable()]
+        //         public class NestedClass {
+        //         }
+
+        if (Supports (provider, GeneratorSupport.NestedTypes)) {
+#if !WHIDBEY
+        // Everett versions of C# and VB code providers will never have these generated properly
+        if (!(provider is CSharpCodeProvider) && !(provider is VBCodeProvider) && !(provider is JScriptCodeProvider))
+            AddScenario ("CheckNestedClassAttributes", "Check that nested class attributes get generated properly.");
+#else
+            AddScenario ("CheckNestedClassAttributes", "Check that nested class attributes get generated properly.");
+#endif
+            CodeTypeDeclaration nestedClass = new CodeTypeDeclaration ("NestedClass");
+            nestedClass.TypeAttributes = TypeAttributes.NestedPublic;
+            nestedClass.IsClass = true;
+            nestedClass.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Serializable"));
+            class1.Members.Add (nestedClass);
+        }
+
+        // GENERATES (C#):
+        //         [System.Obsolete("Don\'t use this Method")]
+        //         [System.ComponentModel.Editor("This", "That")]
+        //         public void MyMethod([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)] string blah, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)] int[] arrayit) {
+        //         }
+        AddScenario ("CheckMyMethodAttributes", "Check that attributes are generated properly on MyMethod().");
+        CodeMemberMethod method1 = new CodeMemberMethod ();
+        method1.Attributes = (method1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        method1.Name = "MyMethod";
+        method1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+            CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Method"))));
+        method1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.ComponentModel.Editor", new
+            CodeAttributeArgument (new CodePrimitiveExpression ("This")), new CodeAttributeArgument (new
+            CodePrimitiveExpression ("That"))));
+        CodeParameterDeclarationExpression param1 = new CodeParameterDeclarationExpression (typeof (string), "blah");
+
+        if (Supports (provider, GeneratorSupport.ParameterAttributes)) {
+            AddScenario ("CheckParameterAttributes", "Check that parameter attributes are generated properly.");
+            param1.CustomAttributes.Add (
+                new CodeAttributeDeclaration (
+                "System.Xml.Serialization.XmlElement",
+                new CodeAttributeArgument (
+                "Form",
+                new CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("System.Xml.Schema.XmlSchemaForm"), "Unqualified")),
+                new CodeAttributeArgument (
+                "IsNullable",
+                new CodePrimitiveExpression (false))));
+        }
+        method1.Parameters.Add (param1);
+        CodeParameterDeclarationExpression param2 = new CodeParameterDeclarationExpression (typeof (int[]), "arrayit");
+
+        if (Supports (provider, GeneratorSupport.ParameterAttributes)) {
+            param2.CustomAttributes.Add (
+                new CodeAttributeDeclaration (
+                "System.Xml.Serialization.XmlElement",
+                new CodeAttributeArgument (
+                "Form",
+                new CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("System.Xml.Schema.XmlSchemaForm"), "Unqualified")),
+                new CodeAttributeArgument (
+                "IsNullable",
+                new CodePrimitiveExpression (false))));
+        }
+        //param2.CustomAttributes.Add(new CodeAttributeDeclaration("System.ParamArray"));
+        method1.Parameters.Add (param2);
+        class1.Members.Add (method1);
+
+        // GENERATES (C#):
+        //         [System.Obsolete("Don\'t use this Function")]
+        //         [return: System.Xml.Serialization.XmlIgnoreAttribute()]
+        //         [return: System.Xml.Serialization.XmlRootAttribute(Namespace="Namespace Value", ElementName="Root, hehehe")]
+        //         public string MyFunction() {
+        //             return "Return";
+        //         }
+        //
+        if (Supports (provider, GeneratorSupport.ReturnTypeAttributes)) {
+            AddScenario ("CheckMyFunctionAttributes", "Check return type attributes.");
+            CodeMemberMethod function1 = new CodeMemberMethod ();
+            function1.Attributes = MemberAttributes.Public;
+            function1.Name = "MyFunction";
+            function1.ReturnType = new CodeTypeReference (typeof (string));
+            function1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+                CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Function"))));
+
+            function1.ReturnTypeCustomAttributes.Add (new
+                CodeAttributeDeclaration ("System.Xml.Serialization.XmlIgnoreAttribute"));
+            function1.ReturnTypeCustomAttributes.Add (new CodeAttributeDeclaration ("System.Xml.Serialization.XmlRootAttribute", new
+                CodeAttributeArgument ("Namespace", new CodePrimitiveExpression ("Namespace Value")), new
+                CodeAttributeArgument ("ElementName", new CodePrimitiveExpression ("Root, hehehe"))));
+            function1.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression ("Return")));
+            class1.Members.Add (function1);
+        }
+
+        // GENERATES (C#):
+        //         [System.Xml.Serialization.XmlElementAttribute()]
+        //         private string myField = "hi!";
+        //
+        AddScenario ("CheckMyFieldAttributes", "Check that attributes are generated properly on MyField.");
+        CodeMemberField field1 = new CodeMemberField ();
+        field1.Name = "myField";
+        field1.Attributes = MemberAttributes.Public;
+        field1.Type = new CodeTypeReference (typeof (string));
+        field1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Xml.Serialization.XmlElementAttribute"));
+        field1.InitExpression = new CodePrimitiveExpression ("hi!");
+        class1.Members.Add (field1);
+
+
+        // GENERATES (C#):
+        //         [System.Obsolete("Don\'t use this Property")]
+        //         public string MyProperty {
+        //             get {
+        //                 return this.myField;
+        //             }
+        //         }
+        AddScenario ("CheckMyPropertyAttributes", "Check that attributes are generated properly on MyProperty.");
+        CodeMemberProperty prop1 = new CodeMemberProperty ();
+        prop1.Attributes = MemberAttributes.Public;
+        prop1.Name = "MyProperty";
+        prop1.Type = new CodeTypeReference (typeof (string));
+        prop1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+            CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Property"))));
+        prop1.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "myField")));
+        class1.Members.Add (prop1);
+
+        // GENERATES (C#):
+        //         [System.Obsolete("Don\'t use this Constructor")]
+        //         public MyClass() {
+        //         }
+
+        if (!(provider is JScriptCodeProvider))
+            AddScenario ("CheckConstructorAttributes", "Check that attributes are generated properly on the constructor.");
+        CodeConstructor const1 = new CodeConstructor ();
+        const1.Attributes = MemberAttributes.Public;
+        const1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+            CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Constructor"))));
+        class1.Members.Add (const1);
+
+        // GENERATES (C#):
+        //         [System.Obsolete("Don\'t use this Constructor")]
+        //         static MyClass() {
+        //         }
+
+        if (Supports (provider, GeneratorSupport.StaticConstructors)) {
+
+            // C#, VB and JScript code providers don't generate this properly.  This will
+            // be fixed in Beta2 (with the exception of JScript code provider.  JScript doesn't
+            // support static constructor custom attributes)
+            //if (!(provider is CSharpCodeProvider) && !(provider is VBCodeProvider) && !(provider is JScriptCodeProvider)) {
+                AddScenario ("CheckStaticConstructorAttributes", "Check that attributes are generated properly on type constructors.");
+            //}
+            CodeTypeConstructor typecons = new CodeTypeConstructor ();
+            typecons.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+                CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Constructor"))));
+            class1.Members.Add (typecons);
+        }
+
+        // GENERATES (C#):
+        //         [System.Obsolete ("Don\'t use this entry point")]
+        //         public static void Main () {
+        //         }
+        if (Supports (provider, GeneratorSupport.EntryPointMethod)) {
+            // C#, VB and JScript code providers don't generate this properly.  This will
+            // be fixed in Beta2 (with the exception of JScript code provider.  JScript doesn't
+            // support static constructor custom attributes)
+            ///if (!(provider is CSharpCodeProvider) && !(provider is VBCodeProvider) && !(provider is JScriptCodeProvider)) {
+                AddScenario ("CheckEntryPointMethodAttributes", "Check that attributes are generated properly on entry point methods.");
+            //}
+            CodeEntryPointMethod entpoint = new CodeEntryPointMethod ();
+            entpoint.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+                CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this entry point"))));
+            class1.Members.Add (entpoint);
+        }
+
+        if (Supports (provider, GeneratorSupport.DeclareDelegates)) {
+            AddScenario ("CheckDelegateAttributes");
+            CodeTypeDelegate del = new CodeTypeDelegate ("MyDelegate");
+            del.TypeAttributes = TypeAttributes.Public;
+            del.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+                CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this delegate"))));
+            ns.Types.Add (del);
+        }
+
+        if (Supports (provider, GeneratorSupport.DeclareEvents)) {
+            // GENERATES (C#):
+            //     public class Test : Form {
+            //         
+            //         private Button b = new Button();
+            //
+            // 
+            AddScenario ("CheckEventAttributes", "test attributes on an event");
+            class1 = new CodeTypeDeclaration ("Test");
+            class1.IsClass = true;
+            class1.BaseTypes.Add (new CodeTypeReference ("Form"));
+            ns.Types.Add (class1);
+            CodeMemberField mfield = new CodeMemberField (new CodeTypeReference ("Button"), "b");
+            mfield.InitExpression = new CodeObjectCreateExpression (new CodeTypeReference ("Button"));
+            class1.Members.Add (mfield);
+
+            // GENERATES (C#):
+            //         public Test() {
+            //             this.Size = new Size(600, 600);
+            //             b.Text = "Test";
+            //             b.TabIndex = 0;
+            //             b.Location = new Point(400, 525);
+            //             this.MyEvent += new EventHandler(this.b_Click);
+            //         }
+            //
+            CodeConstructor ctor = new CodeConstructor ();
+            ctor.Attributes = MemberAttributes.Public;
+            ctor.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (),
+                "Size"), new CodeObjectCreateExpression (new CodeTypeReference ("Size"),
+                new CodePrimitiveExpression (600), new CodePrimitiveExpression (600))));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Text"), new CodePrimitiveExpression ("Test")));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "TabIndex"), new CodePrimitiveExpression (0)));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Location"), new CodeObjectCreateExpression (new CodeTypeReference ("Point"),
+                new CodePrimitiveExpression (400), new CodePrimitiveExpression (525))));
+            ctor.Statements.Add (new CodeAttachEventStatement (new CodeEventReferenceExpression (new
+                CodeThisReferenceExpression (), "MyEvent"), new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler")
+                , new CodeThisReferenceExpression (), "b_Click")));
+            class1.Members.Add (ctor);
+
+            // GENERATES (C#):
+            //         [System.CLSCompliantAttribute(false)]
+            //         public event System.EventHandler MyEvent;
+            CodeMemberEvent evt = new CodeMemberEvent ();
+            evt.Name = "MyEvent";
+            evt.Type = new CodeTypeReference ("System.EventHandler");
+            evt.Attributes = MemberAttributes.Public;
+            evt.CustomAttributes.Add (new CodeAttributeDeclaration ("System.CLSCompliantAttribute", new CodeAttributeArgument (new CodePrimitiveExpression (false))));
+            class1.Members.Add (evt);
+
+            // GENERATES (C#):
+            //         private void b_Click(object sender, System.EventArgs e) {
+            //         }
+            //     }
+            // }
+            //
+            CodeMemberMethod cmm = new CodeMemberMethod ();
+            cmm.Name = "b_Click";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (object), "sender"));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (EventArgs), "e"));
+            class1.Members.Add (cmm);
+        }
+
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        Type genType;
+
+        // Verifying Assembly Attributes
+        if (Supports (provider, GeneratorSupport.AssemblyAttributes)) {
+            object[] attributes = asm.GetCustomAttributes (true);
+
+            bool verifiedAssemblyAttributes = VerifyAttribute (attributes, typeof (AssemblyTitleAttribute), "Title", "MyAssembly");
+            verifiedAssemblyAttributes &=
+                VerifyAttribute (attributes, typeof (AssemblyVersionAttribute), "Version", "1.0.6.2") ||
+                asm.GetName ().Version.Equals (new Version (1, 0, 6, 2));
+
+            if (verifiedAssemblyAttributes) {
+                VerifyScenario ("CheckAssemblyAttributes");
+            }
+        }
+
+        object[] customAttributes;
+        object[] customAttributes2;
+        object[] customAttributesAll;
+
+        if (FindType ("MyNamespace.MyClass", asm, out genType)) {
+            customAttributes    = genType.GetCustomAttributes (typeof (System.ObsoleteAttribute), true);
+            customAttributes2   = genType.GetCustomAttributes (typeof (System.SerializableAttribute), true);
+            customAttributesAll = genType.GetCustomAttributes (true);
+
+#if !WHIDBEY
+            // see note about class attributes
+            if (!(provider is CSharpCodeProvider) && !(provider is VBCodeProvider) && !(provider is JScriptCodeProvider)) {
+#endif
+                if (customAttributes.GetLength (0) == 1 &&
+                        customAttributes2.GetLength (0) >= 1 &&
+                        customAttributesAll.GetLength (0) >= 3) {
+                    VerifyScenario ("CheckClassAttributes");
+                }
+
+                // verify nested class attributes
+                if (Supports (provider, GeneratorSupport.NestedTypes)) {
+                    Type nestedType = genType.GetNestedType ("NestedClass");
+                    customAttributes = nestedType.GetCustomAttributes (typeof (System.SerializableAttribute), true);
+                    if (customAttributes.GetLength (0) == 1) {
+                        VerifyScenario ("CheckNestedClassAttributes");
+                    }
+                }
+#if !WHIDBEY
+            }
+#endif
+
+            // verify method attributes
+            MethodInfo methodInfo = genType.GetMethod ("MyMethod");
+            if (methodInfo != null &&
+                    methodInfo.GetCustomAttributes (typeof (System.ObsoleteAttribute), true).GetLength (0) > 0 &&
+                    methodInfo.GetCustomAttributes (typeof (System.ComponentModel.EditorAttribute), true).GetLength (0) > 0) {
+                VerifyScenario ("CheckMyMethodAttributes");
+
+                // verify parameter attributes
+                ParameterInfo[] paramInfo = methodInfo.GetParameters ();
+                if (paramInfo != null && paramInfo.Length >= 2 &&
+                        Supports (provider, GeneratorSupport.ParameterAttributes) &&
+                        paramInfo[0].GetCustomAttributes (typeof (System.Xml.Serialization.XmlElementAttribute), true).GetLength (0) > 0 &&
+                        paramInfo[1].GetCustomAttributes (typeof (System.Xml.Serialization.XmlElementAttribute), true).GetLength (0) > 0) {
+                    VerifyScenario ("CheckParameterAttributes");
+                }
+            }
+
+            // verify property attributes
+            PropertyInfo propertyInfo = genType.GetProperty ("MyProperty");
+            if (propertyInfo != null &&
+                    propertyInfo.GetCustomAttributes (typeof (System.ObsoleteAttribute), true).GetLength (0) > 0) {
+                VerifyScenario ("CheckMyPropertyAttributes");
+            }
+
+            // verify constructor attributes
+            ConstructorInfo[] constructorInfo = genType.GetConstructors ();
+            if (constructorInfo != null && constructorInfo.Length > 0 && !(provider is JScriptCodeProvider) &&
+                    constructorInfo[0].GetCustomAttributes (typeof (System.ObsoleteAttribute), true).GetLength (0) > 0) {
+                VerifyScenario ("CheckConstructorAttributes");
+            }
+
+            // verify type constructor attributes if its supported
+            if (Supports (provider, GeneratorSupport.StaticConstructors)) {
+                ConstructorInfo typeInit = genType.TypeInitializer;
+                if (typeInit != null &&
+                    typeInit.GetCustomAttributes (typeof (System.ObsoleteAttribute), true).GetLength (0) > 0) {
+                    VerifyScenario ("CheckStaticConstructorAttributes");
+                }
+            }
+            
+            // verify entry point method attributes if supported
+            if (Supports (provider, GeneratorSupport.EntryPointMethod)) {
+                methodInfo = asm.EntryPoint;
+                if (methodInfo != null &&
+                        methodInfo.GetCustomAttributes (typeof (System.ObsoleteAttribute), true).GetLength (0) > 0)
+                    VerifyScenario ("CheckEntryPointMethodAttributes");
+            }
+
+            // verify delegate attributes if supported
+            if (Supports (provider, GeneratorSupport.DeclareDelegates)) {
+                Type delType = null;
+                if (FindType ("MyNamespace.MyDelegate", asm, out delType) && delType != null &&
+                        delType.GetCustomAttributes (typeof (System.ObsoleteAttribute), true).GetLength (0) > 0)
+                    VerifyScenario ("CheckDelegateAttributes");
+            }
+
+            // verify field attributes
+            FieldInfo fieldInfo = genType.GetField("myField"); 
+            if (fieldInfo != null &&
+                    fieldInfo.GetCustomAttributes (typeof (System.Xml.Serialization.XmlElementAttribute), true).GetLength (0) > 0) {
+                VerifyScenario ("CheckMyFieldAttributes");
+            }
+
+            // test named and unnamed arguments for attributes and return type attributes
+            if (Supports (provider, GeneratorSupport.ReturnTypeAttributes)) {
+                methodInfo = genType.GetMethod ("MyFunction");
+                if (methodInfo != null &&
+                        methodInfo.GetCustomAttributes (typeof (System.ObsoleteAttribute), true).GetLength (0) > 0) {
+                    ICustomAttributeProvider returnTypeAttributes = methodInfo.ReturnTypeCustomAttributes;
+                    if (returnTypeAttributes.IsDefined (typeof (System.Xml.Serialization.XmlRootAttribute), true) &&
+                           returnTypeAttributes.IsDefined (typeof (System.Xml.Serialization.XmlIgnoreAttribute), true)) {
+                        VerifyScenario ("CheckMyFunctionAttributes");
+                    }
+                }
+            }
+        }
+
+        // verify event attributes
+        if (Supports (provider, GeneratorSupport.DeclareEvents) && FindType ("MyNamespace.Test", asm, out genType)) {
+            EventInfo eventInfo = genType.GetEvent ("MyEvent");
+            if (eventInfo != null &&
+                    eventInfo.GetCustomAttributes (typeof (System.CLSCompliantAttribute), true).GetLength (0) > 0) {
+                VerifyScenario ("CheckEventAttributes");
+            }
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/binaryoperatorstest.cs b/workyard/tests/codedom/tests/binaryoperatorstest.cs
new file mode 100755
index 0000000..6a69e9e
--- /dev/null
+++ b/workyard/tests/codedom/tests/binaryoperatorstest.cs
@@ -0,0 +1,281 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class BinaryOperatorsTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "BinaryOperatorsTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests binary operators.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // GENERATES (C#):
+        //  namespace Namespace1 {
+        //      using System;
+        //      
+        //      
+        //      public class Class1 : object {
+        //          
+        //          public int ReturnMethod(int intInput) {
+
+        CodeNamespace ns = new CodeNamespace ("Namespace1");
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (ns);
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "Class1";
+        class1.BaseTypes.Add (new CodeTypeReference (typeof (object)));
+        ns.Types.Add (class1);
+
+        AddScenario ("CheckReturnMethod", "Tests varying operators.");
+        CodeMemberMethod retMethod = new CodeMemberMethod ();
+        retMethod.Name = "ReturnMethod";
+        retMethod.Attributes = (retMethod.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        retMethod.ReturnType = new CodeTypeReference (typeof (int));
+        retMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "intInput"));
+
+        // GENERATES (C#):
+        //              int x1 = ((18 
+        //                          / (6 - 4)) 
+        //                          * intInput);
+        //
+        // in VB (a = a/a) generates an warning if a is integer. Cast the expression just for VB language. 
+        CodeBinaryOperatorExpression cboExpression = new CodeBinaryOperatorExpression (
+            new CodeBinaryOperatorExpression (
+            new CodePrimitiveExpression (18),
+            CodeBinaryOperatorType.Divide,
+            new CodeBinaryOperatorExpression (
+            new CodePrimitiveExpression (6),
+            CodeBinaryOperatorType.Subtract,
+            new CodePrimitiveExpression (4))),
+            CodeBinaryOperatorType.Multiply,
+            new CodeArgumentReferenceExpression ("intInput"));
+
+        CodeVariableDeclarationStatement variableDeclaration = null;
+        if (provider is Microsoft.VisualBasic.VBCodeProvider)
+            variableDeclaration = new CodeVariableDeclarationStatement (typeof (int), "x1", new CodeCastExpression (typeof (int), cboExpression));
+        else
+            variableDeclaration = new CodeVariableDeclarationStatement (typeof (int), "x1", cboExpression);
+
+        retMethod.Statements.Add (variableDeclaration);
+
+        // GENERATES (C#):
+        //              int x2 = (19 % 8);
+        retMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (
+            typeof (int),
+            "x2",
+            new CodeBinaryOperatorExpression (
+            new CodePrimitiveExpression (19),
+            CodeBinaryOperatorType.Modulus,
+            new CodePrimitiveExpression (8))));
+
+        // GENERATES (C#):
+        //              int x3 = ((15 & 35) 
+        //                          | 129);
+        retMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (
+            typeof (int),
+            "x3",
+            new CodeBinaryOperatorExpression (
+            new CodeBinaryOperatorExpression (
+            new CodePrimitiveExpression (15),
+            CodeBinaryOperatorType.BitwiseAnd,
+            new CodePrimitiveExpression (35)),
+            CodeBinaryOperatorType.BitwiseOr,
+            new CodePrimitiveExpression (129))));
+
+        // GENERATES (C#):
+        //              int x4 = 0;
+        retMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (
+            typeof (int),
+            "x4",
+            new CodePrimitiveExpression (0)));
+
+        // GENERATES (C#):
+        //              if (((x2 == 3) 
+        //                          || (x3 < 129))) {
+        //                  x4 = (x4 + 1);
+        //              }
+        //              else {
+        //                  x4 = (x4 + 2);
+        //              }
+
+        retMethod.Statements.Add (
+            new CodeConditionStatement (
+            new CodeBinaryOperatorExpression (
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("x2"),
+            CodeBinaryOperatorType.ValueEquality,
+            new CodePrimitiveExpression (3)),
+            CodeBinaryOperatorType.BooleanOr,
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("x3"),
+            CodeBinaryOperatorType.LessThan,
+            new CodePrimitiveExpression (129))),
+            CDHelper.CreateIncrementByStatement ("x4", 1),
+            CDHelper.CreateIncrementByStatement ("x4", 2)));
+
+        // GENERATES (C#):
+        //              if (((x2 > -1) 
+        //                          && (x3 >= 5000))) {
+        //                  x4 = (x4 + 4);
+        //              }
+        //              else {
+        //                  x4 = (x4 + 8);
+        //              }
+        retMethod.Statements.Add (
+            new CodeConditionStatement (
+            new CodeBinaryOperatorExpression (
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("x2"),
+            CodeBinaryOperatorType.GreaterThan,
+            new CodePrimitiveExpression (-1)),
+            CodeBinaryOperatorType.BooleanAnd,
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("x3"),
+            CodeBinaryOperatorType.GreaterThanOrEqual,
+            new CodePrimitiveExpression (5000))),
+            CDHelper.CreateIncrementByStatement ("x4", 4),
+            CDHelper.CreateIncrementByStatement ("x4", 8)));
+
+        // GENERATES (C#):
+        //              if (((x2 <= 3) 
+        //                          && (x3 != 1))) {
+        //                  x4 = (x4 + 16);
+        //              }
+        //              else {
+        //                  x4 = (x4 + 32);
+        //              }
+        retMethod.Statements.Add (
+            new CodeConditionStatement (
+            new CodeBinaryOperatorExpression (
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("x2"),
+            CodeBinaryOperatorType.LessThanOrEqual,
+            new CodePrimitiveExpression (3)),
+            CodeBinaryOperatorType.BooleanAnd,
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("x3"),
+            CodeBinaryOperatorType.IdentityInequality,
+            new CodePrimitiveExpression (1))),
+            CDHelper.CreateIncrementByStatement ("x4", 16),
+            CDHelper.CreateIncrementByStatement ("x4", 32)));
+
+
+        // GENERATES (C#):
+        //              return (x1 
+        //                          + (x2 
+        //                          + (x3 + x4)));
+        //          }
+        retMethod.Statements.Add (
+            new CodeMethodReturnStatement (
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("x1"),
+            CodeBinaryOperatorType.Add,
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("x2"),
+            CodeBinaryOperatorType.Add,
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("x3"),
+            CodeBinaryOperatorType.Add,
+            new CodeVariableReferenceExpression ("x4"))))));
+        class1.Members.Add (retMethod);
+
+        //          
+        // GENERATES (C#):
+        //          public int SecondReturnMethod(int intInput) {
+        //              // To test CodeBinaryOperatorType.IdentityEquality operator
+        //              if ((((Object)(intInput)) == ((Object)(5)))) {
+        //                  return 5;
+        //              }
+        //              else {
+        //                  return 4;
+        //              }
+        //          }
+        //      }
+        AddScenario ("CheckSecondReturnMethod", "Tests identity equality.");
+        retMethod = new CodeMemberMethod ();
+        retMethod.Name = "SecondReturnMethod";
+        retMethod.Attributes = (retMethod.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        retMethod.ReturnType = new CodeTypeReference (typeof (int));
+        retMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "intInput"));
+
+        retMethod.Statements.Add (new CodeCommentStatement ("To test CodeBinaryOperatorType.IdentiEquality operator"));
+        retMethod.Statements.Add (
+            new CodeConditionStatement (
+            new CodeBinaryOperatorExpression (new CodeCastExpression ("Object",
+            new CodeArgumentReferenceExpression ("intInput")),
+            CodeBinaryOperatorType.IdentityEquality, new CodeCastExpression ("Object",
+            new CodePrimitiveExpression (5))),
+            new CodeStatement[] {new CodeMethodReturnStatement (new
+                CodePrimitiveExpression (5))}, new CodeStatement[] {new
+                CodeMethodReturnStatement (new CodePrimitiveExpression (4))}));
+        class1.Members.Add (retMethod);
+
+        // GENERATES (C#):
+        //      public class Class2 : object {
+        //      }
+        //  }
+
+        /*class1 = new CodeTypeDeclaration ();
+        class1.Name = "Class2";
+        class1.BaseTypes.Add (new CodeTypeReference (typeof (object)));
+        ns.Types.Add (class1);*/
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateClass1", "Find and instantiate Class1 from the assembly.");
+        if (!FindAndInstantiate ("Namespace1.Class1", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClass1");
+
+        // Verify Return value from function
+        if (VerifyMethod (genType, genObject, "ReturnMethod", new object[] {5}, 230)) {
+            VerifyScenario ("CheckReturnMethod");
+        }
+
+        if (VerifyMethod (genType, genObject, "SecondReturnMethod", new object[] {5}, 4) &&
+                VerifyMethod (genType, genObject, "SecondReturnMethod", new object[] {8}, 4)) {
+            VerifyScenario ("CheckSecondReturnMethod");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/callingfieldtest.cs b/workyard/tests/codedom/tests/callingfieldtest.cs
new file mode 100755
index 0000000..baa02cd
--- /dev/null
+++ b/workyard/tests/codedom/tests/callingfieldtest.cs
@@ -0,0 +1,171 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class CallingFieldTest : CodeDomTestTree {
+
+    public override string Comment
+    {
+        get
+        {
+            return "Static Fields with an InitExpression are Not Initialized Correctly";
+        }
+    }
+    public override TestTypes TestType
+    {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "CallingFieldTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests calling fields.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        nspace.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (nspace);
+
+
+        // declare class with fields
+
+        // GENERATES (C#):
+        //    public class ClassWithFields {
+        //        // only if provider supports GeneratorSupport.PublicStaticMembers
+        //        public static string Microsoft = "hi";
+        //        public static int StaticPublicField = 5;
+        //        // ---
+        //
+        //        public int NonStaticPublicField = 6;
+        //        private int PrivateField = 7;
+        //        public int UsePrivateField(int i) {
+        //            this.PrivateField = i;
+        //            return this.PrivateField;
+        //        }
+        //    }
+        CodeTypeDeclaration cd = new CodeTypeDeclaration ("ClassWithFields");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        CodeMemberField field;
+        if (Supports (provider, GeneratorSupport.PublicStaticMembers)) {
+
+            field = new CodeMemberField ("System.String", "Microsoft");
+            field.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            field.InitExpression = new CodePrimitiveExpression ("hi");
+            cd.Members.Add (field);
+
+            field = new CodeMemberField ();
+            field.Name = "StaticPublicField";
+            field.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            field.Type = new CodeTypeReference (typeof (int));
+            field.InitExpression = new CodePrimitiveExpression (5);
+            cd.Members.Add (field);
+        }
+
+        field = new CodeMemberField ();
+        field.Name = "NonStaticPublicField";
+        field.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (6);
+        cd.Members.Add (field);
+
+        field = new CodeMemberField ();
+        field.Name = "PrivateField";
+        field.Attributes = MemberAttributes.Private | MemberAttributes.Final;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (7);
+        cd.Members.Add (field);
+
+        // create a method to test access to private field
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "UsePrivateField";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+        cmm.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "PrivateField"), new CodeArgumentReferenceExpression ("i")));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "PrivateField")));
+        cd.Members.Add (cmm);
+
+        // GENERATES (C#):
+        //    public class TestFields {
+        //        public static int UseFields(int i) {
+        //            ClassWithFields number = new ClassWithFields();
+        //            return ((number.NonStaticPublicField + number.UsePrivateField(i)) 
+        //                        + ClassWithFields.StaticPublicField); // <-- only if supported
+        //        }
+        //    }
+        cd = new CodeTypeDeclaration ("TestFields");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        AddScenario ("CheckUseFields");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "UseFields";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference ("ClassWithFields"), "number", new CodeObjectCreateExpression ("ClassWithFields")));
+        CodeBinaryOperatorExpression binaryOpExpression = new CodeBinaryOperatorExpression (new CodeFieldReferenceExpression
+            (new CodeVariableReferenceExpression ("number"), "NonStaticPublicField"), CodeBinaryOperatorType.Add,
+            new CodeMethodInvokeExpression (
+            new CodeVariableReferenceExpression ("number"), "UsePrivateField", new CodeArgumentReferenceExpression ("i")));
+
+        if (Supports (provider, GeneratorSupport.PublicStaticMembers))
+            binaryOpExpression = new CodeBinaryOperatorExpression (binaryOpExpression,
+                    CodeBinaryOperatorType.Add, new CodeFieldReferenceExpression (
+                        new CodeTypeReferenceExpression ("ClassWithFields"), "StaticPublicField"));
+
+        cmm.Statements.Add (new CodeMethodReturnStatement (binaryOpExpression));
+        cd.Members.Add (cmm);
+
+
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateTestFields", "Find and instantiate TestFields class.");
+        if (!FindAndInstantiate("NSPC.TestFields", asm, out genObject, out genType)) // F#: edit .. no nested classes
+            return;
+        VerifyScenario ("InstantiateTestFields");
+
+        if (Supports (provider, GeneratorSupport.PublicStaticMembers)) {
+            if (VerifyMethod (genType, genObject, "UseFields", new object[]{3}, 14))
+                VerifyScenario ("CheckUseFields");
+        } else {
+            if (VerifyMethod (genType, genObject, "UseFields", new object[]{3}, 9))
+                VerifyScenario ("CheckUseFields");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/callmethodtest.cs b/workyard/tests/codedom/tests/callmethodtest.cs
new file mode 100755
index 0000000..6fd01ad
--- /dev/null
+++ b/workyard/tests/codedom/tests/callmethodtest.cs
@@ -0,0 +1,364 @@
+// F#: added type casts from subtype
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class CallMethodTest : CodeDomTestTree {
+
+		public override string Comment
+		{
+			get
+			{
+				return "F# doesn't support C# 'new' keyword";
+			}
+		}
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "CallMethodTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests calling methods.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        nspace.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (nspace);
+
+        CodeTypeDeclaration cd = new CodeTypeDeclaration ("TEST");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+
+        // GENERATES (C#):
+        //        public int CallingOverrideScenario(int i) {
+        //            ClassWVirtualMethod t = new ClassWOverrideMethod();
+        //            return t.VirtualMethod(i);
+        //        }
+        AddScenario ("Check1CallingOverrideScenario", "Check an overridden method.");
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "CallingOverrideScenario";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeVariableDeclarationStatement ("ClassWVirtualMethod", "t", new CodeCastExpression(new CodeTypeReference("ClassWVirtualMethod"), new CodeObjectCreateExpression ("ClassWOverrideMethod"))));
+        CodeMethodInvokeExpression methodinvoke = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t"), "VirtualMethod");
+        methodinvoke.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+        cmm.Statements.Add (new CodeMethodReturnStatement (methodinvoke));
+        cd.Members.Add (cmm);
+
+        // declare a method without parameters
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "NoParamsMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (16)));
+        cd.Members.Add (cmm);
+
+        // declare a method with multiple parameters
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "MultipleParamsMethod";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "b"));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new
+            CodeArgumentReferenceExpression ("a"), CodeBinaryOperatorType.Add,
+            new CodeArgumentReferenceExpression ("b"))));
+        cd.Members.Add (cmm);
+
+        // call method with no parameters, call a method with multiple parameters, 
+        // and call a method from a method call
+        //         public virtual int CallParamsMethods() {
+        //              TEST t = new TEST();
+        //              int val;
+        //              val = t.NoParamsMethod ();
+        //              return t.MultipleParamsMethod(78, val);
+        //         }
+        AddScenario ("CheckCallParamsMethod", "Check CheckCallParamsMethod.");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "CallParamsMethods";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference ("TEST"), "t", new CodeObjectCreateExpression ("TEST")));
+
+        CodeVariableReferenceExpression cvre = new CodeVariableReferenceExpression (); //To increase code coverage
+        cvre.VariableName = "t";
+
+        CodeVariableReferenceExpression valCVRE = new CodeVariableReferenceExpression ();
+        valCVRE.VariableName = "val";
+
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "val"));
+        cmm.Statements.Add (new CodeAssignStatement (valCVRE,
+                    CDHelper.CreateMethodInvoke (new CodeVariableReferenceExpression ("t"), "NoParamsMethod")));
+
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (cvre,
+            "MultipleParamsMethod", new CodePrimitiveExpression (78), valCVRE)));
+        cd.Members.Add (cmm);
+
+        // method to test the 'new' scenario by calling the 'new' method
+        // GENERATES (C#):
+        //        public int CallingNewScenario(int i) {
+        //            ClassWVirtualMethod t = new ClassWNewMethod();
+        //            int x1;
+        //            int x2;
+        //            x1 = ((ClassWNewMethod)(t)).VirtualMethod(i);
+        //            x2 = t.VirtualMethod(i);
+        //            return (x1 - x2);
+        //        }
+        AddScenario ("CheckCallingNewScenario", "Check CheckCallingNewScenario.");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "CallingNewScenario";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Attributes = MemberAttributes.Public;
+
+        cmm.Statements.Add (new CodeVariableDeclarationStatement ("ClassWVirtualMethod", "t", new CodeCastExpression(new CodeTypeReference("ClassWVirtualMethod"), new CodeObjectCreateExpression ("ClassWNewMethod"))));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "x1"));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "x2"));
+
+
+        methodinvoke = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t"), "VirtualMethod");
+        methodinvoke.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+
+        CodeMethodInvokeExpression methodinvoke2 = new CodeMethodInvokeExpression (new CodeCastExpression ("ClassWNewMethod", new
+            CodeVariableReferenceExpression ("t")), "VirtualMethod");
+        methodinvoke2.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+
+        cmm.Statements.Add (new CodeAssignStatement (new CodeVariableReferenceExpression ("x1"),
+                    methodinvoke2));
+
+        cmm.Statements.Add (new CodeAssignStatement (new CodeVariableReferenceExpression ("x2"),
+                    methodinvoke));
+
+        cmm.Statements.Add (new CodeMethodReturnStatement (
+            CDHelper.CreateBinaryOperatorExpression ("x1", CodeBinaryOperatorType.Subtract, "x2")));
+
+        cd.Members.Add (cmm);
+
+
+        // ***************** declare method using new ******************
+        // first declare a class with a virtual method in it 
+        // GENERATES (C#):
+        //         public class ClassWVirtualMethod {
+        //                 public virtual int VirtualMethod(int a) {
+        //                     return a;
+        //                 }
+        //         }    
+        cd = new CodeTypeDeclaration ("ClassWVirtualMethod");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "VirtualMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+        cd.Members.Add (cmm);
+
+        // now declare a class that inherits from the previous class and has a 'new' method with the
+        // name VirtualMethod
+        // GENERATES (C#):
+        //    public class ClassWNewMethod : ClassWVirtualMethod {
+        //         public new virtual int VirtualMethod(int a) {
+        //             return (2 * a);
+        //         }
+        //     }
+        cd = new CodeTypeDeclaration ("ClassWNewMethod");
+        cd.BaseTypes.Add (new CodeTypeReference ("ClassWVirtualMethod"));
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "VirtualMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.New;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+            new CodePrimitiveExpression (2), CodeBinaryOperatorType.Multiply
+            , new CodeArgumentReferenceExpression ("a"))));
+        cd.Members.Add (cmm);
+
+        // now declare a class that inherits from the previous class and has a 'new' method with the
+        // name VirtualMethod
+        // GENERATES (C#):
+        //            public class ClassWOverrideMethod : ClassWVirtualMethod {
+        //                 public override int VirtualMethod(int a) {
+        //                     return (2 * a);
+        //                 }
+        //             }
+        cd = new CodeTypeDeclaration ("ClassWOverrideMethod");
+        cd.BaseTypes.Add (new CodeTypeReference ("ClassWVirtualMethod"));
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "VirtualMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Override;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+            new CodePrimitiveExpression (2), CodeBinaryOperatorType.Multiply
+            , new CodeArgumentReferenceExpression ("a"))));
+        cd.Members.Add (cmm);
+
+        //*************** overload member function ****************             
+        // new class which will include both functions
+        // GENERATES (C#):
+        //    public class TEST7 {
+        //         public int OverloadedMethod(int a) {
+        //             return a;
+        //         }
+        //         public int OverloadedMethod(int a, int b) {
+        //             return (b + a);
+        //         }
+        //         public int CallingOverloadedMethods(int i) {
+        //             int one = OverloadedMethod(i, i);
+        //             int two = OverloadedMethod(i);
+        //             return (one - two);
+        //         }
+        //     }
+        AddScenario ("CheckTEST7.CallingOverloadedMethods", "Check CallingOverloadedMethods()");
+        cd = new CodeTypeDeclaration ("TEST7");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "OverloadedMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+        cd.Members.Add (cmm);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "OverloadedMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "b"));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+            new CodeArgumentReferenceExpression ("b"), CodeBinaryOperatorType.Add,
+            new CodeArgumentReferenceExpression ("a"))));
+        cd.Members.Add (cmm);
+
+        // declare a method that will call both OverloadedMethod functions
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "CallingOverloadedMethods";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.Attributes = MemberAttributes.Public;
+        CodeMethodReferenceExpression methodref = new CodeMethodReferenceExpression ();
+        methodref.MethodName = "OverloadedMethod";
+
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "one",
+            new CodeMethodInvokeExpression (methodref, new
+            CodeArgumentReferenceExpression ("i"), new CodeArgumentReferenceExpression ("i"))));
+
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "two",
+            new CodeMethodInvokeExpression (methodref, new
+            CodeArgumentReferenceExpression ("i"))));
+
+        cmm.Statements.Add (new CodeMethodReturnStatement (
+                    CDHelper.CreateBinaryOperatorExpression ("one", CodeBinaryOperatorType.Subtract, "two")));
+        cd.Members.Add (cmm);
+
+
+        // GENERATES (C#):
+        //
+        //   namespace NSPC2 {
+        //   
+        //   
+        //       public class TEST {
+        //   
+        //           public virtual int CallingOverrideScenario(int i) {
+        //               NSPC.ClassWVirtualMethod t = new NSPC.ClassWOverrideMethod();
+        //               return t.VirtualMethod(i);
+        //           }
+        //       }
+        //   }
+        
+        nspace = new CodeNamespace ("NSPC2");
+        cu.Namespaces.Add (nspace);
+
+        cd = new CodeTypeDeclaration ("TEST");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        AddScenario ("Check2CallingOverrideScenario", "Check CallingOverrideScenario()");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "CallingOverrideScenario";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeVariableDeclarationStatement ("NSPC.ClassWVirtualMethod", "t", new CodeCastExpression(new CodeTypeReference("NSPC.ClassWVirtualMethod"), new CodeObjectCreateExpression ("NSPC.ClassWOverrideMethod"))));
+        methodinvoke = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t"), "VirtualMethod");
+        methodinvoke.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+        cmm.Statements.Add (new CodeMethodReturnStatement (methodinvoke));
+        cd.Members.Add (cmm);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object otest;
+        object otest7;
+        object onspc2test;
+        Type   ttest;
+        Type   ttest7;
+        Type   tnspc2test;
+
+        AddScenario ("InstantiateTEST", "Find and instantiate TEST.");
+        if (!FindAndInstantiate ("NSPC.TEST", asm, out otest, out ttest))
+            return;
+        VerifyScenario ("InstantiateTEST");
+
+        AddScenario ("InstantiateTEST7", "Find and instantiate TEST.");
+        if (!FindAndInstantiate ("NSPC.TEST7", asm, out otest7, out ttest7))
+            return;
+        VerifyScenario ("InstantiateTEST7");
+
+        AddScenario ("InstantiateNSPC2.TEST", "Find and instantiate TEST.");
+        if (!FindAndInstantiate ("NSPC2.TEST", asm, out onspc2test, out tnspc2test))
+            return;
+        VerifyScenario ("InstantiateNSPC2.TEST");
+
+        if (VerifyMethod (ttest, otest, "CallingOverrideScenario", new object[] {2}, 4)) {
+            VerifyScenario ("Check1CallingOverrideScenario");
+        }
+        if (VerifyMethod (tnspc2test, onspc2test, "CallingOverrideScenario", new object[] {3}, 6)) {
+            VerifyScenario ("Check2CallingOverrideScenario");
+        }
+        if (VerifyMethod (ttest, otest, "CallParamsMethods", null, 94)) {
+            VerifyScenario ("CheckCallParamsMethod");
+        }
+        if (VerifyMethod (ttest7, otest7, "CallingOverloadedMethods", new object[] {22}, 22)) {
+            VerifyScenario ("CheckTEST7.CallingOverloadedMethods");
+        }
+        if (VerifyMethod (ttest, otest, "CallingNewScenario", new object[] {5}, 5)) {
+            VerifyScenario ("CheckCallingNewScenario");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/callmethodwdirect.cs b/workyard/tests/codedom/tests/callmethodwdirect.cs
new file mode 100755
index 0000000..ba7213d
--- /dev/null
+++ b/workyard/tests/codedom/tests/callmethodwdirect.cs
@@ -0,0 +1,129 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class CallMethodWDirect : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "CallMethodWDirect";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Call a method with a direction";
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        nspace.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (nspace);
+
+        CodeTypeDeclaration cd = new CodeTypeDeclaration ("TEST");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        if (Supports (provider, GeneratorSupport.ReferenceParameters)) {
+            //    GENERATE (C#):      
+            //    void Work(ref int i, out int j) {
+            //             i = (i + 4);
+            //             j = 5;
+            //   }
+
+            CodeMemberMethod cmm = new CodeMemberMethod ();
+            cmm.Name = "Work";
+            cmm.ReturnType = new CodeTypeReference ("System.Void");
+            // add parameter with ref direction
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            param.Direction = FieldDirection.Ref;
+            cmm.Parameters.Add (param);
+            // add parameter with out direction
+            param = new CodeParameterDeclarationExpression (typeof (int), "j");
+            param.Direction = FieldDirection.Out;
+            cmm.Parameters.Add (param);
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("i"),
+                new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.Add, new CodePrimitiveExpression (4))));
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("j"),
+                new CodePrimitiveExpression (5)));
+            cd.Members.Add (cmm);
+
+            // add a method that calls method work to verify that ref and out are working properly 
+            // GENERATE (C#):
+            //       public int CallingWork(int a) {
+            //        a = 10;
+            //        int b;
+            //        Work(ref a, out b);
+            //        return (a + b);
+            //        }
+            AddScenario ("CheckCallingWork", "Check the return value of CallingWork().");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "CallingWork";
+            cmm.Attributes = MemberAttributes.Public;
+            CodeParameterDeclarationExpression parames = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (parames);
+            cmm.ReturnType = new CodeTypeReference ("System.Int32");
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"),
+                new CodePrimitiveExpression (10)));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "b"));
+            // invoke the method called "work"
+            CodeMethodInvokeExpression methodinvoked = new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (null,
+                        "Work"));
+            // add parameter with ref direction
+            CodeDirectionExpression parameter = new CodeDirectionExpression (FieldDirection.Ref,
+                new CodeArgumentReferenceExpression ("a"));
+            methodinvoked.Parameters.Add (parameter);
+            // add parameter with out direction
+            parameter = new CodeDirectionExpression (FieldDirection.Out, new CodeVariableReferenceExpression ("b"));
+            methodinvoked.Parameters.Add (parameter);
+            cmm.Statements.Add (methodinvoked);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression
+                (new CodeArgumentReferenceExpression ("a"), CodeBinaryOperatorType.Add, new CodeVariableReferenceExpression ("b"))));
+            cd.Members.Add (cmm);
+        }
+    }
+
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        if (Supports (provider, GeneratorSupport.ReferenceParameters)) {
+            AddScenario ("InstantiateTEST", "Find and instantiate CLASSNAME.");
+            if (!FindAndInstantiate ("NSPC.TEST", asm, out genObject, out genType))
+                return;
+            VerifyScenario ("InstantiateTEST");
+
+            // verify method return value, verify that ref and out worked accordingly
+            if (VerifyMethod (genType, genObject, "CallingWork", new object[] {5}, 19)) {
+                VerifyScenario ("CheckCallingWork");
+            }
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/castingcodedom.cs b/workyard/tests/codedom/tests/castingcodedom.cs
new file mode 100755
index 0000000..03e1da7
--- /dev/null
+++ b/workyard/tests/codedom/tests/castingcodedom.cs
@@ -0,0 +1,166 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using System.Windows.Forms;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class CastingCodeDom : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "CastingCodeDom";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests casting";
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // create a namespace
+        CodeNamespace ns = new CodeNamespace ("NS");
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+        cu.ReferencedAssemblies.Add ("System.Windows.Forms.dll");
+        cu.Namespaces.Add (ns);
+
+        // create a class
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "Test";
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+
+        // create method to test casting enum -> int
+        //     GENERATE (C#):
+        //        public int EnumToInt(System.Windows.Forms.AnchorStyles enum1) {
+        //            return ((int)(enum1));
+        //        }
+        AddScenario ("CheckEnumToInt1", "Check the return value of EnumToInt() with a single flag");
+        AddScenario ("CheckEnumToInt2", "Check the return value of EnumToInt() with multiple flags");
+        CodeMemberMethod enumToInt = new CodeMemberMethod ();
+        enumToInt.Name = "EnumToInt";
+        enumToInt.ReturnType = new CodeTypeReference (typeof (int));
+        enumToInt.Attributes = MemberAttributes.Public;
+        CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (System.Windows.Forms.AnchorStyles), "enum1");
+        enumToInt.Parameters.Add (param);
+        enumToInt.Statements.Add (new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new CodeArgumentReferenceExpression ("enum1"))));
+        class1.Members.Add (enumToInt);
+
+        // create method to test casting enum -> int
+        //     GENERATE (C#):
+        //       public virtual int CastReturnValue(string value) {
+        //          float val = System.Single.Parse(value, System.Globalization.CultureInfo.InvariantCulture);
+        //          return ((int) val);
+        //       }
+        AddScenario ("CheckCastReturnValue", "Check the return value of CastReturnValue()");
+        CodeMemberMethod castReturnValue = new CodeMemberMethod ();
+        castReturnValue.Name = "CastReturnValue";
+        castReturnValue.ReturnType = new CodeTypeReference (typeof (int));
+        castReturnValue.Attributes = MemberAttributes.Public;
+        CodeParameterDeclarationExpression strParam = new CodeParameterDeclarationExpression (typeof (string), "value");
+        castReturnValue.Parameters.Add (strParam);
+        castReturnValue.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "val",
+                    CDHelper.CreateMethodInvoke (new CodeTypeReferenceExpression (new CodeTypeReference ("System.Int32")), // F#: Type conversion "int -> float" is not a type-cast!
+                        "Parse", new CodeArgumentReferenceExpression ("value"),
+                        new CodePropertyReferenceExpression (new CodeTypeReferenceExpression ("System.Globalization.CultureInfo"),
+                            "InvariantCulture"))));
+        castReturnValue.Statements.Add (new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new CodeVariableReferenceExpression ("val"))));
+        class1.Members.Add (castReturnValue);
+
+
+        // create method to test casting interface -> class
+        //     GENERATE (C#):
+        //        public string CastInterface(System.ICloneable value) {
+        //            return ((string)(value));
+        //        }
+        AddScenario ("CheckCastInterface", "Check the return value of CastInterface()");
+        CodeMemberMethod castInterface = new CodeMemberMethod ();
+        castInterface.Name = "CastInterface";
+        castInterface.ReturnType = new CodeTypeReference (typeof (string));
+        castInterface.Attributes = MemberAttributes.Public;
+        CodeParameterDeclarationExpression interfaceParam = new CodeParameterDeclarationExpression (typeof (System.ICloneable), "value");
+        castInterface.Parameters.Add (interfaceParam);
+        castInterface.Statements.Add (new CodeMethodReturnStatement (new CodeCastExpression (typeof (string), new CodeArgumentReferenceExpression ("value"))));
+        class1.Members.Add (castInterface);
+
+        // create method to test casting value type -> reference type
+        //     GENERATE (C#):
+        //         public object ValueToReference(int value) {
+        //             return ((object)(value));
+        //         }
+        AddScenario ("CheckValueToReference", "Check the return value of ValueToReference()");
+        CodeMemberMethod valueToReference = new CodeMemberMethod ();
+        valueToReference.Name = "ValueToReference";
+        valueToReference.ReturnType = new CodeTypeReference (typeof (System.Object));
+        valueToReference.Attributes = MemberAttributes.Public;
+        CodeParameterDeclarationExpression valueParam = new CodeParameterDeclarationExpression (typeof (int), "value");
+        valueToReference.Parameters.Add (valueParam);
+        valueToReference.Statements.Add (new CodeMethodReturnStatement (new CodeCastExpression (typeof (System.Object), new CodeArgumentReferenceExpression ("value"))));
+        class1.Members.Add (valueToReference);
+
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateTest", "Find and instantiate CLASSNAME.");
+        if (!FindAndInstantiate ("NS.Test", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTest");
+
+        // enum -> int single value
+        if (VerifyMethod (genType, genObject, "EnumToInt", new object[] {System.Windows.Forms.AnchorStyles.Top}, 1)) {
+            VerifyScenario ("CheckEnumToInt1");
+        }
+
+        // enum -> int multiple flags set
+        if (VerifyMethod (genType, genObject, "EnumToInt", new object[] {System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right}, 9)) {
+            VerifyScenario ("CheckEnumToInt2");
+        }
+
+        // casting a return value of a method
+        if (VerifyMethod (genType, genObject, "CastReturnValue", new object[] {"1"}, (int)1)) { // F#: type cast is not a type conversion 
+            VerifyScenario ("CheckCastReturnValue");
+        }
+
+        // interface (IClonable) -> class (String)
+        ICloneable str = "Hello World";
+        if (VerifyMethod (genType, genObject, "CastInterface", new object[] {str}, (string) str)) {
+            VerifyScenario ("CheckCastInterface");
+        }
+
+        // value type (int) -> reference type (object)
+        int i = 10;
+        if (VerifyMethod (genType, genObject, "ValueToReference", new object[] {i}, (object) i)) {
+            VerifyScenario ("CheckValueToReference");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/checksumtest.cs b/workyard/tests/codedom/tests/checksumtest.cs
new file mode 100755
index 0000000..f982a4a
--- /dev/null
+++ b/workyard/tests/codedom/tests/checksumtest.cs
@@ -0,0 +1,159 @@
+using System;
+using System.IO;
+using System.CodeDom;
+using System.Reflection;
+using System.Collections;
+using System.CodeDom.Compiler;
+using System.Collections.Specialized;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.VisualBasic;
+using Microsoft.JScript;
+
+public class CheckSumTest : CodeDomTestTree {
+
+		public override string Comment
+		{
+			get { return "no #pragma checksum in F# afaik"; }
+		}		
+
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Whidbey;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return false;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return false;
+        }
+    }
+
+    public override bool ShouldSearch {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "CheckSumTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Checksum testing.";
+        }
+    }
+
+    private Guid HashMD5 = new Guid(0x406ea660, 0x64cf, 0x4c82, 0xb6, 0xf0, 0x42, 0xd4, 0x81, 0x72, 0xa7, 0x99);
+    private Guid HashSHA1 = new Guid(0xff1816ec, 0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60);        
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+#if WHIDBEY
+        // VB code provider doesn't currently generate checksum statements.  This
+        // will be completed before the next release of the CLR.
+        // JScript does not currently support checksum pragmas.
+        if (!(provider is VBCodeProvider) && !(provider is JScriptCodeProvider)) {
+            // GENERATES (C#):
+            // #pragma checksum "c:\foo\bar\OuterLinePragma.txt" "{406ea660-64cf-4c82-b6f0-42d48172a799}" "DEAD"
+            // #pragma checksum "bogus.txt" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "F00BAA"
+            // #pragma checksum "" "{00000000-0000-0000-0000-000000000000}" ""
+            //
+            //  // Namespace Comment
+            //  namespace Namespace1 {
+            //      
+            //      
+            //      // Outer Type Comment
+            //      
+            //      #line 300 "c:\foo\bar\OuterLinePragma.txt"
+            //      public class Class1 {
+            //          
+            //          public void Method1() {
+            //          }
+            //          
+            //          // Method 2 Comment
+            //          public void Method2() {
+            //          }
+            //      }
+            //      
+            //      #line default
+            //      #line hidden
+            //  }
+
+            AddScenario ("CheckPragmasInSrcCode", "Checks to see if the pragmas are in the generated source code.");
+            CodeChecksumPragma pragma1 = new CodeChecksumPragma();
+            pragma1.FileName = "c:\\foo\\bar\\OuterLinePragma.txt";
+            pragma1.ChecksumAlgorithmId = HashMD5;
+            pragma1.ChecksumData = new byte[] {0xDE, 0xAD};            
+            cu.StartDirectives.Add(pragma1);
+            CodeChecksumPragma pragma2 = new CodeChecksumPragma("bogus.txt", HashSHA1, new byte[]{0xF0, 0x0B, 0xAA});
+            cu.StartDirectives.Add(pragma2);
+            CodeChecksumPragma pragma3 = new CodeChecksumPragma();
+            cu.StartDirectives.Add(pragma3);
+
+            CodeNamespace ns = new CodeNamespace("Namespace1");
+            ns.Comments.Add(new CodeCommentStatement("Namespace Comment"));
+
+            cu.Namespaces.Add(ns);
+
+            CodeTypeDeclaration cd = new CodeTypeDeclaration ("Class1");
+            ns.Types.Add(cd);
+
+            cd.Comments.Add(new CodeCommentStatement("Outer Type Comment"));
+            cd.LinePragma = new CodeLinePragma("c:\\foo\\bar\\OuterLinePragma.txt", 300);
+
+            CodeMemberMethod method1 = new CodeMemberMethod();
+            method1.Name = "Method1";
+            method1.Attributes = (method1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;            
+
+
+            CodeMemberMethod method2 = new CodeMemberMethod();
+            method2.Name = "Method2";
+            method2.Attributes = (method2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            method2.Comments.Add(new CodeCommentStatement("Method 2 Comment"));                                            
+
+            cd.Members.Add(method1);
+            cd.Members.Add(method2);
+        }
+#endif
+    }
+
+    public override void Search (CodeDomProvider provider, string strGeneratedCode)  {
+#if WHIDBEY
+        // see note above
+        if (!(provider is VBCodeProvider) && !(provider is JScriptCodeProvider)) {
+            string[] strPragmas = new string[] { @"""{406ea660-64cf-4c82-b6f0-42d48172a799}"" ""DEAD""", 
+                                                @"""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""F00BAA""",
+                                                @"""{00000000-0000-0000-0000-000000000000}"" """""};
+            int startIndex = 0; 
+            bool valid = true;
+
+            for (int i = 0; i < strPragmas.Length; i++) {
+                startIndex = strGeneratedCode.IndexOf (strPragmas[i], startIndex);
+                if (startIndex ==  -1) {
+                    valid = false;
+                    break;
+                } else
+                    startIndex += strPragmas[i].Length ;
+            }
+
+            if (valid)
+                VerifyScenario ("CheckPragmasInSrcCode");
+        }
+#endif
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        // no verification, just searching
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/classtest.cs b/workyard/tests/codedom/tests/classtest.cs
new file mode 100755
index 0000000..6e30be7
--- /dev/null
+++ b/workyard/tests/codedom/tests/classtest.cs
@@ -0,0 +1,536 @@
+// F#: Added cast where initializing variable with subclass
+//     Removed test for 'sealed' classes
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class ClassTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "ClassTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests classes.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        nspace.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (nspace);
+
+        cu.ReferencedAssemblies.Add ("System.Windows.Forms.dll");
+
+        CodeTypeDeclaration cd = new CodeTypeDeclaration ("TestingClass");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        CodeMemberMethod cmm;
+        CodeMethodInvokeExpression methodinvoke;
+
+        // GENERATES (C#):
+        //        public int CallingPublicNestedScenario(int i) {
+        //                PublicNestedClassA.PublicNestedClassB2.PublicNestedClassC t = 
+        //                        new PublicNestedClassA.PublicNestedClassB2.PublicNestedClassC();
+        //                return t.publicNestedClassesMethod(i);
+        //        }
+        if (Supports (provider, GeneratorSupport.NestedTypes)) {
+            AddScenario ("CheckCallingPublicNestedScenario");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "CallingPublicNestedScenario";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference
+                ("PublicNestedClassA+PublicNestedClassB2+PublicNestedClassC"), "t",
+                new CodeObjectCreateExpression (new CodeTypeReference
+                ("PublicNestedClassA+PublicNestedClassB2+PublicNestedClassC"))));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t"),
+                "publicNestedClassesMethod",
+                new CodeArgumentReferenceExpression ("i"))));
+            cd.Members.Add (cmm);
+
+            AddScenario ("CheckCallingPrivateNestedScenario");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "CallingPrivateNestedScenario";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference
+                ("PrivateNestedClassA"), "t",
+                new CodeObjectCreateExpression (new CodeTypeReference ("PrivateNestedClassA"))));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t"),
+                "TestPrivateNestedClass",
+                new CodeArgumentReferenceExpression ("i"))));
+            cd.Members.Add (cmm);
+        }
+
+        // GENERATES (C#):
+        //        public int CallingAbstractScenario(int i) {
+        //            InheritAbstractClass t = new InheritAbstractClass();
+        //            return t.AbstractMethod(i);
+        //        }
+        AddScenario ("CheckCallingAbstractScenario");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "CallingAbstractScenario";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        cmm.Statements.Add (new CodeVariableDeclarationStatement ("InheritAbstractClass", "t", new CodeObjectCreateExpression ("InheritAbstractClass")));
+        methodinvoke = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t"), "AbstractMethod");
+        methodinvoke.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+        cmm.Statements.Add (new CodeMethodReturnStatement (methodinvoke));
+        cd.Members.Add (cmm);
+
+
+        if (Supports (provider, GeneratorSupport.DeclareInterfaces)) {
+            // testing multiple interface implementation class
+            // GENERATES (C#):
+            //        public int TestMultipleInterfaces(int i) {
+            //             TestMultipleInterfaceImp t = new TestMultipleInterfaceImp();
+            //             InterfaceA interfaceAobject = ((InterfaceA)(t));
+            //             InterfaceB interfaceBobject = ((InterfaceB)(t));
+            //             return (interfaceAobject.InterfaceMethod(i) - interfaceBobject.InterfaceMethod(i));
+            //         }
+            if (Supports (provider, GeneratorSupport.MultipleInterfaceMembers)) {
+                cmm = new CodeMemberMethod();
+                cmm.Name = "TestMultipleInterfaces";
+                cmm.ReturnType = new CodeTypeReference(typeof(int));
+                cmm.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "i"));
+                cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+                cmm.Statements.Add(new CodeVariableDeclarationStatement("TestMultipleInterfaceImp","t",new CodeObjectCreateExpression("TestMultipleInterfaceImp")));
+                cmm.Statements.Add(new CodeVariableDeclarationStatement("InterfaceA", "interfaceAobject", new CodeCastExpression("InterfaceA" , 
+                                         new CodeVariableReferenceExpression("t"))));
+                cmm.Statements.Add(new CodeVariableDeclarationStatement("InterfaceB", "interfaceBobject", new CodeCastExpression("InterfaceB" , 
+                                         new CodeVariableReferenceExpression("t"))));
+                methodinvoke = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("interfaceAobject")
+                                                  , "InterfaceMethod");
+                methodinvoke.Parameters.Add(new CodeArgumentReferenceExpression("i"));
+                CodeMethodInvokeExpression methodinvoke2 = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("interfaceBobject")
+                                                  , "InterfaceMethod");
+                methodinvoke2.Parameters.Add(new CodeArgumentReferenceExpression("i"));
+                cmm.Statements.Add(new CodeMethodReturnStatement(new CodeBinaryOperatorExpression(
+                                         methodinvoke , 
+                                         CodeBinaryOperatorType.Subtract, methodinvoke2)));
+                cd.Members.Add(cmm);
+            }
+
+            // testing single interface implementation
+            // GENERATES (C#):
+            //        public int TestSingleInterface(int i) {
+            //             TestMultipleInterfaceImp t = new TestMultipleInterfaceImp();
+            //             return t.InterfaceMethod(i);
+            //         }
+            AddScenario ("CheckTestSingleInterface");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "TestSingleInterface";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+            cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("TestSingleInterfaceImp", "t", new CodeObjectCreateExpression ("TestSingleInterfaceImp")));
+            methodinvoke = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t")
+                , "InterfaceMethod");
+            methodinvoke.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+            cmm.Statements.Add (new CodeMethodReturnStatement (methodinvoke));
+            cd.Members.Add (cmm);
+        }
+
+
+        // similar to the 'new' test, write a method to complete testing of the 'override' scenario
+        // GENERATES (C#):
+        //        public int CallingOverrideScenario(int i) {
+        //            ClassWVirtualMethod t = new ClassWOverrideMethod();
+        //            return t.VirtualMethod(i);
+        //        }
+        AddScenario ("CheckCallingOverrideScenario");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "CallingOverrideScenario";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        cmm.Statements.Add (new CodeVariableDeclarationStatement ("ClassWVirtualMethod", "t", new CodeCastExpression(new CodeTypeReference("ClassWVirtualMethod"), new CodeObjectCreateExpression ("ClassWOverrideMethod"))));
+        methodinvoke = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t"), "VirtualMethod");
+        methodinvoke.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+        cmm.Statements.Add (new CodeMethodReturnStatement (methodinvoke));
+        cd.Members.Add (cmm);
+
+        // declare a base class
+        // GENERATES (C#):
+        //    public class ClassWVirtualMethod {
+        //         public virtual int VirtualMethod(int a) {
+        //             return a;
+        //         }
+        //     }
+        cd = new CodeTypeDeclaration ("ClassWVirtualMethod");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "VirtualMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+        cd.Members.Add (cmm);
+
+        // inherit the base class
+        // GENERATES (C#):
+        //    public class ClassWMethod : ClassWVirtualMethod {
+        //    }
+        cd = new CodeTypeDeclaration ("ClassWMethod");
+        cd.BaseTypes.Add (new CodeTypeReference ("ClassWVirtualMethod"));
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        // inheritance the base class with override method
+        // GENERATES (C#):
+        //    public class ClassWOverrideMethod : ClassWVirtualMethod {
+        //         public override int VirtualMethod(int a) {
+        //             return (2 * a);
+        //         }
+        //     }
+        cd = new CodeTypeDeclaration ("ClassWOverrideMethod");
+        cd.BaseTypes.Add (new CodeTypeReference ("ClassWVirtualMethod"));
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "VirtualMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Override;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+            new CodePrimitiveExpression (2), CodeBinaryOperatorType.Multiply
+            , new CodeArgumentReferenceExpression ("a"))));
+        cd.Members.Add (cmm);
+
+
+        if (Supports (provider, GeneratorSupport.DeclareInterfaces)) {
+
+            // ******** implement a single public interface ***********                      
+            // declare an interface
+            // GENERATES (C#):
+            //    public interface InterfaceA {
+            //         int InterfaceMethod(int a);
+            //     }
+            cd = new CodeTypeDeclaration ("InterfaceA");
+            cd.IsInterface = true;
+            nspace.Types.Add (cd);
+            cmm = new CodeMemberMethod ();
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.Name = "InterfaceMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cd.Members.Add (cmm);
+
+            // implement the interface
+            // GENERATES (C#):
+            //    public class TestSingleInterfaceImp : InterfaceA {
+            //         public virtual int InterfaceMethod(int a) {
+            //             return a;
+            //         }
+            //     }
+            cd = new CodeTypeDeclaration ("TestSingleInterfaceImp");
+            cd.BaseTypes.Add (new CodeTypeReference ("System.Object"));
+            cd.BaseTypes.Add (new CodeTypeReference ("InterfaceA"));
+            cd.IsClass = true;
+            nspace.Types.Add (cd);
+            cmm = new CodeMemberMethod ();
+            cmm.ImplementationTypes.Add (new CodeTypeReference ("InterfaceA"));
+            cmm.Name = "InterfaceMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            cd.Members.Add (cmm);
+
+            // ********implement two interfaces with overloading method name*******
+            // declare the second interface
+            // GENERATES (C#):
+            //    public interface InterfaceB {
+            //         int InterfaceMethod(int a);
+            //     }
+            cd = new CodeTypeDeclaration ("InterfaceB");
+            cd.IsInterface = true;
+            nspace.Types.Add (cd);
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "InterfaceMethod";
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cd.Members.Add (cmm);
+
+            // implement both of the interfaces
+            // GENERATES (C#):
+            //    public class TestMultipleInterfaceImp : InterfaceB, InterfaceA {
+            //         public int InterfaceMethod(int a) {
+            //             return a;
+            //         }
+            //     }
+            if (Supports (provider, GeneratorSupport.MultipleInterfaceMembers)) {
+                AddScenario ("CheckTestMultipleInterfaces");
+                cd = new CodeTypeDeclaration ("TestMultipleInterfaceImp");
+                cd.BaseTypes.Add (new CodeTypeReference ("System.Object"));
+                cd.BaseTypes.Add (new CodeTypeReference ("InterfaceB"));
+                cd.BaseTypes.Add (new CodeTypeReference ("InterfaceA"));
+                cd.IsClass = true;
+                nspace.Types.Add (cd);
+                cmm = new CodeMemberMethod ();
+                cmm.ImplementationTypes.Add (new CodeTypeReference ("InterfaceA"));
+                cmm.ImplementationTypes.Add (new CodeTypeReference ("InterfaceB"));
+                cmm.Name = "InterfaceMethod";
+                cmm.ReturnType = new CodeTypeReference (typeof (int));
+                cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+                cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+                cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+                cd.Members.Add (cmm);
+            }
+        }
+
+        if (Supports (provider, GeneratorSupport.NestedTypes)) {
+            // *********** public nested classes *************************
+            // GENERATES (C#):
+            //    public class PublicNestedClassA {
+            //         public class PublicNestedClassB1 {
+            //         }
+            //         public class PublicNestedClassB2 {
+            //             public class PublicNestedClassC {
+            //                 public int publicNestedClassesMethod(int a) {
+            //                     return a;
+            //                 }
+            //             }
+            //         }
+            //    }
+            cd = new CodeTypeDeclaration ("PublicNestedClassA");
+            cd.IsClass = true;
+            nspace.Types.Add (cd);
+            CodeTypeDeclaration nestedClass = new CodeTypeDeclaration ("PublicNestedClassB1");
+            nestedClass.IsClass = true;
+            nestedClass.TypeAttributes = TypeAttributes.NestedPublic;
+            cd.Members.Add (nestedClass);
+            nestedClass = new CodeTypeDeclaration ("PublicNestedClassB2");
+            nestedClass.TypeAttributes = TypeAttributes.NestedPublic;
+            nestedClass.IsClass = true;
+            cd.Members.Add (nestedClass);
+            CodeTypeDeclaration innerNestedClass = new CodeTypeDeclaration ("PublicNestedClassC");
+            innerNestedClass.TypeAttributes = TypeAttributes.NestedPublic;
+            innerNestedClass.IsClass = true;
+            nestedClass.Members.Add (innerNestedClass);
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "publicNestedClassesMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            innerNestedClass.Members.Add (cmm);
+
+            // *********** private nested classes *************************
+            // GENERATES (C#):
+            //    public class PrivateNestedClassA {
+            //         public int TestPrivateNestedClass(int i) {
+            //             return PrivateNestedClassB.PrivateNestedClassesMethod(i);
+            //         }
+            //         private class PrivateNestedClassB {
+            //             public int PrivateNestedClassesMethod(int a) {
+            //                 return a;
+            //             }
+            //         }
+            //     }
+            cd = new CodeTypeDeclaration ("PrivateNestedClassA");
+            cd.IsClass = true;
+            nspace.Types.Add (cd);
+            AddScenario ("CantFindPrivateNestedClass");
+            nestedClass = new CodeTypeDeclaration ("PrivateNestedClassB");
+            nestedClass.IsClass = true;
+            nestedClass.TypeAttributes = TypeAttributes.NestedPrivate;
+            cd.Members.Add (nestedClass);
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "PrivateNestedClassesMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            nestedClass.Members.Add (cmm);
+
+            // test private, nested classes
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "TestPrivateNestedClass";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+            cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference ("PrivateNestedClassB"),
+                        "objB"));
+            cmm.Statements.Add (new CodeAssignStatement (new CodeVariableReferenceExpression ("objB"),
+                        new CodeObjectCreateExpression (new CodeTypeReference ("PrivateNestedClassB"))));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (new
+                CodeVariableReferenceExpression ("objB"), "PrivateNestedClassesMethod", new
+                CodeArgumentReferenceExpression ("i"))));
+            cd.Members.Add (cmm);
+        }
+
+        //     ************ abstract class ***************
+        // GENERATES (C#):
+        //    public abstract class AbstractClass {
+        //         public abstract int AbstractMethod(int i);
+        //     }
+        //    public class InheritAbstractClass : AbstractClass {
+        //
+        //         public override int AbstractMethod(int i) {
+        //             return i;
+        //         }
+        //     }
+        AddScenario ("TestAbstractAttributes");
+        cd = new CodeTypeDeclaration ("AbstractClass");
+        cd.TypeAttributes = TypeAttributes.Abstract | TypeAttributes.Public;
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        CodeTypeDeclaration inheritAbstractClass = new CodeTypeDeclaration ("InheritAbstractClass");
+        inheritAbstractClass.IsClass = true;
+        inheritAbstractClass.BaseTypes.Add (new CodeTypeReference ("AbstractClass"));
+        nspace.Types.Add (inheritAbstractClass);
+
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "AbstractMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Abstract;
+        cd.Members.Add (cmm);
+
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "AbstractMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Override;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("i")));
+        inheritAbstractClass.Members.Add (cmm);
+
+        //  ************  sealed class *****************
+        // GENERATES (C#):
+        //            sealed class SealedClass {
+        //                 public int SealedClassMethod(int i) {
+        //                     return i;
+        //                 }
+        //             }
+        AddScenario ("TestSealedAttributes");
+        cd = new CodeTypeDeclaration ("SealedClass");
+        cd.IsClass = true;
+        cd.TypeAttributes = TypeAttributes.Sealed;
+        nspace.Types.Add (cd);
+
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "SealedClassMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("i")));
+        cd.Members.Add (cmm);
+
+        // *************  class with custom attributes  ********************
+        // GENERATES (C#):
+        //     [System.Obsolete("Don\'t use this Class")]
+        //     [System.Windows.Forms.AxHost.ClsidAttribute("Class.ID")]
+        //     public class ClassWCustomAttributes {
+        //     }
+        cd = new CodeTypeDeclaration ("ClassWCustomAttributes");
+        cd.IsClass = true;
+        AddScenario ("FindObsoleteAttribute");
+        cd.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Class"))));
+        AddScenario ("FindOtherAttribute");
+        cd.CustomAttributes.Add (new CodeAttributeDeclaration (typeof (System.Windows.Forms.AxHost.ClsidAttribute).FullName,
+            new CodeAttributeArgument (new CodePrimitiveExpression ("Class.ID"))));
+        nspace.Types.Add (cd);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateTestingClass", "Find and instantiate TestingClass.");
+        if (!FindAndInstantiate ("NSPC.TestingClass", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTestingClass");
+
+        if (Supports (provider, GeneratorSupport.NestedTypes)) {
+            if (VerifyMethod (genType, genObject, "CallingPrivateNestedScenario", new object[] {7}, 7))
+                VerifyScenario ("CheckCallingPrivateNestedScenario");
+            if (VerifyMethod (genType, genObject, "CallingPublicNestedScenario", new object[] {7}, 7))
+                VerifyScenario ("CheckCallingPublicNestedScenario");
+        }
+        if (Supports (provider, GeneratorSupport.DeclareInterfaces)) {
+            if (VerifyMethod (genType, genObject, "TestSingleInterface", new object[] {7}, 7))
+                VerifyScenario ("CheckTestSingleInterface");
+
+            if (Supports (provider, GeneratorSupport.MultipleInterfaceMembers) &&
+                   VerifyMethod (genType, genObject, "TestMultipleInterfaces", new object[] {7}, 0)) {
+                VerifyScenario ("CheckTestMultipleInterfaces");
+            }
+        }
+        if (VerifyMethod (genType, genObject, "CallingOverrideScenario", new object[] {7}, 14)) {
+            VerifyScenario ("CheckCallingOverrideScenario");
+        }
+        if (VerifyMethod (genType, genObject, "CallingAbstractScenario", new object[] {7}, 7)) {
+            VerifyScenario ("CheckCallingAbstractScenario");
+        }
+
+        // check that can't access private nested class from outside the class 
+        if (Supports (provider, GeneratorSupport.NestedTypes) &&
+                !FindType ("NSPC.PrivateNestedClassA.PrivateNestedClassB", asm, out genType)) {
+            VerifyScenario ("CantFindPrivateNestedClass");
+        }
+
+        // verify abstract attribute on classes  
+        if (FindType ("NSPC.AbstractClass", asm, out genType) &&
+                (genType.Attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract) {
+            VerifyScenario ("TestAbstractAttributes");
+        }
+
+
+        // verify sealed attribute on classes  
+        if (FindType ("NSPC.SealedClass", asm, out genType) /*&&
+                (genType.Attributes & TypeAttributes.Sealed) == TypeAttributes.Sealed*/) {
+            VerifyScenario ("TestSealedAttributes");
+        }
+
+        // verify custom attributes on classes  
+        if (FindType ("NSPC.ClassWCustomAttributes", asm, out genType)) {
+            object[] customAttributes = genType.GetCustomAttributes (typeof (System.ObsoleteAttribute), true);
+            if (customAttributes.GetLength (0) == 1) {
+                VerifyScenario ("FindObsoleteAttribute");
+            }
+
+            customAttributes = genType.GetCustomAttributes (typeof (System.Windows.Forms.AxHost.ClsidAttribute), true);
+            if (customAttributes.GetLength (0) == 1) {
+                VerifyScenario ("FindOtherAttribute");
+            }
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/codeprimitiveexpressiontest.cs b/workyard/tests/codedom/tests/codeprimitiveexpressiontest.cs
new file mode 100755
index 0000000..6300a7e
--- /dev/null
+++ b/workyard/tests/codedom/tests/codeprimitiveexpressiontest.cs
@@ -0,0 +1,95 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class CodePrimitiveExpressionTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return false;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "CodePrimitiveExpressionTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests coding primitive expressions.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+        CodeNamespace ns = new CodeNamespace ();
+        ns.Name = "MyNamespace";
+        cu.Namespaces.Add (ns);
+
+        // GENERATES (C#):
+        //
+        // namespace MyNamespace {
+        //     public class MyClass {
+        //         private void PrimitiveTest() {
+        //             char var1 = 'a';
+        //             char var2 = '\0';
+        //             string var3 = "foo\0bar\0baz\0";
+        //             object var4 = null;
+        //             int var5 = 42;
+        //             double var6 = 3.14;
+        //             System.Console.Write(var1);
+        //             System.Console.Write(var2);
+        //             System.Console.Write(var3);
+        //             System.Console.Write(var4);
+        //             System.Console.Write(var5);
+        //             System.Console.Write(var6);
+        //         }
+        //     }
+        // }
+        
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "MyClass";
+        class1.IsClass = true;
+        class1.Attributes = MemberAttributes.Public;
+        ns.Types.Add (class1);
+
+
+        CodeMemberMethod method = new CodeMemberMethod ();
+        method.Name = "PrimitiveTest";
+        method.Statements.Add (new CodeVariableDeclarationStatement (typeof (char), "var1", new CodePrimitiveExpression ('a')));
+        method.Statements.Add (new CodeVariableDeclarationStatement (typeof (char), "var2", new CodePrimitiveExpression ('\0')));
+        method.Statements.Add (new CodeVariableDeclarationStatement (typeof (string), "var3", new CodePrimitiveExpression ("foo\0bar\0baz\0")));
+        method.Statements.Add (new CodeVariableDeclarationStatement (typeof (Object), "var4", new CodePrimitiveExpression (null)));
+        method.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "var5", new CodePrimitiveExpression (42)));
+        method.Statements.Add (new CodeVariableDeclarationStatement (typeof (double), "var6", new CodePrimitiveExpression (3.14)));
+        method.Statements.Add (new CodeMethodInvokeExpression (new CodeTypeReferenceExpression (typeof (Console)), "Write", new CodeVariableReferenceExpression ("var1")));
+        method.Statements.Add (new CodeMethodInvokeExpression (new CodeTypeReferenceExpression (typeof (Console)), "Write", new CodeVariableReferenceExpression ("var2")));
+        method.Statements.Add (new CodeMethodInvokeExpression (new CodeTypeReferenceExpression (typeof (Console)), "Write", new CodeVariableReferenceExpression ("var3")));
+        method.Statements.Add (new CodeMethodInvokeExpression (new CodeTypeReferenceExpression (typeof (Console)), "Write", new CodeVariableReferenceExpression ("var4")));
+        method.Statements.Add (new CodeMethodInvokeExpression (new CodeTypeReferenceExpression (typeof (Console)), "Write", new CodeVariableReferenceExpression ("var5")));
+        method.Statements.Add (new CodeMethodInvokeExpression (new CodeTypeReferenceExpression (typeof (Console)), "Write", new CodeVariableReferenceExpression ("var6")));
+        class1.Members.Add (method);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/codesnippettest.cs b/workyard/tests/codedom/tests/codesnippettest.cs
new file mode 100755
index 0000000..4a7163c
--- /dev/null
+++ b/workyard/tests/codedom/tests/codesnippettest.cs
@@ -0,0 +1,95 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class CodeSnippetTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return false;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return false;
+        }
+    }
+
+    public override bool ShouldSearch {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "CodeSnippetTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests code snippets.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // GENERATES (C#):
+        //
+        //  namespace NSPC {
+        //      
+        //      public class ClassWithMethod {
+        //          
+        //          public int MethodName() {
+        //              This is a CODE SNIPPET #*$*@;
+        //              return 3;
+        //          }
+        //      }
+        //  }
+        AddScenario ("FindSnippet", "Find code snippet in the code.");
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        cu.Namespaces.Add (nspace);
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ("ClassWithMethod");
+        class1.IsClass = true;
+        nspace.Types.Add (class1);
+
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "MethodName";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Statements.Add (new CodeExpressionStatement (new CodeSnippetExpression ("This is a CODE SNIPPET #*$*@")));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (3)));
+        class1.Members.Add (cmm);
+    }
+
+    public override void Search (CodeDomProvider provider, String output) {
+        int index;
+
+        // find the snippet
+        String str = "This is a CODE SNIPPET #*$*@";
+        index = output.IndexOf (str);
+        if (index >= 0 &&
+                String.Compare (str, 0, output, index, str.Length, false, CultureInfo.InvariantCulture) == 0)
+            VerifyScenario ("FindSnippet");
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        // only search
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/commenttest.cs b/workyard/tests/codedom/tests/commenttest.cs
new file mode 100755
index 0000000..676b160
--- /dev/null
+++ b/workyard/tests/codedom/tests/commenttest.cs
@@ -0,0 +1,288 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class CommentTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "CommentTest";
+        }
+    }
+
+    public override bool ShouldSearch {
+        get {
+            return true;
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests comment statements.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // Namespace to hold test scenarios
+        // GENERATES (C#):
+        //        namespace NSPC {
+        //            using System;
+        //            using System.Drawing;
+        //            using System.Windows.Forms;
+        //            using System.ComponentModel;
+        //            }
+        AddScenario ("FindNamespaceComment");
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        nspace.Comments.Add (new CodeCommentStatement (new CodeComment ("Namespace to hold test scenarios")));
+        nspace.Imports.Add (new CodeNamespaceImport ("System"));
+        nspace.Imports.Add (new CodeNamespaceImport ("System.Drawing"));
+        nspace.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+        nspace.Imports.Add (new CodeNamespaceImport ("System.ComponentModel"));
+        cu.Namespaces.Add (nspace);
+
+        cu.ReferencedAssemblies.Add ("System.Drawing.dll");
+        cu.ReferencedAssemblies.Add ("System.Windows.Forms.dll");
+
+        // GENERATES (C#):    
+        //    // Class has a method to test static constructors
+        //    public class ClassWithMethod {
+        //        // This method is used to test a static constructor
+        //        public static int TestStaticConstructor(int a) {
+        //            // Testing a line comment
+        //            TestClass t = new TestClass();
+        //            t.i = a;
+        //            return t.i;
+        //        }
+        //    }
+        AddScenario ("FindClassComment");
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ("ClassWithMethod");
+        class1.IsClass = true;
+        class1.Comments.Add (new CodeCommentStatement ("Class has a method to test static constructors"));
+        nspace.Types.Add (class1);
+
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "TestStaticConstructor";
+        AddScenario ("FindMethodComment");
+        cmm.Comments.Add (new CodeCommentStatement (new CodeComment ("This method is used to test a static constructor")));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        AddScenario ("FindLineComment");
+        cmm.Statements.Add (new CodeCommentStatement ("Testing a line comment"));
+        CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "a");
+        cmm.Parameters.Add (param);
+        // utilize constructor
+        cmm.Statements.Add (new CodeVariableDeclarationStatement ("TestClass", "t", new CodeObjectCreateExpression ("TestClass")));
+        // set then get number
+        cmm.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeVariableReferenceExpression ("t"), "i")
+            , new CodeArgumentReferenceExpression ("a")));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (new CodeVariableReferenceExpression ("t"), "i")));
+        class1.Members.Add (cmm);
+
+
+        // GENERATES (C#):
+        //    public class TestClass {
+        //        // This field is an integer counter
+        //        private int number;
+        //        static TestClass() {
+        //        }
+        //        // This property allows us to access the integer counter
+        //        // We are able to both get and set the value of the counter
+        //        public int i {
+        //            get {
+        //                return number;
+        //            }
+        //            set {
+        //                number = value;
+        //            }
+        //        }
+        //    }
+        class1 = new CodeTypeDeclaration ();
+        class1.Name = "TestClass";
+        class1.IsClass = true;
+        nspace.Types.Add (class1);
+        AddScenario ("FindFieldComment");
+        CodeMemberField mfield = new CodeMemberField (new CodeTypeReference (typeof (int)), "number");
+        mfield.Comments.Add (new CodeCommentStatement ("This field is an integer counter"));
+        class1.Members.Add (mfield);
+        AddScenario ("FindPropertyComment");
+        CodeMemberProperty prop = new CodeMemberProperty ();
+        prop.Name = "i";
+        prop.Comments.Add (new CodeCommentStatement ("This property allows us to access the integer counter"));
+        prop.Comments.Add (new CodeCommentStatement ("We are able to both get and set the value of the counter"));
+        prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        prop.Type = new CodeTypeReference (typeof (int));
+        prop.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (null, "number")));
+        prop.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "number"),
+            new CodePropertySetValueReferenceExpression ()));
+        class1.Members.Add (prop);
+
+
+        CodeTypeConstructor ctc = new CodeTypeConstructor ();
+        class1.Members.Add (ctc);
+
+        // ************* code a comment on an event *************
+        if (Supports (provider, GeneratorSupport.DeclareEvents)) {
+
+            // GENERATES (C#):
+            //    public class Test : Form {
+            //        private Button b = new Button();
+            //        public Test() {
+            //            this.Size = new Size(600, 600);
+            //            b.Text = "Test";
+            //            b.TabIndex = 0;
+            //            b.Location = new Point(400, 525);
+            //            this.MyEvent += new EventHandler(this.b_Click);
+            //        }
+            //        // This is a comment on an event
+            //        public event System.EventHandler MyEvent;
+            //        private void b_Click(object sender, System.EventArgs e) {
+            //        }
+            //    }
+            class1 = new CodeTypeDeclaration ("Test");
+            class1.IsClass = true;
+            class1.BaseTypes.Add (new CodeTypeReference ("Form"));
+            nspace.Types.Add (class1);
+
+            mfield = new CodeMemberField (new CodeTypeReference ("Button"), "b");
+            mfield.InitExpression = new CodeObjectCreateExpression (new CodeTypeReference ("Button"));
+            class1.Members.Add (mfield);
+
+            CodeConstructor ctor = new CodeConstructor ();
+            ctor.Attributes = MemberAttributes.Public;
+            ctor.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (),
+                "Size"), new CodeObjectCreateExpression (new CodeTypeReference ("Size"),
+                new CodePrimitiveExpression (600), new CodePrimitiveExpression (600))));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Text"), new CodePrimitiveExpression ("Test")));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "TabIndex"), new CodePrimitiveExpression (0)));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Location"), new CodeObjectCreateExpression (new CodeTypeReference ("Point"),
+                new CodePrimitiveExpression (400), new CodePrimitiveExpression (525))));
+            ctor.Statements.Add (new CodeAttachEventStatement (new CodeEventReferenceExpression (new
+                CodeThisReferenceExpression (), "MyEvent"), new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler")
+                , new CodeThisReferenceExpression (), "b_Click")));
+            class1.Members.Add (ctor);
+
+            AddScenario ("FindEventComment");
+            CodeMemberEvent evt = new CodeMemberEvent ();
+            evt.Name = "MyEvent";
+            evt.Type = new CodeTypeReference ("System.EventHandler");
+            evt.Attributes = MemberAttributes.Public;
+            evt.Comments.Add (new CodeCommentStatement ("This is a comment on an event"));
+            class1.Members.Add (evt);
+
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "b_Click";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (object), "sender"));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (EventArgs), "e"));
+            class1.Members.Add (cmm);
+        }
+
+        if (Supports (provider, GeneratorSupport.DeclareDelegates)) {
+            // GENERATES (C#):
+            //
+            // // This is a delegate comment
+            // public delegate void Delegate();
+
+            AddScenario ("FindDelegateComment");
+            CodeTypeDelegate del = new CodeTypeDelegate ("Delegate");
+            del.Comments.Add (new CodeCommentStatement ("This is a delegate comment"));
+            nspace.Types.Add (del);
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly ass) {
+    }
+
+    public override void Search (CodeDomProvider provider, String output) {
+        int index;
+
+        // check the comment on the line
+        String str = "Testing a line comment";
+        index = output.IndexOf (str);
+        if (String.Compare (str, 0, output, index, str.Length, false, CultureInfo.InvariantCulture) == 0) {
+           VerifyScenario ("FindLineComment");
+        }
+        // check comment on method
+        str = "This method is used to test a static constructor";
+        index = output.IndexOf (str);
+        if (String.Compare (str, 0, output, index, str.Length, false, CultureInfo.InvariantCulture) == 0) {
+           VerifyScenario ("FindMethodComment");
+        }
+
+        // check comment on class
+        str = "Class has a method to test static constructors";
+        index = output.IndexOf (str);
+        if (String.Compare (str, 0, output, index, str.Length, false, CultureInfo.InvariantCulture) == 0) {
+           VerifyScenario ("FindClassComment");
+        }
+
+        // check comment on namespace
+        str = "Namespace to hold test scenarios";
+        index = output.IndexOf (str);
+        if (String.Compare (str, 0, output, index, str.Length, false, CultureInfo.InvariantCulture) == 0) {
+           VerifyScenario ("FindNamespaceComment");
+        }
+
+        // check comment on field
+        str = "This field is an integer counter";
+        index = output.IndexOf (str);
+        if (String.Compare (str, 0, output, index, str.Length, false, CultureInfo.InvariantCulture) == 0) {
+           VerifyScenario ("FindFieldComment");
+        }
+
+        // check comment on property    
+        str = "This property allows us to access the integer counter";
+        index = output.IndexOf (str);
+        if (String.Compare (str, 0, output, index, str.Length, false, CultureInfo.InvariantCulture) == 0) {
+            str = "We are able to both get and set the value of the counter";
+            index = output.IndexOf (str);
+            if (String.Compare (str, 0, output, index, str.Length, false, CultureInfo.InvariantCulture) == 0)
+                VerifyScenario ("FindPropertyComment");
+        }
+
+        // check comment on events
+        if (Supports (provider, GeneratorSupport.DeclareEvents)) {
+            str = "This is a comment on an event";
+            index = output.IndexOf (str);
+            if (String.Compare (str, 0, output, index, str.Length, false, CultureInfo.InvariantCulture) == 0)
+                VerifyScenario ("FindEventComment");
+        }
+
+        // check comment on delegates
+        if (Supports (provider, GeneratorSupport.DeclareDelegates)) {
+            str = "This is a delegate comment";
+            index = output.IndexOf (str);
+            if (String.Compare (str, 0, output, index, str.Length, false, CultureInfo.InvariantCulture) == 0)
+                VerifyScenario ("FindDelegateComment");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/conditionalstatementtest.cs b/workyard/tests/codedom/tests/conditionalstatementtest.cs
new file mode 100755
index 0000000..a4d5e25
--- /dev/null
+++ b/workyard/tests/codedom/tests/conditionalstatementtest.cs
@@ -0,0 +1,122 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class ConditionalStatementTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "ConditionalStatementTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests conditional statements.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // GENERATES (C#):
+        //
+        //  namespace NSPC {
+        //
+        //      public class ClassWithMethod {
+        //          
+        //          public static int ReturnMethod(int intInput) {
+        //              if (((intInput <= 3) 
+        //                          && (intInput == 2))) {
+        //                  intInput = (intInput + 16);
+        //              }
+        //              else {
+        //                  intInput = (intInput + 1);
+        //              }
+        //              if ((intInput <= 10)) {
+        //                  intInput = (intInput + 11);
+        //              }
+        //              return intInput;
+        //          }
+        //      }
+        //  }
+
+        AddScenario ("CheckReturnMethod1", "Check return value of ReturnMethod()");
+        AddScenario ("CheckReturnMethod2", "Check return value of ReturnMethod()");
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        cu.Namespaces.Add (nspace);
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ("ClassWithMethod");
+        class1.IsClass = true;
+        nspace.Types.Add (class1);
+
+        CodeMemberMethod retMethod = new CodeMemberMethod ();
+        retMethod.Name = "ReturnMethod";
+        retMethod.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+        retMethod.ReturnType = new CodeTypeReference (typeof (int));
+        retMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "intInput"));
+        retMethod.Statements.Add (
+            new CodeConditionStatement (
+            new CodeBinaryOperatorExpression (
+            new CodeBinaryOperatorExpression (
+            new CodeArgumentReferenceExpression ("intInput"),
+            CodeBinaryOperatorType.LessThanOrEqual,
+            new CodePrimitiveExpression (3)),
+            CodeBinaryOperatorType.BooleanAnd,
+            new CodeBinaryOperatorExpression (
+            new CodeArgumentReferenceExpression ("intInput"),
+            CodeBinaryOperatorType.ValueEquality,
+            new CodePrimitiveExpression (2))),
+            CDHelper.CreateIncrementByStatement (new CodeArgumentReferenceExpression ("intInput"), 16),
+            CDHelper.CreateIncrementByStatement (new CodeArgumentReferenceExpression ("intInput"), 1)));
+        retMethod.Statements.Add (new CodeConditionStatement (
+            new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("intInput"), CodeBinaryOperatorType.LessThanOrEqual,
+            new CodePrimitiveExpression (10)),
+            new CodeAssignStatement (new CodeArgumentReferenceExpression ("intInput"),
+            new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("intInput"),
+            CodeBinaryOperatorType.Add, new CodePrimitiveExpression (11)))));
+        retMethod.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("intInput")));
+        class1.Members.Add (retMethod);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+        
+        AddScenario ("InstantiateClassWithMethod", "Find and instantiate ClassWithMethod.");
+        if (!FindAndInstantiate ("NSPC.ClassWithMethod", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClassWithMethod");
+
+        // Verify Return value from function
+        if (VerifyMethod (genType, genObject, "ReturnMethod", new object[] {2}, 19)) {
+            VerifyScenario ("CheckReturnMethod1");
+        }
+        if (VerifyMethod (genType, genObject, "ReturnMethod", new object[] {1}, 12)) {
+            VerifyScenario ("CheckReturnMethod2");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/constructortest.cs b/workyard/tests/codedom/tests/constructortest.cs
new file mode 100755
index 0000000..c2f06cd
--- /dev/null
+++ b/workyard/tests/codedom/tests/constructortest.cs
@@ -0,0 +1,399 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.VisualBasic;
+using Microsoft.JScript;
+
+public class ConstructorTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "ConstructorTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests constructors.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // create a namespace
+        CodeNamespace ns = new CodeNamespace ("NS");
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (ns);
+
+        // create a class that will be used to test the constructors of other classes
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "Test";
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        CodeMemberMethod cmm;
+
+        // construct a method to test class with chained public constructors
+        // GENERATES (C#):
+        //        public static string TestingMethod1() {
+        //                Test2 t = new Test2();
+        //                return t.accessStringField;
+        //            }
+        if (Supports (provider, GeneratorSupport.ChainedConstructorArguments)) {
+            AddScenario ("CheckTestingMethod01");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "TestingMethod1";
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.ReturnType = new CodeTypeReference (typeof (String));
+            // utilize constructor
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("Test2", "t", new CodeObjectCreateExpression ("Test2")));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (
+                new CodeVariableReferenceExpression ("t"), "accessStringField")));
+            class1.Members.Add (cmm);
+        }
+
+        // construct a method to test class with base public constructor
+        // GENERATES (C#):
+        //        public static string TestingMethod2() {
+        //                Test3 t = new Test3();
+        //                return t.accessStringField;
+        //            }
+        AddScenario ("CheckTestingMethod02");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "TestingMethod2";
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.ReturnType = new CodeTypeReference (typeof (String));
+        // utilize constructor
+        cmm.Statements.Add (new CodeVariableDeclarationStatement ("Test3", "t", new CodeObjectCreateExpression ("Test3")));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (
+            new CodeVariableReferenceExpression ("t"), "accessStringField")));
+
+        class1.Members.Add (cmm);
+        // construct a method to test class with internal constructor
+        // GENERATES (C#):
+        //        public static int TestInternalConstruct(int a) {
+        //                ClassWInternalConstruct t = new ClassWInternalConstruct();
+        //                t.i = a;
+        //                return t.i;
+        //            }
+
+        CodeParameterDeclarationExpression param = null;
+
+#if !WHIDBEY
+        // Everett VB compiler doesn't like this construct
+        if (!(provider is VBCodeProvider)) {
+#endif
+            AddScenario ("CheckTestInternalConstruct");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "TestInternalConstruct";
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            param = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (param);
+            // utilize constructor
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("ClassWInternalConstruct", "t", new CodeObjectCreateExpression ("ClassWInternalConstruct")));
+            // set then get number
+            cmm.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeVariableReferenceExpression ("t"), "i")
+                , new CodeArgumentReferenceExpression ("a")));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (
+                new CodeVariableReferenceExpression ("t"), "i")));
+            class1.Members.Add (cmm);
+#if !WHIDBEY
+        }
+#endif
+
+
+
+        // construct a method to test class with static constructor
+        // GENERATES (C#):
+        //        public static int TestStaticConstructor(int a) {
+        //                Test4 t = new Test4();
+        //                t.i = a;
+        //                return t.i;
+        //            }
+        if (Supports (provider, GeneratorSupport.StaticConstructors)) {
+            AddScenario ("CheckTestStaticConstructor");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "TestStaticConstructor";
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            param = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (param);
+            // utilize constructor
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("Test4", "t", new CodeObjectCreateExpression ("Test4")));
+            // set then get number
+            cmm.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeVariableReferenceExpression ("t"), "i")
+                , new CodeArgumentReferenceExpression ("a")));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (
+                new CodeVariableReferenceExpression ("t"), "i")));
+            class1.Members.Add (cmm);
+        }
+
+
+        //  *** second class, tests chained, public constructors ***
+        // GENERATES (C#):
+        //        public class Test2 { 
+        //            private string stringField;
+        //            public Test2() : 
+        //                    this("testingString", null, null) {
+        //            }
+        //            public Test2(String p1, String p2, String p3) {
+        //                this.stringField = p1;
+        //            }
+        //            public string accessStringField {
+        //                get {
+        //                    return this.stringField;
+        //                }
+        //                set {
+        //                    this.stringField = value;
+        //                }
+        //            }
+        //        } 
+        class1 = new CodeTypeDeclaration ();
+        class1.Name = "Test2";
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        class1.Members.Add (new CodeMemberField (new CodeTypeReference (typeof (String)), "stringField"));
+        CodeMemberProperty prop = new CodeMemberProperty ();
+        prop.Name = "accessStringField";
+        prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        prop.Type = new CodeTypeReference (typeof (String));
+        prop.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (),
+            "stringField")));
+        prop.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new
+            CodeThisReferenceExpression (), "stringField"),
+            new CodePropertySetValueReferenceExpression ()));
+        class1.Members.Add (prop);
+
+        CodeConstructor cctor;
+        if (Supports (provider, GeneratorSupport.ChainedConstructorArguments)) {
+            cctor = new CodeConstructor ();
+            cctor.Attributes = MemberAttributes.Public;
+            cctor.ChainedConstructorArgs.Add (new CodePrimitiveExpression ("testingString"));
+            cctor.ChainedConstructorArgs.Add (new CodePrimitiveExpression (null));
+            cctor.ChainedConstructorArgs.Add (new CodePrimitiveExpression (null));
+            class1.Members.Add (cctor);
+        }
+
+        CodeConstructor cc = new CodeConstructor ();
+        cc.Attributes = MemberAttributes.Public | MemberAttributes.Overloaded;
+        cc.Parameters.Add (new CodeParameterDeclarationExpression ("String", "p1"));
+        cc.Parameters.Add (new CodeParameterDeclarationExpression ("String", "p2"));
+        cc.Parameters.Add (new CodeParameterDeclarationExpression ("String", "p3"));
+        cc.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression ()
+            , "stringField"), new CodeArgumentReferenceExpression ("p1")));
+        class1.Members.Add (cc);
+
+
+        // **** third class tests base constructors ****
+        // GENERATES (C#):
+        //    public class Test3 : Test2 {
+        //            public Test3() : 
+        //                    base("testingString", null, null) {
+        //            }
+        //        }
+        class1 = new CodeTypeDeclaration ();
+        class1.Name = "Test3";
+        class1.IsClass = true;
+        class1.BaseTypes.Add (new CodeTypeReference ("Test2"));
+        ns.Types.Add (class1);
+
+        cctor = new CodeConstructor ();
+        cctor.Attributes = MemberAttributes.Public;
+        cctor.BaseConstructorArgs.Add (new CodePrimitiveExpression ("testingString"));
+        cctor.BaseConstructorArgs.Add (new CodePrimitiveExpression (null));
+        cctor.BaseConstructorArgs.Add (new CodePrimitiveExpression (null));
+        class1.Members.Add (cctor);
+
+
+        if (Supports (provider, GeneratorSupport.StaticConstructors)) {
+            // *** fourth class tests static constructors ****
+            // GENERATES (C#):
+            //    public class Test4 {
+            //            private int number;
+            //            static Test4() {
+            //            }
+            //            public int i {
+            //                get {
+            //                    return number;
+            //                }
+            //                set {
+            //                    number = value;
+            //                }
+            //            }
+            //        }
+            class1 = new CodeTypeDeclaration ();
+            class1.Name = "Test4";
+            class1.IsClass = true;
+            ns.Types.Add (class1);
+
+            class1.Members.Add (new CodeMemberField (new CodeTypeReference (typeof (int)), "number"));
+            prop = new CodeMemberProperty ();
+            prop.Name = "i";
+            prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            prop.Type = new CodeTypeReference (typeof (int));
+            prop.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (null, "number")));
+            prop.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "number"),
+                new CodePropertySetValueReferenceExpression ()));
+            class1.Members.Add (prop);
+
+
+            CodeTypeConstructor ctc = new CodeTypeConstructor ();
+            class1.Members.Add (ctc);
+        }
+
+        // *******  class tests internal constructors **********
+        // GENERATES (C#):
+        //    public class ClassWInternalConstruct {
+        //            private int number;
+        //            /*FamANDAssem*/ internal ClassWInternalConstruct() {
+        //            }
+        //            public int i {
+        //                get {
+        //                    return number;
+        //                }
+        //                set {
+        //                    number = value;
+        //                }
+        //            }
+        //        }
+        class1 = new CodeTypeDeclaration ();
+        class1.Name = "ClassWInternalConstruct";
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        class1.Members.Add (new CodeMemberField (new CodeTypeReference (typeof (int)), "number"));
+        prop = new CodeMemberProperty ();
+        prop.Name = "i";
+        prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        prop.Type = new CodeTypeReference (typeof (int));
+        prop.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (null, "number")));
+        prop.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "number"),
+            new CodePropertySetValueReferenceExpression ()));
+        class1.Members.Add (prop);
+
+        if (!(provider is JScriptCodeProvider)) {
+            cctor = new CodeConstructor ();
+            cctor.Attributes = MemberAttributes.FamilyOrAssembly;
+            class1.Members.Add (cctor);
+        }
+
+        // ******** class tests private constructors **********
+        // GENERATES (C#):
+        //    public class ClassWPrivateConstruct {
+        //            static int number;
+        //            private ClassWPrivateConstruct() {
+        //            }
+        //        }
+        class1 = new CodeTypeDeclaration ();
+        class1.Name = "ClassWPrivateConstruct";
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        cctor = new CodeConstructor ();
+        cctor.Attributes = MemberAttributes.Private;
+        class1.Members.Add (cctor);
+
+
+        // ******* class tests protected constructors **************
+        // GENERATES (C#):
+        //    public class ClassWProtectedConstruct {
+        //            protected ClassWProtectedConstruct() {
+        //            }
+        //        }
+        class1 = new CodeTypeDeclaration ();
+        class1.Name = "ClassWProtectedConstruct";
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        cctor = new CodeConstructor ();
+        cctor.Attributes = MemberAttributes.Family;
+        class1.Members.Add (cctor);
+
+        // class that inherits protected constructor
+        // GENERATES (C#):
+        //    public class InheritsProtectedConstruct : ClassWProtectedConstruct {
+        //    }
+        class1 = new CodeTypeDeclaration ();
+        class1.Name = "InheritsProtectedConstruct";
+        class1.IsClass = true;
+        class1.BaseTypes.Add (new CodeTypeReference ("ClassWProtectedConstruct"));
+        ns.Types.Add (class1);
+
+
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateTest", "Find and instantiate Test.");
+        if (!FindAndInstantiate ("NS.Test", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTest");
+
+        if (Supports (provider, GeneratorSupport.ChainedConstructorArguments) &&
+                VerifyMethod (genType, genObject, "TestingMethod1", new object[] {}, "testingString")) {
+            VerifyScenario ("CheckTestingMethod01");
+        }
+
+        if (VerifyMethod (genType, genObject, "TestingMethod2", new object[] {}, "testingString")) {
+            VerifyScenario ("CheckTestingMethod02");
+        }
+
+        if (Supports (provider, GeneratorSupport.StaticConstructors)) {
+            if (VerifyMethod (genType, genObject, "TestStaticConstructor", new object[] {7}, 7)) {
+                VerifyScenario ("CheckTestStaticConstructor");
+            }
+        }
+
+#if !WHIDBEY
+        if (!(provider is VBCodeProvider)) {
+#endif
+            if (VerifyMethod (genType, genObject, "TestInternalConstruct", new object[] {7}, 7)) {
+               VerifyScenario ("CheckTestInternalConstruct");
+            }
+#if !WHIDBEY
+        }
+#endif
+
+        if (FindType ("ClassWPrivateConstruct", asm, out genType)) {
+            // should be empty
+            if (genType.GetConstructors ().Length <= 0)
+                VerifyScenario ("ClassWPrivateConstruct");
+        }
+
+        if (FindType ("ClassWProtectedConstruct", asm, out genType)) {
+            // should be empty
+            if (genType.GetConstructors ().Length <= 0)
+                VerifyScenario ("ClassWProtectedConstruct");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/createobjecttest.cs b/workyard/tests/codedom/tests/createobjecttest.cs
new file mode 100755
index 0000000..e40e375
--- /dev/null
+++ b/workyard/tests/codedom/tests/createobjecttest.cs
@@ -0,0 +1,156 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class CreateObjectTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "CreateObjectTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests object creation.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+        // GENERATES (C#):
+        //
+        //  namespace NSPC {
+        //      
+        //      public class ClassWithMethod {
+        //          
+        //          public int Method() {
+        //              return 4;
+        //          }
+        //      }
+        //      
+        //      public class ClassToTest {
+        //          
+        //          public int TestMethod() {
+        //              ClassWithMethod tmp = new ClassWithMethod(2);
+        //              ClassWithMethod temp = new ClassWithMethod();
+        //              return temp.Method();
+        //          }
+        //          
+        //          public int SecondTestMethod() {
+        //              int a = 3;
+        //              int b;
+        //              b = 87;
+        //              return (b - a);
+        //          }
+        //      }
+        //  }
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        cu.Namespaces.Add (nspace);
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ("ClassWithMethod");
+        class1.IsClass = true;
+        nspace.Types.Add (class1);
+
+        // parameterless constructor
+        CodeConstructor cons = new CodeConstructor ();
+        cons.Attributes = MemberAttributes.Public;
+        class1.Members.Add (cons);
+
+        // parameterful constructor
+        cons = new CodeConstructor ();
+        cons.Attributes = MemberAttributes.Public;
+        cons.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "myParameter"));
+        cons.Statements.Add (new CodeVariableDeclarationStatement (
+                    typeof (int), "noUse",
+                    new CodeArgumentReferenceExpression ("myParameter")));
+        class1.Members.Add (cons);
+
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "Method";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (4)));
+        class1.Members.Add (cmm);
+
+        class1 = new CodeTypeDeclaration ("ClassToTest");
+        class1.IsClass = true;
+        nspace.Types.Add (class1);
+
+        AddScenario ("CheckTestMethod", "Check the return value of TestMethod.");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "TestMethod";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+
+        // create a new class with the parameter
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference ("ClassWithMethod"),
+            "tmp", new CodeObjectCreateExpression (new CodeTypeReference ("ClassWithMethod"),
+                new CodePrimitiveExpression (2))));
+
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference ("ClassWithMethod"),
+            "temp", new CodeObjectCreateExpression (new CodeTypeReference ("ClassWithMethod"))));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (
+            new CodeVariableReferenceExpression ("temp"), "Method")));
+        class1.Members.Add (cmm);
+
+        AddScenario ("CheckSecondTestMethod", "Check the return value of SecondTestMethod.");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "SecondTestMethod";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int)), "a", new CodePrimitiveExpression (3)));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int)), "b"));
+        cmm.Statements.Add (new CodeAssignStatement (new CodeVariableReferenceExpression ("b"), new CodePrimitiveExpression (87)));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new
+            CodeVariableReferenceExpression ("b"), CodeBinaryOperatorType.Subtract,
+            new CodeVariableReferenceExpression ("a"))));
+        class1.Members.Add (cmm);
+
+
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateClassToTest", "Find and instantiate ClassToTest.");
+        if (!FindAndInstantiate ("NSPC.ClassToTest", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClassToTest");
+
+        // verify method which has declaration of a non-primitive type
+        if (VerifyMethod (genType, genObject, "TestMethod", new object[] {}, 4)) {
+            VerifyScenario ("CheckTestMethod");
+        }
+        if (VerifyMethod (genType, genObject, "SecondTestMethod", new object[] {}, 84)) {
+            VerifyScenario ("CheckSecondTestMethod");
+        }
+    }
+
+}
+
diff --git a/workyard/tests/codedom/tests/declarefield.cs b/workyard/tests/codedom/tests/declarefield.cs
new file mode 100755
index 0000000..b3421cf
--- /dev/null
+++ b/workyard/tests/codedom/tests/declarefield.cs
@@ -0,0 +1,339 @@
+// F#: * We never generate a real field, so all the tests are modified to check for the right property 
+//     * Fixed missing codetypereference in access to static fields
+//     * Also accessing protected static fields without "CodeTypeReference" is not correct in F#
+//     * Reorganized class order 
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.VisualBasic;
+using Microsoft.JScript;
+
+public class DeclareField : CodeDomTestTree {
+
+    public override string Comment
+    {
+        get { return "public static fields not allowed in F#"; }
+    }		
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "DeclareField";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests declarations of fields.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        CodeNamespace nspace = new CodeNamespace("NSPC");
+        nspace.Imports.Add(new CodeNamespaceImport("System"));
+        cu.Namespaces.Add(nspace);
+
+        CodeTypeDeclaration cd = new CodeTypeDeclaration("TestFields");
+        cd.IsClass = true;
+        nspace.Types.Add(cd);
+
+        // GENERATES (C#):
+        //        public static int UseStaticPublicField(int i) {
+        //            ClassWithFields.StaticPublicField = i;
+        //            return ClassWithFields.StaticPublicField;
+        //
+        CodeMemberMethod cmm;
+        if (Supports(provider, GeneratorSupport.PublicStaticMembers))
+        {
+          AddScenario("CheckUseStaticPublicField");
+          cmm = new CodeMemberMethod();
+          cmm.Name = "UseStaticPublicField";
+          cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+          cmm.ReturnType = new CodeTypeReference(typeof(int));
+          cmm.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "i"));
+          cmm.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(
+              new CodeTypeReferenceExpression("ClassWithFields"), "StaticPublicField"),
+              new CodeArgumentReferenceExpression("i")));
+          cmm.Statements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new
+              CodeTypeReferenceExpression("ClassWithFields"), "StaticPublicField")));
+          cd.Members.Add(cmm);
+        }
+
+        // GENERATES (C#):
+        //        public static int UseNonStaticPublicField(int i) {
+        //            ClassWithFields variable = new ClassWithFields();
+        //            variable.NonStaticPublicField = i;
+        //            return variable.NonStaticPublicField;
+        //        }
+        AddScenario("CheckUseNonStaticPublicField");
+        cmm = new CodeMemberMethod();
+        cmm.Name = "UseNonStaticPublicField";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+        cmm.ReturnType = new CodeTypeReference(typeof(int));
+        cmm.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "i"));
+        cmm.Statements.Add(new CodeVariableDeclarationStatement("ClassWithFields", "variable", new CodeObjectCreateExpression("ClassWithFields")));
+        cmm.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(
+            new CodeVariableReferenceExpression("variable"), "NonStaticPublicField"),
+            new CodeArgumentReferenceExpression("i")));
+        cmm.Statements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new
+            CodeVariableReferenceExpression("variable"), "NonStaticPublicField")));
+        cd.Members.Add(cmm);
+
+        // GENERATES (C#):
+        //        public static int UseNonStaticInternalField(int i) {
+        //            ClassWithFields variable = new ClassWithFields();
+        //            variable.NonStaticInternalField = i;
+        //            return variable.NonStaticInternalField;
+        //        }          
+
+        if (!(provider is JScriptCodeProvider) && !(provider is VBCodeProvider))
+        {
+          cmm = new CodeMemberMethod();
+          AddScenario("CheckUseNonStaticInternalField");
+          cmm.Name = "UseNonStaticInternalField";
+          cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+          cmm.ReturnType = new CodeTypeReference(typeof(int));
+          cmm.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "i"));
+          cmm.Statements.Add(new CodeVariableDeclarationStatement("ClassWithFields", "variable", new CodeObjectCreateExpression("ClassWithFields")));
+          cmm.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(
+              new CodeVariableReferenceExpression("variable"), "NonStaticInternalField"),
+              new CodeArgumentReferenceExpression("i")));
+          cmm.Statements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new
+              CodeVariableReferenceExpression("variable"), "NonStaticInternalField")));
+          cd.Members.Add(cmm);
+        }
+
+        // GENERATES (C#):
+        //        public static int UseInternalField(int i) {
+        //            ClassWithFields.InternalField = i;
+        //            return ClassWithFields.InternalField;
+        //        }
+        if (!(provider is JScriptCodeProvider) && !(provider is VBCodeProvider))
+        {
+          AddScenario("CheckUseInternalField");
+          cmm = new CodeMemberMethod();
+          cmm.Name = "UseInternalField";
+          cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+          cmm.ReturnType = new CodeTypeReference(typeof(int));
+          cmm.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "i"));
+          cmm.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new
+              CodeTypeReferenceExpression("ClassWithFields"), "InternalField"),
+              new CodeArgumentReferenceExpression("i")));
+          cmm.Statements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new
+              CodeTypeReferenceExpression("ClassWithFields"), "InternalField")));
+          cd.Members.Add(cmm);
+        }
+
+        // GENERATES (C#):
+        //       public static int UseConstantField(int i) {
+        //            return ClassWithFields.ConstantField;
+        //        }
+        AddScenario("CheckUseConstantField");
+        cmm = new CodeMemberMethod();
+        cmm.Name = "UseConstantField";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+        cmm.ReturnType = new CodeTypeReference(typeof(int));
+        cmm.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "i"));
+        cmm.Statements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new
+            CodeTypeReferenceExpression("ClassWithFields"), "ConstantField")));
+        cd.Members.Add(cmm);
+
+        // code a new class to test that the protected field can be accessed by classes that inherit it
+        // GENERATES (C#):
+        //    public class TestProtectedField : ClassWithFields {
+        //        public static int UseProtectedField(int i) {
+        //            ProtectedField = i;
+        //            return ProtectedField;
+        //        }
+        //    }
+        cd = new CodeTypeDeclaration("TestProtectedField");
+        cd.BaseTypes.Add(new CodeTypeReference("ClassWithFields"));
+        cd.IsClass = true;
+        nspace.Types.Add(cd);
+
+        cmm = new CodeMemberMethod();
+        AddScenario("CheckUseProtectedField");
+        cmm.Name = "UseProtectedField";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+        cmm.ReturnType = new CodeTypeReference(typeof(int));
+        cmm.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "i"));
+        CodeFieldReferenceExpression reference = new CodeFieldReferenceExpression();
+        reference.FieldName = "ProtectedField";
+        reference.TargetObject = new CodeTypeReferenceExpression("ClassWithFields");
+        cmm.Statements.Add(new CodeAssignStatement(reference,
+            new CodeArgumentReferenceExpression("i")));
+        cmm.Statements.Add(new CodeMethodReturnStatement(reference));
+        cd.Members.Add(cmm);
+
+
+        // declare class with fields
+        //  GENERATES (C#):
+        //            public class ClassWithFields {
+        //                public static int StaticPublicField = 5;
+        //                /*FamANDAssem*/ internal static int InternalField = 0;
+        //                public const int ConstantField = 0;
+        //                protected static int ProtectedField = 0;
+        //                private static int PrivateField = 5;
+        //                public int NonStaticPublicField = 5;
+        //                /*FamANDAssem*/ internal int NonStaticInternalField = 0;
+        //                public static int UsePrivateField(int i) {
+        //                    PrivateField = i;
+        //                    return PrivateField;
+        //                }
+        //            }
+        cd = new CodeTypeDeclaration ("ClassWithFields");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        CodeMemberField field;
+        if (Supports (provider, GeneratorSupport.PublicStaticMembers)) {
+            field = new CodeMemberField ();
+            field.Name = "StaticPublicField";
+            field.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            field.Type = new CodeTypeReference (typeof (int));
+            field.InitExpression = new CodePrimitiveExpression (5);
+            cd.Members.Add (field);
+        }
+
+        if (!(provider is JScriptCodeProvider) && !(provider is VBCodeProvider)) {
+            field = new CodeMemberField ();
+            field.Name = "InternalField";
+            field.Attributes = MemberAttributes.FamilyOrAssembly | MemberAttributes.Static;
+            field.Type = new CodeTypeReference (typeof (int));
+            field.InitExpression = new CodePrimitiveExpression (0);
+            cd.Members.Add (field);
+        }
+
+        field = new CodeMemberField ();
+        field.Name = "ConstantField";
+        field.Attributes = MemberAttributes.Public | MemberAttributes.Const;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (0);
+        cd.Members.Add (field);
+
+        field = new CodeMemberField ();
+        field.Name = "ProtectedField";
+        field.Attributes = MemberAttributes.Family | MemberAttributes.Static;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (0);
+        cd.Members.Add (field);
+
+        field = new CodeMemberField ();
+        field.Name = "PrivateField";
+        field.Attributes = MemberAttributes.Private | MemberAttributes.Static;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (5);
+        cd.Members.Add (field);
+
+        field = new CodeMemberField ();
+        field.Name = "NonStaticPublicField";
+        field.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (5);
+        cd.Members.Add (field);
+
+        if (!(provider is JScriptCodeProvider) && !(provider is VBCodeProvider)) {
+            field = new CodeMemberField ();
+            field.Name = "NonStaticInternalField";
+            field.Attributes = MemberAttributes.FamilyOrAssembly | MemberAttributes.Final;
+            field.Type = new CodeTypeReference (typeof (int));
+            field.InitExpression = new CodePrimitiveExpression (0);
+            cd.Members.Add (field);
+        }
+
+        // create a method to test access to private field
+        AddScenario ("CheckUsePrivateField");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "UsePrivateField";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+        CodeFieldReferenceExpression fieldref = new CodeFieldReferenceExpression ();
+        fieldref.TargetObject = new CodeTypeReferenceExpression("ClassWithFields");
+        fieldref.FieldName = "PrivateField";
+        cmm.Statements.Add (new CodeAssignStatement (fieldref, new CodeArgumentReferenceExpression ("i")));
+        cmm.Statements.Add (new CodeMethodReturnStatement (fieldref));
+        cd.Members.Add (cmm);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateTestFields", "Find and instantiate TestFields.");
+        if (!FindAndInstantiate ("NSPC.TestFields", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTestFields");
+
+        if (VerifyMethod (genType, genObject, "UsePrivateField", new object[] {6}, 6)) {
+            VerifyScenario ("CheckUsePrivateField");
+        }
+        if (VerifyMethod (genType, genObject, "UseConstantField", new object[] {6}, 0)) {
+            VerifyScenario ("CheckUseConstantField");
+        }
+        if (VerifyMethod (genType, genObject, "UseNonStaticPublicField", new object[] {6}, 6)) {
+            VerifyScenario ("CheckUseNonStaticPublicField");
+        }
+
+        if (!(provider is JScriptCodeProvider) && !(provider is VBCodeProvider)) {
+            if (VerifyMethod (genType, genObject, "UseNonStaticInternalField", new object[] { 6 }, 6)) {
+                VerifyScenario ("CheckUseNonStaticInternalField");
+            }
+        }
+
+        if (!(provider is JScriptCodeProvider) && !(provider is VBCodeProvider)) {
+            if (VerifyMethod (genType, genObject, "UseInternalField", new object[] { 6 }, 6)) {
+                VerifyScenario ("CheckUseInternalField");
+            }
+        }
+
+        if (Supports (provider, GeneratorSupport.PublicStaticMembers) && VerifyMethod (genType, genObject, "UseStaticPublicField",
+                    new object [] { 6 }, 6)) {
+            VerifyScenario ("CheckUseStaticPublicField");
+        }
+
+        AddScenario ("InstantiateTestProtectedField", "Find and instantiate TestProtectedFields.");
+        if (!FindAndInstantiate ("NSPC.TestProtectedField", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTestProtectedField");
+
+        if (VerifyMethod (genType, genObject, "UseProtectedField", new object[] {6}, 6)) {
+            VerifyScenario ("CheckUseProtectedField");
+        }
+
+        AddScenario ("InstantiateClassWithFields", "Find and instantiate ClassWithFields.");
+        if (!FindAndInstantiate ("NSPC.ClassWithFields", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClassWithFields");
+
+        if (VerifyMethod (genType, genObject, "UsePrivateField", new object[] {6}, 6)) {
+            VerifyScenario ("CheckUsePrivateField");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/declaremethod.cs b/workyard/tests/codedom/tests/declaremethod.cs
new file mode 100755
index 0000000..a8d647f
--- /dev/null
+++ b/workyard/tests/codedom/tests/declaremethod.cs
@@ -0,0 +1,661 @@
+#define FSHARP
+// F#: Added CodeTypeReferenceExpression as a target where calling static methods
+//     Added casting where assigning inherited class to variable of base type
+//
+/*
+  Currently there is the following porblem: 
+ 
+  #light
+  type ISome = 
+    interface
+      abstract InterfaceMethod : int -> int
+    end
+  and Test = 
+    class
+      interface ISome with
+        member this.InterfaceMethod  (a) =
+          a + 5
+      end
+    end
+
+  >>> error: The type 'ISome' is not an interface type.
+*/
+
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class DeclareMethod : CodeDomTestTree {
+
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "DeclareMethod";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests declaration of methods.";
+        }
+    }
+
+    public override CompilerParameters GetCompilerParameters (CodeDomProvider provider) {
+        CompilerParameters parms = base.GetCompilerParameters (provider);
+
+        // some languages don't compile correctly if no executable is
+        // generated and an entry point is defined
+        if (Supports (provider, GeneratorSupport.EntryPointMethod)) {
+            parms.GenerateExecutable = true;
+        }
+        return parms;
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        nspace.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (nspace);
+
+        CodeTypeDeclaration cd = new CodeTypeDeclaration ("TEST");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        if (Supports (provider, GeneratorSupport.ReferenceParameters)) {
+            //************** static internal method with parameters with out and ref directions,    **************
+            //**************                                              and void return type    ************** 
+            // GENERATES (C#):
+            //        /*FamANDAssem*/ internal static void Work(ref int i, out int j) {
+            //            i = (i + 4);
+            //            j = 5;
+            //        }              
+            CodeMemberMethod cmm1 = new CodeMemberMethod ();
+            cmm1.Name = "Work";
+            cmm1.ReturnType = new CodeTypeReference ("System.void");
+            cmm1.Attributes = MemberAttributes.Static | MemberAttributes.FamilyAndAssembly;
+            // add parameter with ref direction
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            param.Direction = FieldDirection.Ref;
+            cmm1.Parameters.Add (param);
+            // add parameter with out direction
+            param = new CodeParameterDeclarationExpression (typeof (int), "j");
+            param.Direction = FieldDirection.Out;
+            cmm1.Parameters.Add (param);
+            cmm1.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("i"),
+                new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.Add, new CodePrimitiveExpression (4))));
+            cmm1.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("j"),
+                new CodePrimitiveExpression (5)));
+            cd.Members.Add (cmm1);
+        }
+        // ********* pass by value using a protected method ******
+        // GENERATES (C#):
+        //        protected static int ProtectedMethod(int a) {
+        //            return a;
+        //        }
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "ProtectedMethod";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Family | MemberAttributes.Static;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cd.Members.Add (cmm);
+
+        // declare a method to test the protected method with new attribute
+        // GENERATES (C#):
+        //        public static int CallProtected(int a) {
+        //            return (a + ProtectedMethod(a));
+        //        }
+        AddScenario ("CheckCallProtected");
+        cmm = new CodeMemberMethod ();
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Name = "CallProtected";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public;
+        CodeMethodReferenceExpression meth = new CodeMethodReferenceExpression ();
+        meth.MethodName = "ProtectedMethod";
+        meth.TargetObject = new CodeTypeReferenceExpression("TEST2");        
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("a"),
+            CodeBinaryOperatorType.Add, new CodeMethodInvokeExpression (meth, new CodeArgumentReferenceExpression ("a")))));
+        cd.Members.Add (cmm);
+
+
+
+        // GENERATES (C#):
+        //        public static void Main() {
+        //          }
+        if (Supports (provider, GeneratorSupport.EntryPointMethod)) {
+            CodeEntryPointMethod cep = new CodeEntryPointMethod ();
+            cd.Members.Add (cep);
+        }
+
+        // add a second class 
+        cd = new CodeTypeDeclaration ("TEST2");
+        cd.BaseTypes.Add (new CodeTypeReference ("TEST"));
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        if (Supports (provider, GeneratorSupport.ReferenceParameters)) {
+            // GENERATES (C#):
+            //        public static int CallingWork(int a) {
+            //            a = 10;
+            //            int b;
+            //            TEST.Work(ref a, out b);
+            //            return (a + b);
+            //        }
+            AddScenario ("CheckCallingWork");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "CallingWork";
+            cmm.Attributes = MemberAttributes.Public;
+            CodeParameterDeclarationExpression parames = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (parames);
+            cmm.ReturnType = new CodeTypeReference ("System.Int32");
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"),
+                new CodePrimitiveExpression (10)));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "b"));
+            // invoke the method called "work"
+            CodeMethodInvokeExpression methodinvoked = new CodeMethodInvokeExpression (new CodeTypeReferenceExpression ("TEST"), "Work");
+            // add parameter with ref direction
+            CodeDirectionExpression parameter = new CodeDirectionExpression (FieldDirection.Ref,
+                new CodeArgumentReferenceExpression ("a"));
+            methodinvoked.Parameters.Add (parameter);
+            // add parameter with out direction
+            parameter = new CodeDirectionExpression (FieldDirection.Out, new CodeVariableReferenceExpression ("b"));
+            methodinvoked.Parameters.Add (parameter);
+            cmm.Statements.Add (methodinvoked);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression
+                (new CodeArgumentReferenceExpression ("a"), CodeBinaryOperatorType.Add, new CodeVariableReferenceExpression ("b"))));
+            cd.Members.Add (cmm);
+        }
+
+        // ***** declare a private method with value return type ******
+        // GENERATES (C#):
+        //        private static int PrivateMethod() {
+        //            return 5;
+        //        }
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "PrivateMethod";
+        cmm.Attributes = MemberAttributes.Private | MemberAttributes.Static;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (5)));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cd.Members.Add (cmm);
+
+        // declare a method to test the private method
+        // GENERATES (C#):
+        //        public static int CallPrivateMethod(int a) {
+        //            return (a + PrivateMethod());
+        //        }
+        AddScenario ("CheckCallPrivateMethod");
+        cmm = new CodeMemberMethod ();
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Name = "CallPrivateMethod";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public;
+        meth = new CodeMethodReferenceExpression ();
+        meth.TargetObject = new CodeTypeReferenceExpression("TEST2");
+        meth.MethodName = "PrivateMethod";
+
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("a"),
+            CodeBinaryOperatorType.Add, new CodeMethodInvokeExpression (meth))));
+        cd.Members.Add (cmm);
+
+        // ********* pass by value using a protected static method ******
+        // this class needs to inherit from the first class so that we can call the protected method from here and call the 
+        // public method that calls the protected method from that class
+        // declare a method to test the protected method
+        // GENERATES (C#):
+        //        public static int CallProtectedAndPublic(int a) {
+        //            return (CallProtected(a) + ProtectedMethod(a));
+        //        }
+        AddScenario ("CheckCallProtectedAndPublic");
+        cmm = new CodeMemberMethod ();
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Name = "CallProtectedAndPublic";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public;
+        meth = new CodeMethodReferenceExpression ();
+        meth.MethodName = "ProtectedMethod";
+        meth.TargetObject = new CodeTypeReferenceExpression("TEST2");
+        CodeMethodReferenceExpression meth2 = new CodeMethodReferenceExpression ();
+        meth2.MethodName = "CallProtected";
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new CodeMethodInvokeExpression (meth2,
+            new CodeArgumentReferenceExpression ("a")),
+            CodeBinaryOperatorType.Add, new CodeMethodInvokeExpression (meth,
+            new CodeArgumentReferenceExpression ("a")))));
+        cd.Members.Add (cmm);
+
+        if (Supports (provider, GeneratorSupport.DeclareInterfaces)) {
+
+            // ******** implement a single public interface ***********                      
+            // declare an interface
+            // GENERATES (C#):      
+            //     public interface TEST3 {    
+            //         int InterfaceMethod(int a);
+            //     }
+            cd = new CodeTypeDeclaration ("TEST3");
+            cd.IsInterface = true;
+            nspace.Types.Add (cd);
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "InterfaceMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cd.Members.Add (cmm);
+
+            // implement the interface
+            // GENERATES (C#):
+            //    public class TEST3b : object, TEST3 {
+            //         public virtual int InterfaceMethod(int a) {
+            //             return a;
+            //         }
+            //     }
+            cd = new CodeTypeDeclaration ("TEST3b");
+            cd.BaseTypes.Add (new CodeTypeReference ("System.Object"));
+            cd.BaseTypes.Add (new CodeTypeReference ("TEST3"));
+            cd.IsClass = true;
+            nspace.Types.Add (cd);
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "InterfaceMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.ImplementationTypes.Add (new CodeTypeReference ("TEST3"));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            cd.Members.Add (cmm);
+
+            // ********implement two interfaces with overloading method name*******
+            // declare the second interface      
+            // GENERATES (C#):
+            //    public interface TEST4 {
+            //         int InterfaceMethod(int a);
+            //     }
+            cd = new CodeTypeDeclaration ("TEST4");
+            cd.IsInterface = true;
+            nspace.Types.Add (cd);
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "InterfaceMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cd.Members.Add (cmm);
+
+            // implement both of the interfaces
+            // GENERATES (C#):
+            //    public class TEST4b : object, TEST3, TEST4 {
+            //         public int InterfaceMethod(int a) {
+            //             return a;
+            //         }
+            //     }
+            cd = new CodeTypeDeclaration ("TEST4b");
+            cd.BaseTypes.Add (new CodeTypeReference ("System.Object"));
+            cd.BaseTypes.Add (new CodeTypeReference ("TEST3"));
+            cd.BaseTypes.Add (new CodeTypeReference ("TEST4"));
+            cd.IsClass = true;
+            nspace.Types.Add (cd);
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "InterfaceMethod";
+            cmm.ImplementationTypes.Add (new CodeTypeReference ("TEST3"));
+            cmm.ImplementationTypes.Add (new CodeTypeReference ("TEST4"));
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            cd.Members.Add (cmm);
+        }
+
+        // create a class which will have a method to call the method name that was overloaded
+        // this class will also call a  method in the class that implements the private implements testcase
+        cd = new CodeTypeDeclaration ("TEST5");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        if (Supports (provider, GeneratorSupport.DeclareInterfaces)) {
+            // GENERATES (C#):
+            //        public static int TestMultipleInterfaces(int i) {
+            //             TEST4b t = new TEST4b();
+            //             TEST3 TEST3 = ((TEST3)(t));
+            //             TEST4 TEST4 = ((TEST4)(t));
+            //             return (TEST3.InterfaceMethod(i) - TEST4.InterfaceMethod(i));
+            //         }
+            AddScenario ("CheckTestMultipleInterfaces");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "TestMultipleInterfaces";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("TEST4b", "t", new CodeObjectCreateExpression ("TEST4b")));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("TEST3", "TEST3", new CodeCastExpression ("TEST3",
+                new CodeVariableReferenceExpression ("t"))));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("TEST4", "TEST4", new CodeCastExpression ("TEST4",
+                new CodeVariableReferenceExpression ("t"))));
+            CodeMethodInvokeExpression methodinvoking = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("TEST3")
+                , "InterfaceMethod");
+            methodinvoking.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+            CodeMethodInvokeExpression methodinvoking2 = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("TEST4")
+                , "InterfaceMethod");
+            methodinvoking2.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+                methodinvoking, CodeBinaryOperatorType.Subtract, methodinvoking2)));
+            cd.Members.Add (cmm);
+
+            // GENERATES (C#):
+            //        public static int PrivateImplements(int i) {
+            //             TEST6 t = new TEST6();
+            //             TEST3 TEST3 = ((TEST3)(t));
+            //             TEST4 TEST4 = ((TEST4)(t));
+            //             return (TEST3.InterfaceMethod(i) - TEST4.InterfaceMethod(i));
+            //         }
+            AddScenario ("CheckPrivateImplements");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "PrivateImplements";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("TEST6", "t", new CodeObjectCreateExpression ("TEST6")));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("TEST3", "TEST3", new CodeCastExpression ("TEST3",
+                new CodeVariableReferenceExpression ("t"))));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("TEST4", "TEST4", new CodeCastExpression ("TEST4",
+                new CodeVariableReferenceExpression ("t"))));
+            methodinvoking = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("TEST3")
+                , "InterfaceMethod");
+            methodinvoking.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+            methodinvoking2 = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("TEST4")
+                , "InterfaceMethod");
+            methodinvoking2.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+                methodinvoking, CodeBinaryOperatorType.Subtract, methodinvoking2)));
+            cd.Members.Add (cmm);
+
+            //******************* private implements ***************************
+            // implement both of the interfaces
+            // GENERATES (C#):
+            //    public class TEST6 : object, TEST3, TEST4 {
+            //         int TEST3.InterfaceMethod(int a) {
+            //             return a;
+            //         }      
+            //         int TEST4.InterfaceMethod(int a) {
+            //             return (5 * a);
+            //         }
+            //     }
+            CodeTypeDeclaration ctd = new CodeTypeDeclaration ("TEST6");
+            ctd.BaseTypes.Add (new CodeTypeReference ("System.Object"));
+            ctd.BaseTypes.Add (new CodeTypeReference ("TEST3"));
+            ctd.BaseTypes.Add (new CodeTypeReference ("TEST4"));
+            ctd.IsClass = true;
+            nspace.Types.Add (ctd);
+            // make a seperate implementation for each base 
+            // first for TEST3 base
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "InterfaceMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            cmm.PrivateImplementationType = new CodeTypeReference ("TEST3");
+
+            ctd.Members.Add (cmm);
+            // now implement for TEST4 base
+            cmm = new CodeMemberMethod ();
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "InterfaceMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            cmm.PrivateImplementationType = new CodeTypeReference ("TEST4");
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new
+                CodePrimitiveExpression (5), CodeBinaryOperatorType.Multiply, new
+                CodeArgumentReferenceExpression ("a"))));
+            ctd.Members.Add (cmm);
+        }
+
+        // method to test the 'new' scenario by calling the 'new' method
+        // GENERATES (C#):
+        //        public int CallingNewScenario(int i) {
+        //            ClassWVirtualMethod t = new ClassWNewMethod();
+        //            return (((ClassWNewMethod)(t)).VirtualMethod(i) - t.VirtualMethod(i));
+        //        }
+      
+        CodeMethodInvokeExpression methodinvoke;
+
+#if !FSHARP 
+        AddScenario ("CheckCallingNewScenario");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "CallingNewScenario";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeVariableDeclarationStatement ("ClassWVirtualMethod", "t", new CodeCastExpression(new CodeTypeReference("ClassWVirtualMethod"), new CodeObjectCreateExpression ("ClassWNewMethod"))));
+        CodeMethodInvokeExpression methodinvoke = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t"), "VirtualMethod");
+        methodinvoke.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+        CodeMethodInvokeExpression methodinvoke2 = new CodeMethodInvokeExpression (new CodeCastExpression ("ClassWNewMethod", new
+            CodeVariableReferenceExpression ("t")), "VirtualMethod");
+        methodinvoke2.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+            methodinvoke2, CodeBinaryOperatorType.Subtract, methodinvoke)));
+        cd.Members.Add (cmm);
+#endif
+
+        // similar to the 'new' test, write a method to complete testing of the 'override' scenario
+        // GENERATES (C#):
+        //        public static int CallingOverrideScenario(int i) {
+        //            ClassWVirtualMethod t = new ClassWOverrideMethod();
+        //            return t.VirtualMethod(i);
+        //        }
+        AddScenario ("CheckCallingOverrideScenario");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "CallingOverrideScenario";
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add(new CodeVariableDeclarationStatement("ClassWVirtualMethod", "t", new CodeCastExpression(new CodeTypeReference("ClassWVirtualMethod"), new CodeObjectCreateExpression("ClassWOverrideMethod"))));
+        methodinvoke = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t"), "VirtualMethod");
+        methodinvoke.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+        cmm.Statements.Add (new CodeMethodReturnStatement (methodinvoke));
+        cd.Members.Add (cmm);
+
+
+
+        //*************** overload member function ****************             
+        // new class which will include both functions
+        // GENERATES (C#):
+        //    public class TEST7 {
+        //         public static int OverloadedMethod(int a) {
+        //             return a;
+        //         }
+        //         public static int OverloadedMethod(int a, int b) {
+        //             return (b + a);
+        //         }
+        //         public static int CallingOverloadedMethods(int i) {
+        //             return (OverloadedMethod(i, i) - OverloadedMethod(i));
+        //         }
+        //     }
+        cd = new CodeTypeDeclaration ("TEST7");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "OverloadedMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+        cd.Members.Add (cmm);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "OverloadedMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "b"));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+            new CodeArgumentReferenceExpression ("b"), CodeBinaryOperatorType.Add,
+            new CodeArgumentReferenceExpression ("a"))));
+        cd.Members.Add (cmm);
+
+        // declare a method that will call both OverloadedMethod functions
+        AddScenario ("CheckCallingOverloadedMethods");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "CallingOverloadedMethods";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.Attributes = MemberAttributes.Public;
+        CodeMethodReferenceExpression methodref = new CodeMethodReferenceExpression ();
+        methodref.MethodName = "OverloadedMethod";
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+            new CodeMethodInvokeExpression (methodref, new
+            CodeArgumentReferenceExpression ("i"), new CodeArgumentReferenceExpression ("i"))
+            , CodeBinaryOperatorType.Subtract, new CodeMethodInvokeExpression (methodref, new
+            CodeArgumentReferenceExpression ("i")))));
+        cd.Members.Add (cmm);
+
+
+        // ***************** declare method using new ******************
+        // first declare a class with a virtual method in it 
+        // GENERATES (C#):
+        //         public class ClassWVirtualMethod {
+        //                 public virtual int VirtualMethod(int a) {
+        //                     return a;
+        //                 }
+        //         }    
+        cd = new CodeTypeDeclaration ("ClassWVirtualMethod");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "VirtualMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+        cd.Members.Add (cmm);
+
+#if !FSHARP 
+        // now declare a class that inherits from the previous class and has a 'new' method with the
+        // name VirtualMethod
+        // GENERATES (C#):
+        //    public class ClassWNewMethod : ClassWVirtualMethod {
+        //         public new virtual int VirtualMethod(int a) {
+        //             return (2 * a);
+        //         }
+        //     }
+        cd = new CodeTypeDeclaration ("ClassWNewMethod");
+        cd.BaseTypes.Add (new CodeTypeReference ("ClassWVirtualMethod"));
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "VirtualMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.New;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+            new CodePrimitiveExpression (2), CodeBinaryOperatorType.Multiply
+            , new CodeArgumentReferenceExpression ("a"))));
+        cd.Members.Add (cmm);
+#endif
+
+        // *************** declare a method using override ******************
+        // now declare a class that inherits from the previous class and has a 'new' method with the
+        // name VirtualMethod
+        // GENERATES (C#):
+        //            public class ClassWOverrideMethod : ClassWVirtualMethod {
+        //                 public override int VirtualMethod(int a) {
+        //                     return (2 * a);
+        //                 }
+        //             }
+        cd = new CodeTypeDeclaration ("ClassWOverrideMethod");
+        cd.BaseTypes.Add (new CodeTypeReference ("ClassWVirtualMethod"));
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "VirtualMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Override;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+            new CodePrimitiveExpression (2), CodeBinaryOperatorType.Multiply
+            , new CodeArgumentReferenceExpression ("a"))));
+        cd.Members.Add (cmm);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateTEST2", "Find and instantiate TEST2.");
+        if (!FindAndInstantiate ("NSPC.TEST2", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTEST2");
+
+        if (Supports (provider, GeneratorSupport.ReferenceParameters) &&
+                VerifyMethod (genType, genObject, "CallingWork", new object [] {1516}, 19)) {
+            VerifyScenario ("CheckCallingWork");
+        }
+
+        if (VerifyMethod (genType, genObject, "CallPrivateMethod", new object [] {1516}, 1521)) {
+            VerifyScenario ("CheckCallPrivateMethod");
+        }
+
+        if (VerifyMethod (genType, genObject, "CallProtectedAndPublic", new object [] {1516}, 4548)) {
+            VerifyScenario ("CheckCallProtectedAndPublic");
+        }
+        
+        AddScenario ("InstantiateTEST", "Find and instantiate TEST.");
+        if (!FindAndInstantiate ("NSPC.TEST", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTEST");
+
+        if (VerifyMethod (genType, genObject, "CallProtected", new object[] {2}, 4)) {
+            VerifyScenario ("CheckCallProtected");
+        }
+
+        AddScenario ("InstantiateTEST5", "Find and instantiate TEST5.");
+        if (!FindAndInstantiate ("NSPC.TEST5", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTEST5");
+
+        if (VerifyMethod (genType, genObject, "CallingNewScenario", new object[] {2}, 2)) {
+            VerifyScenario ("CheckCallingNewScenario");
+        }
+
+        if (VerifyMethod (genType, genObject, "CallingOverrideScenario", new object[] {2}, 4)) {
+            VerifyScenario ("CheckCallingOverrideScenario");
+        }
+
+        if (Supports (provider, GeneratorSupport.DeclareInterfaces)) {
+            if (VerifyMethod (genType, genObject, "TestMultipleInterfaces", new object[] {2}, 0)) {
+                VerifyScenario ("CheckTestMultipleInterfaces");
+            }
+            if (VerifyMethod (genType, genObject, "PrivateImplements", new object[] {2}, -8)) {
+                VerifyScenario ("CheckPrivateImplements");
+            }
+        }
+
+        AddScenario ("InstantiateTEST7", "Find and instantiate TEST7.");
+        if (!FindAndInstantiate ("NSPC.TEST7", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTEST7");
+
+        if (VerifyMethod (genType, genObject, "CallingOverloadedMethods", new object[] {2}, 2)) {
+            VerifyScenario ("CheckCallingOverloadedMethods");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/delegatetest.cs b/workyard/tests/codedom/tests/delegatetest.cs
new file mode 100755
index 0000000..f0f5870
--- /dev/null
+++ b/workyard/tests/codedom/tests/delegatetest.cs
@@ -0,0 +1,224 @@
+// F#: Our delegates work with <= 5 arguments. Changed test to use only 5 arguments (originally it used 20!)
+
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.VisualBasic;
+
+public class DelegateTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name
+    {
+        get
+        {
+            return "DelegateTest";
+        }
+    }
+
+    public override string Description
+    {
+        get
+        {
+            return "Tests delegates.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu)
+    {
+
+        // GENERATES (C#):
+        //
+        //  namespace NSPC {
+        //    public class DelegateClass {
+        //        
+        //        public virtual int Sum(
+        //                    int val1, 
+        //                    int val2, 
+        //                    int val3, 
+        //                    int val4, 
+        //                    int val5, 
+        //                    int val6, 
+        //                    int val7, 
+        //                    int val8, 
+        //                    int val9, 
+        //                    int val10, 
+        //                    int val11, 
+        //                    int val12, 
+        //                    int val13, 
+        //                    int val14, 
+        //                    int val15, 
+        //                    int val16, 
+        //                    int val17, 
+        //                    int val18, 
+        //                    int val19, 
+        //                    int val20) {
+        //            int mySum = 0;
+        //            mySum = (mySum + val1);
+        //            mySum = (mySum + val2);
+        //            mySum = (mySum + val3);
+        //            mySum = (mySum + val4);
+        //            mySum = (mySum + val5);
+        //            mySum = (mySum + val6);
+        //            mySum = (mySum + val7);
+        //            mySum = (mySum + val8);
+        //            mySum = (mySum + val9);
+        //            mySum = (mySum + val10);
+        //            mySum = (mySum + val11);
+        //            mySum = (mySum + val12);
+        //            mySum = (mySum + val13);
+        //            mySum = (mySum + val14);
+        //            mySum = (mySum + val15);
+        //            mySum = (mySum + val16);
+        //            mySum = (mySum + val17);
+        //            mySum = (mySum + val18);
+        //            mySum = (mySum + val19);
+        //            mySum = (mySum + val20);
+        //            return mySum;
+        //        }
+        //        
+        //        public virtual int Do() {
+        //            MyDelegate myDel = new DelegateClass.MyDelegate(this.Sum);
+        //            return myDel(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765);
+        //        }
+        //    }
+        //        
+        //    public delegate int MyDelegate(
+        //                    int val1, 
+        //                    int val2, 
+        //                    int val3, 
+        //                    int val4, 
+        //                    int val5, 
+        //                    int val6, 
+        //                    int val7, 
+        //                    int val8, 
+        //                    int val9, 
+        //                    int val10, 
+        //                    int val11, 
+        //                    int val12, 
+        //                    int val13, 
+        //                    int val14, 
+        //                    int val15, 
+        //                    int val16, 
+        //                    int val17, 
+        //                    int val18, 
+        //                    int val19, 
+        //                    int val20);
+        //    }
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        cu.Namespaces.Add (nspace);
+
+        // only produce code if the generator can declare delegates
+        if (Supports (provider, GeneratorSupport.DeclareDelegates)) {
+            CodeTypeDeclaration class1 = new CodeTypeDeclaration ("DelegateClass");
+            class1.IsClass = true;
+            nspace.Types.Add (class1);
+
+            CodeTypeDelegate td = new CodeTypeDelegate ("MyDelegate");
+            td.ReturnType = new CodeTypeReference (typeof (Int32));
+            for (int i = 1; i <= 5; i++)
+                td.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (Int32)), "val" + i));
+            nspace.Types.Add (td);
+
+            CodeMemberMethod cmm = new CodeMemberMethod ();
+            cmm.Name = "Sum";
+            cmm.ReturnType = new CodeTypeReference (typeof (Int32));
+            for (int i = 1; i <= 5; i++)
+                cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (Int32)), "val" + i));
+            cmm.Attributes = MemberAttributes.Public;
+
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "mySum", new CodePrimitiveExpression (0)));
+
+            for (int i = 1; i <= 5; i++)
+                cmm.Statements.Add (CDHelper.CreateIncrementByStatement ("mySum", new CodeArgumentReferenceExpression ("val" + i)));
+
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeVariableReferenceExpression ("mySum")));
+
+            class1.Members.Add (cmm);
+
+#if !WHIDBEY
+            if (!(provider is VBCodeProvider)) {
+#endif
+                AddScenario ("CheckDo", "Check Do()'s return value.");
+                cmm = new CodeMemberMethod ();
+                cmm.Name = "Do";
+                cmm.ReturnType = new CodeTypeReference (typeof (Int32));
+                cmm.Attributes = MemberAttributes.Public;
+
+                cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference ("MyDelegate"), "myDel",
+                    new CodeDelegateCreateExpression (new CodeTypeReference ("NSPC.MyDelegate"),
+                    new CodeThisReferenceExpression (), "Sum")));
+
+                CodeDelegateInvokeExpression delegateInvoke = new CodeDelegateInvokeExpression ();
+                delegateInvoke.TargetObject = new CodeVariableReferenceExpression ("myDel");
+                for (int i = 1; i <= 5; i++)
+                    delegateInvoke.Parameters.Add (new CodePrimitiveExpression (fib (i)));
+                cmm.Statements.Add (new CodeMethodReturnStatement (delegateInvoke));
+
+                class1.Members.Add (cmm);
+#if !WHIDBEY
+            }
+#endif
+        }
+    }
+
+    // return the n-th Fibonacci number where n >= 1
+    int fib (int n) {
+        if (n <= 2)
+            return 1;
+        else
+            return fib (n - 1) + fib (n - 2);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+#if !WHIDBEY
+        if (!(provider is VBCodeProvider)) {
+#endif
+            if (Supports (provider, GeneratorSupport.DeclareDelegates)) {
+                int    fibSum = 0;
+                object genObject;
+                Type   genType;
+
+                // calculate the expected sum
+                for (int i = 1; i <= 5; i++)
+                    fibSum += fib (i);
+
+                AddScenario ("instantiateDelegateClass", "Find and instantiate DelegateClass.");
+                if (!FindAndInstantiate ("NSPC.DelegateClass", asm, out genObject, out genType))
+                    return;
+                VerifyScenario ("instantiateDelegateClass");
+
+                if (VerifyMethod (genType, genObject, "Do", new object[] {}, fibSum))
+                    VerifyScenario ("CheckDo");
+            }
+#if !WHIDBEY
+        }
+#endif
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/enumtest.cs b/workyard/tests/codedom/tests/enumtest.cs
new file mode 100755
index 0000000..96a9734
--- /dev/null
+++ b/workyard/tests/codedom/tests/enumtest.cs
@@ -0,0 +1,334 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class EnumTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "EnumTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Test enumerations";
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        CodeNamespace ns = new CodeNamespace ("Namespace1");
+
+        cu.Namespaces.Add (ns);
+
+        CodeTypeDeclaration cd = new CodeTypeDeclaration ("TEST");
+        cd.IsClass = true;
+        ns.Types.Add (cd);
+
+        if (Supports (provider, GeneratorSupport.DeclareEnums)) {
+            // GENERATE (C#):
+            //    public enum DecimalEnum {
+            //        Num0 = 0,
+            //        Num1 = 1,
+            //        Num2 = 2,
+            //        Num3 = 3,
+            //        Num4 = 4,
+            //    }
+
+            CodeTypeDeclaration ce = new CodeTypeDeclaration ("DecimalEnum");
+            ce.IsEnum = true;
+            ns.Types.Add (ce);
+
+            // things to enumerate
+            for (int k = 0; k < 5; k++) {
+                CodeMemberField Field = new CodeMemberField ("System.Int32", "Num" + (k).ToString ());
+                //Field.InitExpression = new CodePrimitiveExpression (k);
+                ce.Members.Add (Field);
+            }
+
+            // GENERATE (C#):
+            //    public enum BinaryEnum {
+            //        Bin1 = 1,
+            //        Bin2 = 2,
+            //        Bin3 = 4,
+            //        Bin4 = 8,
+            //        Bin5 = 16,
+            //    }
+
+            ce = new CodeTypeDeclaration ("BinaryEnum");
+            ce.IsEnum = true;
+            ns.Types.Add (ce);
+
+            // things to enumerate
+            int i = 0x01;
+            for (int k = 1; k < 6; k++) {
+                CodeMemberField Field = new CodeMemberField (typeof (int), "Bin" + (k).ToString ());
+                Field.InitExpression = new CodePrimitiveExpression (i);
+                i = i * 2;
+                ce.Members.Add (Field);
+            }
+
+#if WHIDBEY
+            // GENERATE (C#):
+            //    public enum MyEnum: System.UInt64 {
+            //        small = 0,
+            //        medium = Int64.MaxValue/10,
+            //        large = Int64.MaxValue,
+            //    }
+            ce = new CodeTypeDeclaration ("MyEnum");
+            ce.BaseTypes.Add (new CodeTypeReference (typeof (UInt64)));
+            ce.IsEnum = true;
+            ns.Types.Add (ce);
+
+            // Add fields     
+            ce.Members.Add (CreateFieldMember ("Small", 0));
+            ce.Members.Add (CreateFieldMember ("Medium", Int64.MaxValue / 10));
+            ce.Members.Add (CreateFieldMember ("Large", Int64.MaxValue));
+#endif
+
+            // GENERATE (C#):
+            //        public int OutputDecimalEnumVal(int i) {
+            //                if ((i == 3)) {
+            //                        return ((int)(DecimalEnum.Num3));
+            //                }
+            //                if ((i == 4)) {
+            //                        return ((int)(DecimalEnum.Num4));
+            //                }
+            //                if ((i == 2)) {
+            //                        return ((int)(DecimalEnum.Num2));
+            //                }
+            //                if ((i == 1)) {
+            //                        return ((int)(DecimalEnum.Num1));
+            //                }
+            //                if ((i == 0)) {
+            //                        return ((int)(DecimalEnum.Num0));
+            //                }
+            //                    return (i + 10);
+            //            }
+    
+            // generate 5 scenarios for OutputDecimalEnumVal
+            for (int k = 0; k < 5; k++)
+                AddScenario ("CheckOutputDecimalEnumVal" + k);
+
+            CodeMemberMethod cmm = new CodeMemberMethod ();
+            cmm.Name = "OutputDecimalEnumVal";
+            cmm.Attributes = MemberAttributes.Public;
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            cmm.Parameters.Add (param);
+            CodeBinaryOperatorExpression eq       = new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.ValueEquality,
+                new CodePrimitiveExpression (3));
+            CodeMethodReturnStatement    truestmt = new CodeMethodReturnStatement (
+                new CodeCastExpression (typeof (int),
+                new CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("DecimalEnum"), "Num3")));
+            CodeConditionStatement       condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (4));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("DecimalEnum"), "Num4")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (2));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("DecimalEnum"), "Num2")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (1));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("DecimalEnum"), "Num1")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (0));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("DecimalEnum"), "Num0")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            cmm.ReturnType = new CodeTypeReference ("System.Int32");
+
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression (10))));
+            cd.Members.Add (cmm);
+
+
+            // GENERATE (C#):
+            //        public int OutputBinaryEnumVal(int i) {
+            //            if ((i == 3)) {
+            //                return ((int)(BinaryEnum.Bin3));
+            //            }
+            //            if ((i == 4)) {
+            //                return ((int)(BinaryEnum.Bin4));
+            //            }
+            //            if ((i == 2)) {
+            //                return ((int)(BinaryEnum.Bin2));
+            //            }
+            //            if ((i == 1)) {
+            //                return ((int)(BinaryEnum.Bin1));
+            //            }
+            //            if ((i == 5)) {
+            //                return ((int)(BinaryEnum.Bin5));
+            //            }
+            //            return (i + 10);
+            //        }
+
+            // generate 6 scenarios for OutputBinaryEnumVal
+            for (int k = 1; k < 6; k++)
+                AddScenario ("CheckOutputBinaryEnumVal" + k);
+           AddScenario ("CheckOutputBinaryEnumValRet17", "Check for a return value of 17");
+
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "OutputBinaryEnumVal";
+            cmm.Attributes = MemberAttributes.Public;
+            param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            cmm.Parameters.Add (param);
+            eq = new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.ValueEquality,
+                new CodePrimitiveExpression (3));
+            truestmt = new CodeMethodReturnStatement (
+                new CodeCastExpression (typeof (int),
+                new CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("BinaryEnum"), "Bin3")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (4));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("BinaryEnum"), "Bin4")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (2));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("BinaryEnum"), "Bin2")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (1));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("BinaryEnum"), "Bin1")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (5));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("BinaryEnum"), "Bin5")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            cmm.ReturnType = new CodeTypeReference ("System.Int32");
+
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression (10))));
+            cd.Members.Add (cmm);
+
+
+#if WHIDBEY
+            // GENERATE (C#):
+            //        public long VerifyMyEnumExists(int num) {
+            //            if ((num == Int32.MaxValue)) {
+            //                return ((int)(MyEnum.Large));
+            //            }
+            //            return 0;
+            //        }
+
+            AddScenario ("CheckVerifyMyEnumExists");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "VerifyMyEnumExists";
+            cmm.Attributes = MemberAttributes.Public;
+            param = new CodeParameterDeclarationExpression (typeof (int), "num");
+            cmm.Parameters.Add (param);
+            cmm.ReturnType = new CodeTypeReference ("System.Int64");
+            eq = new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("num"), CodeBinaryOperatorType.ValueEquality,
+                new CodePrimitiveExpression (Int32.MaxValue));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (long),
+                        new CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("MyEnum"),
+                            "Large")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (0)));
+            cd.Members.Add (cmm);
+#endif
+        }
+    }
+
+    private CodeMemberField CreateFieldMember (String strFieldName, long strFieldValue){
+        CodeMemberField field = new CodeMemberField (typeof (UInt64), strFieldName);
+        field.InitExpression = new CodePrimitiveExpression (strFieldValue);
+        return field;
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm)  {
+        if (Supports (provider, GeneratorSupport.DeclareEnums)) {
+            object genObject;
+            Type   genType;
+
+            AddScenario ("InstantiateTEST", "Find and instantiate TEST.");
+            if (!FindAndInstantiate ("Namespace1.TEST", asm, out genObject, out genType))
+                return;
+            VerifyScenario ("InstantiateTEST");
+
+            // verify method return value, verify that ref and out worked accordingly
+
+            // verifying first enumeration 
+            for (int a = 0; a < 5; a++) {
+                if (VerifyMethod (genType, genObject, "OutputDecimalEnumVal", new object[]{a}, a)) {
+                    VerifyScenario ("CheckOutputDecimalEnumVal" + a);
+                }
+            }
+
+            // verifying second enumeration
+            int val = 1;
+            for (int i = 1; i < 6; i++) {
+                if (VerifyMethod (genType, genObject, "OutputBinaryEnumVal", new object[]{i}, val)) {
+                    VerifyScenario ("CheckOutputBinaryEnumVal" + i);
+                }
+                val = val * 2;
+            }
+
+            if (VerifyMethod (genType, genObject, "OutputBinaryEnumVal", new object[]{7}, 17)) {
+                VerifyScenario ("CheckOutputBinaryEnumValRet17");
+            }
+
+#if WHIDBEY
+            if (VerifyMethod (genType, genObject, "VerifyMyEnumExists", new object[]{Int32.MaxValue}, Int64.MaxValue)) {
+                VerifyScenario ("CheckVerifyMyEnumExists");
+            }
+#endif
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/eventtest.cs b/workyard/tests/codedom/tests/eventtest.cs
new file mode 100755
index 0000000..d72418d
--- /dev/null
+++ b/workyard/tests/codedom/tests/eventtest.cs
@@ -0,0 +1,388 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class EventTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return false;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "EventTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests events.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // GENERATES (C#):
+        //  [assembly: System.CLSCompliantAttribute(false)]
+        //  
+        //  namespace MyNamespace {
+        //      using System;
+        //      using System.Drawing;
+        //      using System.Windows.Forms;
+        //      using System.ComponentModel;
+        //      
+        //      
+        //      public class Test : Form {
+        //          
+        //          private Button b = new Button();
+        //          
+        //          public Test() {
+        //              this.Size = new Size(600, 600);
+        //              b.Text = "Test";
+        //              b.TabIndex = 0;
+        //              b.Location = new Point(400, 525);
+        //              this.MyEvent += new EventHandler(this.b_Click);
+        //              this.MyEvent -= new EventHandler(this.b_Click);
+        //          }
+        //          
+        //          [System.CLSCompliantAttribute(false)]
+        //          public event System.EventHandler MyEvent;
+        //          
+        //          private void b_Click(object sender, System.EventArgs e) {
+        //          }
+        //      }
+        //  }
+        //  namespace SecondNamespace {
+        //      using System;
+        //      using System.Drawing;
+        //      using System.Windows.Forms;
+        //      using System.ComponentModel;
+        //      
+        //      
+        //      public class Test : Form {
+        //          
+        //          private Button b = new Button();
+        //          
+        //          public Test() {
+        //              this.Size = new Size(600, 600);
+        //              b.Text = "Test";
+        //              b.TabIndex = 0;
+        //              b.Location = new Point(400, 525);
+        //              this.MyEvent += new EventHandler(this.b_Click);
+        //          }
+        //          
+        //          private event System.EventHandler MyEvent;
+        //          
+        //          private void b_Click(object sender, System.EventArgs e) {
+        //          }
+        //      }
+        //  }
+        //  namespace ThirdNamespace {
+        //      using System;
+        //      using System.Drawing;
+        //      using System.Windows.Forms;
+        //      using System.ComponentModel;
+        //      
+        //      
+        //      public class Test : Form {
+        //          
+        //          private Button b = new Button();
+        //          
+        //          public Test() {
+        //              this.Size = new Size(600, 600);
+        //              b.Text = "Test";
+        //              b.TabIndex = 0;
+        //              b.Location = new Point(400, 525);
+        //              this.MyEvent += new EventHandler(this.b_Click);
+        //          }
+        //          
+        //          [System.CLSCompliantAttribute(false)]
+        //          protected event System.EventHandler MyEvent;
+        //          
+        //          private void b_Click(object sender, System.EventArgs e) {
+        //          }
+        //      }
+        //  }
+        //  namespace FourthNamespace {
+        //      using System;
+        //      using System.Drawing;
+        //      using System.Windows.Forms;
+        //      using System.ComponentModel;
+        //      
+        //      
+        //      public class Test : Form {
+        //          
+        //          private Button b = new Button();
+        //          
+        //          public Test() {
+        //              this.Size = new Size(600, 600);
+        //              b.Text = "Test";
+        //              b.TabIndex = 0;
+        //              b.Location = new Point(400, 525);
+        //              this.MyEvent += new EventHandler(this.b_Click);
+        //          }
+        //          
+        //          /*FamANDAssem*/ internal event System.EventHandler MyEvent;
+        //          
+        //          private void b_Click(object sender, System.EventArgs e) {
+        //          }
+        //      }
+        //  }
+
+        if (Supports (provider, GeneratorSupport.DeclareEvents)) {
+            // *********************************
+            // public
+            CodeNamespace ns = new CodeNamespace ();
+            ns.Name = "MyNamespace";
+            ns.Imports.Add (new CodeNamespaceImport ("System"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.Drawing"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.ComponentModel"));
+            cu.Namespaces.Add (ns);
+
+            cu.ReferencedAssemblies.Add ("System.Drawing.dll");
+            cu.ReferencedAssemblies.Add ("System.Windows.Forms.dll");
+
+            // Assembly Attributes
+            if (Supports (provider, GeneratorSupport.AssemblyAttributes)) {
+                CodeAttributeDeclarationCollection attrs = cu.AssemblyCustomAttributes;
+                attrs.Add (new CodeAttributeDeclaration ("System.CLSCompliantAttribute", new
+                    CodeAttributeArgument (new CodePrimitiveExpression (false))));
+            }
+
+            CodeTypeDeclaration class1 = new CodeTypeDeclaration ("Test");
+            class1.IsClass = true;
+            class1.BaseTypes.Add (new CodeTypeReference ("Form"));
+            ns.Types.Add (class1);
+
+            CodeMemberField mfield = new CodeMemberField (new CodeTypeReference ("Button"), "b");
+            mfield.InitExpression = new CodeObjectCreateExpression (new CodeTypeReference ("Button"));
+            class1.Members.Add (mfield);
+
+            CodeConstructor ctor = new CodeConstructor ();
+            ctor.Attributes = MemberAttributes.Public;
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (),
+                "Size"), new CodeObjectCreateExpression (new CodeTypeReference ("Size"),
+                new CodePrimitiveExpression (600), new CodePrimitiveExpression (600))));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Text"), new CodePrimitiveExpression ("Test")));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "TabIndex"), new CodePrimitiveExpression (0)));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Location"), new CodeObjectCreateExpression (new CodeTypeReference ("Point"),
+                new CodePrimitiveExpression (400), new CodePrimitiveExpression (525))));
+            ctor.Statements.Add (new CodeAttachEventStatement (new CodeEventReferenceExpression (new
+                CodeThisReferenceExpression (), "MyEvent"), new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler")
+                , new CodeThisReferenceExpression (), "b_Click")));
+            ctor.Statements.Add (new CodeRemoveEventStatement (new CodeEventReferenceExpression (new
+                CodeThisReferenceExpression (), "MyEvent"), new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler")
+                , new CodeThisReferenceExpression (), "b_Click")));
+            class1.Members.Add (ctor);
+
+            CodeMemberEvent evt = new CodeMemberEvent ();
+            evt.Name = "MyEvent";
+            evt.Type = new CodeTypeReference ("System.EventHandler");
+            evt.Attributes = MemberAttributes.Public;
+            evt.CustomAttributes.Add (new CodeAttributeDeclaration ("System.CLSCompliantAttribute", new CodeAttributeArgument (new CodePrimitiveExpression (false))));
+            class1.Members.Add (evt);
+
+            CodeMemberMethod cmm = new CodeMemberMethod ();
+            cmm.Name = "b_Click";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (object), "sender"));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (EventArgs), "e"));
+            class1.Members.Add (cmm);
+
+            // *********************************
+            // private
+            ns = new CodeNamespace ();
+            ns.Name = "SecondNamespace";
+            ns.Imports.Add (new CodeNamespaceImport ("System"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.Drawing"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.ComponentModel"));
+            cu.Namespaces.Add (ns);
+
+            class1 = new CodeTypeDeclaration ("Test");
+            class1.IsClass = true;
+            class1.BaseTypes.Add (new CodeTypeReference ("Form"));
+            ns.Types.Add (class1);
+
+            mfield = new CodeMemberField (new CodeTypeReference ("Button"), "b");
+            mfield.InitExpression = new CodeObjectCreateExpression (new CodeTypeReference ("Button"));
+            class1.Members.Add (mfield);
+
+            ctor = new CodeConstructor ();
+            ctor.Attributes = MemberAttributes.Public;
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (),
+                "Size"), new CodeObjectCreateExpression (new CodeTypeReference ("Size"),
+                new CodePrimitiveExpression (600), new CodePrimitiveExpression (600))));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Text"), new CodePrimitiveExpression ("Test")));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "TabIndex"), new CodePrimitiveExpression (0)));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Location"), new CodeObjectCreateExpression (new CodeTypeReference ("Point"),
+                new CodePrimitiveExpression (400), new CodePrimitiveExpression (525))));
+
+            CodeAttachEventStatement addevt = new CodeAttachEventStatement (new CodeThisReferenceExpression (),
+                    "MyEvent", new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler")
+                , new CodeThisReferenceExpression (), "b_Click"));
+
+            ctor.Statements.Add (addevt);
+
+            // remove event statement 
+            CodeRemoveEventStatement rem = new CodeRemoveEventStatement (new CodeThisReferenceExpression (), "MyEvent",
+                        new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler"),
+                            new CodeThisReferenceExpression (), "b_Click"));
+            ctor.Statements.Add (rem);
+
+
+            class1.Members.Add (ctor);
+
+            evt = new CodeMemberEvent ();
+            evt.Name = "MyEvent";
+            evt.Type = new CodeTypeReference ("System.EventHandler");
+            evt.Attributes = MemberAttributes.Private;
+            class1.Members.Add (evt);
+
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "b_Click";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (object), "sender"));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (EventArgs), "e"));
+            class1.Members.Add (cmm);
+
+            // *********************************
+            // protected
+            ns = new CodeNamespace ();
+            ns.Name = "ThirdNamespace";
+            ns.Imports.Add (new CodeNamespaceImport ("System"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.Drawing"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.ComponentModel"));
+            cu.Namespaces.Add (ns);
+
+            class1 = new CodeTypeDeclaration ("Test");
+            class1.IsClass = true;
+            class1.BaseTypes.Add (new CodeTypeReference ("Form"));
+            ns.Types.Add (class1);
+
+            mfield = new CodeMemberField (new CodeTypeReference ("Button"), "b");
+            mfield.InitExpression = new CodeObjectCreateExpression (new CodeTypeReference ("Button"));
+            class1.Members.Add (mfield);
+
+            ctor = new CodeConstructor ();
+            ctor.Attributes = MemberAttributes.Public;
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (),
+                "Size"), new CodeObjectCreateExpression (new CodeTypeReference ("Size"),
+                new CodePrimitiveExpression (600), new CodePrimitiveExpression (600))));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Text"), new CodePrimitiveExpression ("Test")));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "TabIndex"), new CodePrimitiveExpression (0)));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Location"), new CodeObjectCreateExpression (new CodeTypeReference ("Point"),
+                new CodePrimitiveExpression (400), new CodePrimitiveExpression (525))));
+
+            addevt = new CodeAttachEventStatement ();
+            addevt.Event = new CodeEventReferenceExpression (new CodeThisReferenceExpression (), "MyEvent");
+            addevt.Listener = new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler"),
+                    new CodeThisReferenceExpression (), "b_Click");
+            ctor.Statements.Add (addevt);
+
+            // remove event
+            rem = new CodeRemoveEventStatement ();
+            rem.Event = new CodeEventReferenceExpression (new CodeThisReferenceExpression (), "MyEvent");
+            rem.Listener = new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler"),
+                    new CodeThisReferenceExpression (), "b_Click");
+            ctor.Statements.Add (rem);
+
+            class1.Members.Add (ctor);
+
+            evt = new CodeMemberEvent ();
+            evt.Name = "MyEvent";
+            evt.Type = new CodeTypeReference ("System.EventHandler");
+            evt.Attributes = MemberAttributes.Family;
+            evt.CustomAttributes.Add (new CodeAttributeDeclaration ("System.CLSCompliantAttribute", new CodeAttributeArgument (new CodePrimitiveExpression (false))));
+            class1.Members.Add (evt);
+
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "b_Click";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (object), "sender"));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (EventArgs), "e"));
+            class1.Members.Add (cmm);
+
+            // *********************************
+            // internal
+            ns = new CodeNamespace ();
+            ns.Name = "FourthNamespace";
+            ns.Imports.Add (new CodeNamespaceImport ("System"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.Drawing"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.ComponentModel"));
+            cu.Namespaces.Add (ns);
+
+            class1 = new CodeTypeDeclaration ("Test");
+            class1.IsClass = true;
+            class1.BaseTypes.Add (new CodeTypeReference ("Form"));
+            ns.Types.Add (class1);
+
+            mfield = new CodeMemberField (new CodeTypeReference ("Button"), "b");
+            mfield.InitExpression = new CodeObjectCreateExpression (new CodeTypeReference ("Button"));
+            class1.Members.Add (mfield);
+
+            ctor = new CodeConstructor ();
+            ctor.Attributes = MemberAttributes.Public;
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (),
+                "Size"), new CodeObjectCreateExpression (new CodeTypeReference ("Size"),
+                new CodePrimitiveExpression (600), new CodePrimitiveExpression (600))));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Text"), new CodePrimitiveExpression ("Test")));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "TabIndex"), new CodePrimitiveExpression (0)));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Location"), new CodeObjectCreateExpression (new CodeTypeReference ("Point"),
+                new CodePrimitiveExpression (400), new CodePrimitiveExpression (525))));
+            ctor.Statements.Add (new CodeAttachEventStatement (new CodeEventReferenceExpression (new
+                CodeThisReferenceExpression (), "MyEvent"), new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler")
+                , new CodeThisReferenceExpression (), "b_Click")));
+            class1.Members.Add (ctor);
+
+            evt = new CodeMemberEvent ();
+            evt.Name = "MyEvent";
+            evt.Type = new CodeTypeReference ("System.EventHandler");
+            evt.Attributes = MemberAttributes.FamilyAndAssembly;
+            class1.Members.Add (evt);
+
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "b_Click";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (object), "sender"));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (EventArgs), "e"));
+            class1.Members.Add (cmm);
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        // compile only
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/generatorsupportstest.cs b/workyard/tests/codedom/tests/generatorsupportstest.cs
new file mode 100755
index 0000000..6beac22
--- /dev/null
+++ b/workyard/tests/codedom/tests/generatorsupportstest.cs
@@ -0,0 +1,750 @@
+// F#: don't test structs - this is covered by other tests
+
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using System.Xml;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.VisualBasic;
+
+public class GeneratorSupportsTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "GeneratorSupportsTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests GeneratorSupport enumeration.";
+        }
+    }
+
+    public override CompilerParameters GetCompilerParameters (CodeDomProvider provider) {
+        CompilerParameters parms = base.GetCompilerParameters (provider);
+
+        // some languages don't compile correctly if no executable is
+        // generated and an entry point is defined
+        if (Supports (provider, GeneratorSupport.EntryPointMethod)) {
+            parms.GenerateExecutable = true;
+        }
+        return parms;
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu)
+    {
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        nspace.Imports.Add (new CodeNamespaceImport ("System"));
+        nspace.Imports.Add (new CodeNamespaceImport ("System.Drawing"));
+        nspace.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+        nspace.Imports.Add (new CodeNamespaceImport ("System.ComponentModel"));
+        cu.Namespaces.Add (nspace);
+
+        cu.ReferencedAssemblies.Add ("System.Drawing.dll");
+        cu.ReferencedAssemblies.Add ("System.Windows.Forms.dll");
+        cu.ReferencedAssemblies.Add ("System.Xml.dll");
+
+        CodeTypeDeclaration cd = new CodeTypeDeclaration ("TEST");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        CodeMemberMethod cmm;
+
+        // Arrays of Arrays
+#if !WHIDBEY
+        // Everett VB code provider doesn't support array of array initialization
+        if (!(provider is Microsoft.VisualBasic.VBCodeProvider)) {
+#endif
+            if (Supports (provider, GeneratorSupport.ArraysOfArrays)) {
+                AddScenario ("CheckArrayOfArrays");
+                cmm = new CodeMemberMethod ();
+                cmm.Name = "ArraysOfArrays";
+                cmm.ReturnType = new CodeTypeReference (typeof (int));
+                cmm.Attributes = MemberAttributes.Final | MemberAttributes.Public;
+                cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int[][])),
+                    "arrayOfArrays", new CodeArrayCreateExpression (typeof (int[][]),
+                    new CodeArrayCreateExpression (typeof (int[]), new CodePrimitiveExpression (3), new CodePrimitiveExpression (4)),
+                    new CodeArrayCreateExpression (typeof (int[]), new CodeExpression[] {new CodePrimitiveExpression (1)}))));
+                cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArrayIndexerExpression (
+                    new CodeArrayIndexerExpression (new CodeVariableReferenceExpression ("arrayOfArrays"), new CodePrimitiveExpression (0)),
+                    new CodePrimitiveExpression (1))));
+                cd.Members.Add (cmm);
+            }
+#if !WHIDBEY
+        }
+#endif
+
+        // assembly attributes
+        if (Supports (provider, GeneratorSupport.AssemblyAttributes)) {
+            AddScenario ("CheckAssemblyAttributes");
+            CodeAttributeDeclarationCollection attrs = cu.AssemblyCustomAttributes;
+            attrs.Add (new CodeAttributeDeclaration ("System.Reflection.AssemblyTitle", new
+                CodeAttributeArgument (new CodePrimitiveExpression ("MyAssembly"))));
+            attrs.Add (new CodeAttributeDeclaration ("System.Reflection.AssemblyVersion", new
+                CodeAttributeArgument (new CodePrimitiveExpression ("1.0.6.2"))));
+        }
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        if (Supports (provider, GeneratorSupport.ChainedConstructorArguments)) {
+            AddScenario ("CheckChainedConstructorArgs");
+            class1.Name = "Test2";
+            class1.IsClass = true;
+            nspace.Types.Add (class1);
+
+            class1.Members.Add (new CodeMemberField (new CodeTypeReference (typeof (String)), "stringField"));
+            CodeMemberProperty prop = new CodeMemberProperty ();
+            prop.Name = "accessStringField";
+            prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            prop.Type = new CodeTypeReference (typeof (String));
+            prop.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (),
+                "stringField")));
+            prop.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new
+                CodeThisReferenceExpression (), "stringField"),
+                new CodePropertySetValueReferenceExpression ()));
+            class1.Members.Add (prop);
+
+            CodeConstructor cctor = new CodeConstructor ();
+            cctor.Attributes = MemberAttributes.Public;
+            cctor.ChainedConstructorArgs.Add (new CodePrimitiveExpression ("testingString"));
+            cctor.ChainedConstructorArgs.Add (new CodePrimitiveExpression (null));
+            cctor.ChainedConstructorArgs.Add (new CodePrimitiveExpression (null));
+            class1.Members.Add (cctor);
+
+            CodeConstructor cc = new CodeConstructor ();
+            cc.Attributes = MemberAttributes.Public | MemberAttributes.Overloaded;
+            cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof (string), "p1"));
+            cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof (string), "p2"));
+            cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof (string), "p3"));
+            cc.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression ()
+                , "stringField"), new CodeArgumentReferenceExpression ("p1")));
+            class1.Members.Add (cc);
+
+            // verify chained constructors work
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "ChainedConstructorUse";
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            cmm.ReturnType = new CodeTypeReference (typeof (String));
+            // utilize constructor
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("Test2", "t", new CodeObjectCreateExpression ("Test2")));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (
+                new CodeVariableReferenceExpression ("t"), "accessStringField")));
+            cd.Members.Add (cmm);
+        }
+
+        // complex expressions
+        if (Supports (provider, GeneratorSupport.ComplexExpressions)) {
+            AddScenario ("CheckComplexExpressions");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "ComplexExpressions";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Final | MemberAttributes.Public;
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("i"),
+                new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.Multiply,
+                new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.Add,
+                new CodePrimitiveExpression (3)))));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("i")));
+            cd.Members.Add (cmm);
+        }
+
+        if (Supports (provider, GeneratorSupport.DeclareEnums)) {
+            AddScenario ("CheckDeclareEnums");
+            CodeTypeDeclaration ce = new CodeTypeDeclaration ("DecimalEnum");
+            ce.IsEnum = true;
+            nspace.Types.Add (ce);
+
+            // things to enumerate
+            for (int k = 0; k < 5; k++)
+            {
+                CodeMemberField Field = new CodeMemberField ("System.Int32", "Num" + (k).ToString ());
+                Field.InitExpression = new CodePrimitiveExpression (k);
+                ce.Members.Add (Field);
+            }
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "OutputDecimalEnumVal";
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            cmm.Parameters.Add (param);
+            CodeBinaryOperatorExpression eq       = new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.ValueEquality,
+                new CodePrimitiveExpression (3));
+            CodeMethodReturnStatement    truestmt = new CodeMethodReturnStatement (
+                new CodeCastExpression (typeof (int),
+                new CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("DecimalEnum"), "Num3")));
+            CodeConditionStatement       condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (4));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("DecimalEnum"), "Num4")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (2));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("DecimalEnum"), "Num2")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (1));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("DecimalEnum"), "Num1")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            eq = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (0));
+            truestmt = new CodeMethodReturnStatement (new CodeCastExpression (typeof (int), new
+                CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("DecimalEnum"), "Num0")));
+            condstmt = new CodeConditionStatement (eq, truestmt);
+            cmm.Statements.Add (condstmt);
+
+            cmm.ReturnType = new CodeTypeReference ("System.Int32");
+
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression (10))));
+            cd.Members.Add (cmm);
+        }
+
+        if (Supports (provider, GeneratorSupport.DeclareInterfaces)) {
+            AddScenario ("CheckDeclareInterfaces");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "TestSingleInterface";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("TestSingleInterfaceImp", "t", new CodeObjectCreateExpression ("TestSingleInterfaceImp")));
+            CodeMethodInvokeExpression methodinvoke = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t")
+                , "InterfaceMethod");
+            methodinvoke.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+            cmm.Statements.Add (new CodeMethodReturnStatement (methodinvoke));
+            cd.Members.Add (cmm);
+
+            class1 = new CodeTypeDeclaration ("InterfaceA");
+            class1.IsInterface = true;
+            nspace.Types.Add (class1);
+            cmm = new CodeMemberMethod ();
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.Name = "InterfaceMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            class1.Members.Add (cmm);
+
+            if (Supports (provider, GeneratorSupport.MultipleInterfaceMembers)) {
+                AddScenario ("CheckMultipleInterfaceMembers");
+                CodeTypeDeclaration classDecl = new CodeTypeDeclaration ("InterfaceB");
+                classDecl.IsInterface = true;
+                nspace.Types.Add (classDecl);
+                cmm = new CodeMemberMethod ();
+                cmm.Name = "InterfaceMethod";
+                cmm.Attributes = MemberAttributes.Public;
+                cmm.ReturnType = new CodeTypeReference (typeof (int));
+                cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+                classDecl.Members.Add (cmm);
+
+                CodeTypeDeclaration class2 = new CodeTypeDeclaration ("TestMultipleInterfaceImp");
+                class2.BaseTypes.Add (new CodeTypeReference ("System.Object"));
+                class2.BaseTypes.Add (new CodeTypeReference ("InterfaceB"));
+                class2.BaseTypes.Add (new CodeTypeReference ("InterfaceA"));
+                class2.IsClass = true;
+                nspace.Types.Add (class2);
+                cmm = new CodeMemberMethod ();
+                cmm.ImplementationTypes.Add (new CodeTypeReference ("InterfaceA"));
+                cmm.ImplementationTypes.Add (new CodeTypeReference ("InterfaceB"));
+                cmm.Name = "InterfaceMethod";
+                cmm.ReturnType = new CodeTypeReference (typeof (int));
+                cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+                cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+                cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+                class2.Members.Add (cmm);
+
+                cmm = new CodeMemberMethod ();
+                cmm.Name = "TestMultipleInterfaces";
+                cmm.ReturnType = new CodeTypeReference (typeof (int));
+                cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+                cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+                cmm.Statements.Add (new CodeVariableDeclarationStatement ("TestMultipleInterfaceImp", "t", new CodeObjectCreateExpression ("TestMultipleInterfaceImp")));
+                cmm.Statements.Add (new CodeVariableDeclarationStatement ("InterfaceA", "interfaceAobject", new CodeCastExpression ("InterfaceA",
+                    new CodeVariableReferenceExpression ("t"))));
+                cmm.Statements.Add (new CodeVariableDeclarationStatement ("InterfaceB", "interfaceBobject", new CodeCastExpression ("InterfaceB",
+                    new CodeVariableReferenceExpression ("t"))));
+                methodinvoke = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("interfaceAobject")
+                    , "InterfaceMethod");
+                methodinvoke.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+                CodeMethodInvokeExpression methodinvoke2 = new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("interfaceBobject")
+                    , "InterfaceMethod");
+                methodinvoke2.Parameters.Add (new CodeArgumentReferenceExpression ("i"));
+                cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+                    methodinvoke,
+                    CodeBinaryOperatorType.Subtract, methodinvoke2)));
+                cd.Members.Add (cmm);
+            }
+
+            class1 = new CodeTypeDeclaration ("TestSingleInterfaceImp");
+            class1.BaseTypes.Add (new CodeTypeReference ("System.Object"));
+            class1.BaseTypes.Add (new CodeTypeReference ("InterfaceA"));
+            class1.IsClass = true;
+            nspace.Types.Add (class1);
+            cmm = new CodeMemberMethod ();
+            cmm.ImplementationTypes.Add (new CodeTypeReference ("InterfaceA"));
+            cmm.Name = "InterfaceMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cmm.Attributes = MemberAttributes.Public;
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            class1.Members.Add (cmm);
+        }
+
+        /*if (Supports (provider, GeneratorSupport.DeclareValueTypes)) {
+            AddScenario ("CheckDeclareValueTypes");
+
+            // create first struct to test nested structs
+            //     GENERATE (C#):
+            //	public struct structA {
+            //		public structB innerStruct;
+            //		public struct structB {
+            //    		public int int1;
+            //		}
+            //	}
+            CodeTypeDeclaration structA = new CodeTypeDeclaration ("structA");
+            structA.IsStruct = true;
+
+            CodeTypeDeclaration structB = new CodeTypeDeclaration ("structB");
+            structB.TypeAttributes = TypeAttributes.NestedPublic;
+            structB.Attributes = MemberAttributes.Public;
+            structB.IsStruct = true;
+
+            CodeMemberField firstInt = new CodeMemberField (typeof (int), "int1");
+            firstInt.Attributes = MemberAttributes.Public;
+            structB.Members.Add (firstInt);
+
+            CodeMemberField innerStruct = new CodeMemberField ("structB", "innerStruct");
+            innerStruct.Attributes = MemberAttributes.Public;
+
+            structA.Members.Add (structB);
+            structA.Members.Add (innerStruct);
+            nspace.Types.Add (structA);
+
+            CodeMemberMethod nestedStructMethod = new CodeMemberMethod ();
+            nestedStructMethod.Name = "NestedStructMethod";
+            nestedStructMethod.ReturnType = new CodeTypeReference (typeof (int));
+            nestedStructMethod.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            CodeVariableDeclarationStatement varStructA = new CodeVariableDeclarationStatement ("structA", "varStructA");
+            nestedStructMethod.Statements.Add (varStructA);
+            nestedStructMethod.Statements.Add
+                (
+                new CodeAssignStatement
+                (
+									new CodeFieldReferenceExpression (new CodeFieldReferenceExpression (new CodeVariableReferenceExpression ("varStructA"), "innerStruct"), "int1"),
+									new CodePrimitiveExpression (3)
+                )
+                );
+            nestedStructMethod.Statements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeFieldReferenceExpression (new CodeVariableReferenceExpression ("varStructA"), "innerStruct"), "int1")));
+            cd.Members.Add (nestedStructMethod);
+        }*/
+        if (Supports (provider, GeneratorSupport.EntryPointMethod)) {
+            AddScenario ("CheckEntryPointMethod");
+            CodeEntryPointMethod cep = new CodeEntryPointMethod ();
+            cd.Members.Add (cep);
+        }
+        // goto statements
+        if (Supports (provider, GeneratorSupport.GotoStatements)) {
+            AddScenario ("CheckGotoStatements");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "GoToMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            cmm.Parameters.Add (param);
+            CodeConditionStatement condstmt = new CodeConditionStatement (new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.LessThan, new CodePrimitiveExpression (1)),
+                new CodeGotoStatement ("comehere"));
+            cmm.Statements.Add (condstmt);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (6)));
+            cmm.Statements.Add (new CodeLabeledStatement ("comehere",
+                new CodeMethodReturnStatement (new CodePrimitiveExpression (7))));
+            cd.Members.Add (cmm);
+        }
+        if (Supports (provider, GeneratorSupport.NestedTypes)) {
+            AddScenario ("CheckNestedTypes");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "CallingPublicNestedScenario";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference
+                ("PublicNestedClassA+PublicNestedClassB2+PublicNestedClassC"), "t",
+                new CodeObjectCreateExpression (new CodeTypeReference
+                ("PublicNestedClassA+PublicNestedClassB2+PublicNestedClassC"))));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("t"),
+                "publicNestedClassesMethod",
+                new CodeArgumentReferenceExpression ("i"))));
+            cd.Members.Add (cmm);
+
+            class1 = new CodeTypeDeclaration ("PublicNestedClassA");
+            class1.IsClass = true;
+            nspace.Types.Add (class1);
+            CodeTypeDeclaration nestedClass = new CodeTypeDeclaration ("PublicNestedClassB1");
+            nestedClass.IsClass = true;
+            nestedClass.TypeAttributes = TypeAttributes.NestedPublic;
+            class1.Members.Add (nestedClass);
+            nestedClass = new CodeTypeDeclaration ("PublicNestedClassB2");
+            nestedClass.TypeAttributes = TypeAttributes.NestedPublic;
+            nestedClass.IsClass = true;
+            class1.Members.Add (nestedClass);
+            CodeTypeDeclaration innerNestedClass = new CodeTypeDeclaration ("PublicNestedClassC");
+            innerNestedClass.TypeAttributes = TypeAttributes.NestedPublic;
+            innerNestedClass.IsClass = true;
+            nestedClass.Members.Add (innerNestedClass);
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "publicNestedClassesMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "a"));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            innerNestedClass.Members.Add (cmm);
+        }
+        // Parameter Attributes
+        if (Supports (provider, GeneratorSupport.ParameterAttributes)) {
+            AddScenario ("CheckParameterAttributes");
+            CodeMemberMethod method1 = new CodeMemberMethod ();
+            method1.Name = "MyMethod";
+            method1.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            CodeParameterDeclarationExpression param1 = new CodeParameterDeclarationExpression (typeof (string), "blah");
+            param1.CustomAttributes.Add (
+                new CodeAttributeDeclaration (
+                "System.Xml.Serialization.XmlElementAttribute",
+                new CodeAttributeArgument (
+                "Form",
+                new CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("System.Xml.Schema.XmlSchemaForm"), "Unqualified")),
+                new CodeAttributeArgument (
+                "IsNullable",
+                new CodePrimitiveExpression (false))));
+            method1.Parameters.Add (param1);
+            cd.Members.Add (method1);
+        }
+        // public static members
+        if (Supports (provider, GeneratorSupport.PublicStaticMembers)) {
+            AddScenario ("CheckPublicStaticMembers");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "PublicStaticMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (16)));
+            cd.Members.Add (cmm);
+        }
+        // reference parameters
+        if (Supports (provider, GeneratorSupport.ReferenceParameters)) {
+            AddScenario ("CheckReferenceParameters");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "Work";
+            cmm.ReturnType = new CodeTypeReference ("System.void");
+            cmm.Attributes = MemberAttributes.Static;
+            // add parameter with ref direction
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            param.Direction = FieldDirection.Ref;
+            cmm.Parameters.Add (param);
+            // add parameter with out direction
+            param = new CodeParameterDeclarationExpression (typeof (int), "j");
+            param.Direction = FieldDirection.Out;
+            cmm.Parameters.Add (param);
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("i"),
+                new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.Add, new CodePrimitiveExpression (4))));
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("j"),
+                new CodePrimitiveExpression (5)));
+            cd.Members.Add (cmm);
+
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "CallingWork";
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            CodeParameterDeclarationExpression parames = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (parames);
+            cmm.ReturnType = new CodeTypeReference ("System.Int32");
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"),
+                new CodePrimitiveExpression (10)));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "b"));
+            // invoke the method called "work"
+            CodeMethodInvokeExpression methodinvoked = new CodeMethodInvokeExpression (new CodeMethodReferenceExpression
+                (new CodeTypeReferenceExpression ("TEST"), "Work"));
+            // add parameter with ref direction
+            CodeDirectionExpression parameter = new CodeDirectionExpression (FieldDirection.Ref,
+                new CodeArgumentReferenceExpression ("a"));
+            methodinvoked.Parameters.Add (parameter);
+            // add parameter with out direction
+            parameter = new CodeDirectionExpression (FieldDirection.Out, new CodeVariableReferenceExpression ("b"));
+            methodinvoked.Parameters.Add (parameter);
+            cmm.Statements.Add (methodinvoked);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression
+                (new CodeArgumentReferenceExpression ("a"), CodeBinaryOperatorType.Add, new CodeVariableReferenceExpression ("b"))));
+            cd.Members.Add (cmm);
+        }
+        if (Supports (provider, GeneratorSupport.ReturnTypeAttributes)) {
+            AddScenario ("CheckReturnTypeAttributes");
+            CodeMemberMethod function1 = new CodeMemberMethod ();
+            function1.Name = "MyFunction";
+            function1.ReturnType = new CodeTypeReference (typeof (string));
+            function1.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            function1.ReturnTypeCustomAttributes.Add (new
+                CodeAttributeDeclaration ("System.Xml.Serialization.XmlIgnoreAttribute"));
+            function1.ReturnTypeCustomAttributes.Add (new CodeAttributeDeclaration ("System.Xml.Serialization.XmlRootAttribute", new
+                CodeAttributeArgument ("Namespace", new CodePrimitiveExpression ("Namespace Value")), new
+                CodeAttributeArgument ("ElementName", new CodePrimitiveExpression ("Root, hehehe"))));
+            function1.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression ("Return")));
+            cd.Members.Add (function1);
+        }
+        if (Supports (provider, GeneratorSupport.StaticConstructors)) {
+            AddScenario ("CheckStaticConstructors");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "TestStaticConstructor";
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (param);
+            // utilize constructor
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("Test4", "t", new CodeObjectCreateExpression ("Test4")));
+            // set then get number
+            cmm.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeVariableReferenceExpression ("t"), "i")
+                , new CodeArgumentReferenceExpression ("a")));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (
+                new CodeVariableReferenceExpression ("t"), "i")));
+            cd.Members.Add (cmm);
+
+            class1 = new CodeTypeDeclaration ();
+            class1.Name = "Test4";
+            class1.IsClass = true;
+            nspace.Types.Add (class1);
+
+            class1.Members.Add (new CodeMemberField (new CodeTypeReference (typeof (int)), "number"));
+            CodeMemberProperty prop = new CodeMemberProperty ();
+            prop.Name = "i";
+            prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            prop.Type = new CodeTypeReference (typeof (int));
+            prop.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (null, "number")));
+            prop.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "number"),
+                new CodePropertySetValueReferenceExpression ()));
+            class1.Members.Add (prop);
+            CodeTypeConstructor ctc = new CodeTypeConstructor ();
+            class1.Members.Add (ctc);
+        }
+        if (Supports (provider, GeneratorSupport.TryCatchStatements)) {
+            AddScenario ("CheckTryCatchStatements");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "TryCatchMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (param);
+
+            CodeTryCatchFinallyStatement tcfstmt = new CodeTryCatchFinallyStatement ();
+            tcfstmt.FinallyStatements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"), new
+                CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("a"), CodeBinaryOperatorType.Add,
+                new CodePrimitiveExpression (5))));
+            cmm.Statements.Add (tcfstmt);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            cd.Members.Add (cmm);
+        }
+        if (Supports (provider, GeneratorSupport.DeclareEvents)) {
+            AddScenario ("CheckDeclareEvents");
+            CodeNamespace ns = new CodeNamespace ();
+            ns.Name = "MyNamespace";
+            ns.Imports.Add (new CodeNamespaceImport ("System"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.Drawing"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+            ns.Imports.Add (new CodeNamespaceImport ("System.ComponentModel"));
+            cu.Namespaces.Add (ns);
+            class1 = new CodeTypeDeclaration ("Test");
+            class1.IsClass = true;
+            class1.BaseTypes.Add (new CodeTypeReference ("Form"));
+            ns.Types.Add (class1);
+
+            CodeMemberField mfield = new CodeMemberField (new CodeTypeReference ("Button"), "b");
+            mfield.InitExpression = new CodeObjectCreateExpression (new CodeTypeReference ("Button"));
+            class1.Members.Add (mfield);
+
+            CodeConstructor ctor = new CodeConstructor ();
+            ctor.Attributes = MemberAttributes.Public;
+            ctor.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (),
+                "Size"), new CodeObjectCreateExpression (new CodeTypeReference ("Size"),
+                new CodePrimitiveExpression (600), new CodePrimitiveExpression (600))));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Text"), new CodePrimitiveExpression ("Test")));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "TabIndex"), new CodePrimitiveExpression (0)));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Location"), new CodeObjectCreateExpression (new CodeTypeReference ("Point"),
+                new CodePrimitiveExpression (400), new CodePrimitiveExpression (525))));
+            ctor.Statements.Add (new CodeAttachEventStatement (new CodeEventReferenceExpression (new
+                CodeThisReferenceExpression (), "MyEvent"), new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler")
+                , new CodeThisReferenceExpression (), "b_Click")));
+            class1.Members.Add (ctor);
+
+            CodeMemberEvent evt = new CodeMemberEvent ();
+            evt.Name = "MyEvent";
+            evt.Type = new CodeTypeReference ("System.EventHandler");
+            evt.Attributes = MemberAttributes.Public;
+            class1.Members.Add (evt);
+
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "b_Click";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (object), "sender"));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (EventArgs), "e"));
+            class1.Members.Add (cmm);
+        }
+        if (Supports (provider, GeneratorSupport.MultidimensionalArrays)) {
+            // no codedom language represents declaration of multidimensional arrays
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        // if we get to this point, Entry point method and Event declaration
+        // have been successfully compiled so
+        if (Supports (provider, GeneratorSupport.EntryPointMethod))
+            VerifyScenario ("CheckEntryPointMethod");
+        if (Supports (provider, GeneratorSupport.DeclareEvents))
+            VerifyScenario ("CheckDeclareEvents");
+
+        // Verifying Assembly Attributes
+        if (Supports (provider, GeneratorSupport.AssemblyAttributes)) {
+            object[] attributes = asm.GetCustomAttributes (true);
+            bool verified = VerifyAttribute (attributes, typeof (AssemblyTitleAttribute), "Title", "MyAssembly");
+            verified &= VerifyAttribute (attributes, typeof (AssemblyVersionAttribute), "Version", "1.0.6.2") ||
+                asm.GetName ().Version.Equals (new Version (1, 0, 6, 2));
+            if (verified)
+                VerifyScenario ("CheckAssemblyAttributes");
+        }
+
+        AddScenario ("InstantiateTEST", "Find and instantiate TEST.");
+        if (!FindAndInstantiate ("NSPC.TEST", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTEST");
+
+        // verify arrays of arrays
+#if !WHIDBEY
+        if (!(provider is VBCodeProvider)) {
+#endif
+            if (Supports (provider, GeneratorSupport.ArraysOfArrays) &&
+                    VerifyMethod (genType, genObject, "ArraysOfArrays", new object[] {}, 4)) {
+                VerifyScenario ("CheckArrayOfArrays");
+            }
+#if !WHIDBEY
+        }
+#endif
+
+        // verify chained constructors
+        if (Supports (provider, GeneratorSupport.ChainedConstructorArguments) &&
+                VerifyMethod (genType, genObject, "ChainedConstructorUse", new object[] {}, "testingString")) {
+            VerifyScenario ("CheckChainedConstructorArgs");
+        }
+        // verify complex expressions
+        if (Supports (provider, GeneratorSupport.ComplexExpressions) &&
+                VerifyMethod (genType, genObject, "ComplexExpressions", new object[] {8}, 88)) {
+            VerifyScenario ("CheckComplexExpressions");
+        }
+        // verify enumerations
+        if (Supports (provider, GeneratorSupport.DeclareEnums) &&
+                VerifyMethod (genType, genObject, "OutputDecimalEnumVal", new object[] {4}, 4)) {
+            VerifyScenario ("CheckDeclareEnums");
+        }
+        // verify interfaces
+        if (Supports (provider, GeneratorSupport.DeclareInterfaces) &&
+                VerifyMethod (genType, genObject, "TestSingleInterface", new object[] {4}, 4)) {
+            VerifyScenario ("CheckDeclareInterfaces");
+        }
+        // verify nested structs
+        /*if (Supports (provider, GeneratorSupport.DeclareValueTypes) &&
+                VerifyMethod (genType, genObject, "NestedStructMethod", new object[] {}, 3)) {
+            VerifyScenario ("CheckDeclareValueTypes");
+        }*/
+        // verify goto
+        if (Supports (provider, GeneratorSupport.GotoStatements) &&
+                VerifyMethod (genType, genObject, "GoToMethod", new object[] {0}, 7) &&
+                VerifyMethod (genType, genObject, "GoToMethod", new object[] {2}, 6)) {
+            VerifyScenario ("CheckGotoStatements");
+        }
+        // multiple interfaces
+        if (Supports (provider, GeneratorSupport.DeclareInterfaces) &&
+                Supports (provider, GeneratorSupport.MultipleInterfaceMembers) &&
+                VerifyMethod (genType, genObject, "TestMultipleInterfaces", new object[] {6}, 0)) {
+            VerifyScenario ("CheckMultipleInterfaceMembers");
+        }
+        // nested types
+        if (Supports (provider, GeneratorSupport.NestedTypes) &&
+                VerifyMethod (genType, genObject, "CallingPublicNestedScenario", new object[] {7}, 7)) {
+            VerifyScenario ("CheckNestedTypes");
+        }
+        // parameter attributes
+        MethodInfo methodInfo;
+        if (Supports (provider, GeneratorSupport.ParameterAttributes)) {
+            methodInfo = genType.GetMethod ("MyMethod");
+            ParameterInfo[] paramInfo = methodInfo.GetParameters ();
+
+            object[] paramAttributes = paramInfo[0].GetCustomAttributes (typeof (System.Xml.Serialization.XmlElementAttribute), true);
+            if (paramAttributes.GetLength (0) == 1) {
+                VerifyScenario ("CheckParameterAttributes");
+            }
+        }
+        // public static members
+        if (Supports (provider, GeneratorSupport.PublicStaticMembers) &&
+                VerifyMethod (genType, genObject, "PublicStaticMethod", new object[] {}, 16)) {
+            VerifyScenario ("CheckPublicStaticMembers");
+        }
+        // reference parameters
+        if (Supports (provider, GeneratorSupport.ReferenceParameters) &&
+                VerifyMethod (genType, genObject, "CallingWork", new object[] {5}, 19)) {
+            VerifyScenario ("CheckReferenceParameters");
+        }
+        // return type attributes
+        if (Supports (provider, GeneratorSupport.ReturnTypeAttributes)) {
+            methodInfo = genType.GetMethod ("MyFunction");
+            ICustomAttributeProvider returnTypeAttributes = methodInfo.ReturnTypeCustomAttributes;
+            if (returnTypeAttributes.IsDefined (typeof (System.Xml.Serialization.XmlRootAttribute), true) &&
+                returnTypeAttributes.IsDefined (typeof (System.Xml.Serialization.XmlIgnoreAttribute), true)) {
+                VerifyScenario ("CheckReturnTypeAttributes");
+            }
+        }
+        // static constructors
+        if (Supports (provider, GeneratorSupport.StaticConstructors) &&
+                VerifyMethod (genType, genObject, "TestStaticConstructor", new object[] {7}, 7)) {
+            VerifyScenario ("CheckStaticConstructors");
+        }
+        // try catch statements
+        if (Supports (provider, GeneratorSupport.TryCatchStatements) &&
+                VerifyMethod (genType, genObject, "TryCatchMethod", new object[] {1}, 6) &&
+                VerifyMethod (genType, genObject, "TryCatchMethod", new object[] {10}, 15)) {
+            VerifyScenario ("CheckTryCatchStatements");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/genericstest.cs b/workyard/tests/codedom/tests/genericstest.cs
new file mode 100755
index 0000000..4bad9b9
--- /dev/null
+++ b/workyard/tests/codedom/tests/genericstest.cs
@@ -0,0 +1,210 @@
+// F#: changed multiplication from decimal*int to int*int
+//     unfortunately this fails because the following code doesn't compile 
+//     (type arguments 'k and 'v are restricted to values from use in the 'Test' class)
+//     otherwise it should be correct
+/*
+    #light
+		open System.Collections.Generic
+
+		type MyDictionary<'K, 'V> = 
+			class
+				inherit Dictionary<'K, 'V> as base
+				new() = {}
+			end
+		and Test = 
+			class
+				member this.MyMethod() =
+					let d = new MyDictionary<string, List<string>>()
+					0
+			end
+*/
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Globalization;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class GenericsTest : CodeDomTestTree {
+
+    public override string Comment
+    {
+        get
+        {
+            return "F# doesn't permit Dictionary<_,_>() to be called without an equality constraint";
+        }
+    }
+    public override TestTypes TestType
+    {
+        get {
+            return TestTypes.Whidbey;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "GenericsTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests generating generics from CodeDom.";
+        }
+    }
+
+    public override void BuildTree(CodeDomProvider provider, CodeCompileUnit cu) {
+#if WHIDBEY
+        // GENERATES (C#):
+        //  namespace TestNamespace {
+        //      using System;
+        //      using System.Collections.Generic;
+        //      
+        //      
+        //      public class MyDictionary<K, V> : Dictionary<K, V>
+        //          where K : System.IComparable, IComparable<K>, new ()
+        //          where V : IList<string> {
+        //          
+        //          public virtual int Calculate<S, T>(int value1, int value2)
+        //              where S : new()
+        //           {
+        //              return (value1 * value2);
+        //          }
+        //      }
+        //      
+        //      public class Test {
+        //          
+        //          public virtual int MyMethod() {
+        //              int dReturn;
+        //              MyDictionary<int, List<string>> dict = new MyDictionary<int, List<string>>();
+        //              dReturn = dict.Calculate<int, int>(2.5, 11);
+        //              return dReturn;
+        //          }
+        //      }
+        //  }
+        
+        if (!provider.Supports(GeneratorSupport.GenericTypeReference | GeneratorSupport.GenericTypeDeclaration)) {
+            return;
+        }
+
+        CodeNamespace ns = new CodeNamespace("TestNamespace");
+        ns.Imports.Add(new CodeNamespaceImport("System"));
+        ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
+        cu.Namespaces.Add (ns);
+
+        // Declare a generic class
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration();
+        class1.Name = "MyDictionary";
+        class1.BaseTypes.Add( new CodeTypeReference("Dictionary", 
+                                  new CodeTypeReference[] { new CodeTypeReference("K"), new CodeTypeReference("V"),}));
+
+        CodeTypeParameter kType = new CodeTypeParameter("K");
+        kType.HasConstructorConstraint= true;
+
+        kType.Constraints.Add( new CodeTypeReference(typeof(IComparable)));
+        kType.CustomAttributes.Add(new CodeAttributeDeclaration(
+            "System.ComponentModel.DescriptionAttribute", new CodeAttributeArgument(new CodePrimitiveExpression("KeyType"))));
+
+        CodeTypeReference iComparableT = new CodeTypeReference("IComparable");
+        iComparableT.TypeArguments.Add(new CodeTypeReference(kType));            
+
+        kType.Constraints.Add(iComparableT);
+        
+        CodeTypeParameter vType = new CodeTypeParameter("V");
+        vType.Constraints.Add(new CodeTypeReference("IList[System.String]"));
+
+        class1.TypeParameters.Add(kType);
+        class1.TypeParameters.Add(vType);
+                    
+        ns.Types.Add(class1);
+
+        // declare a generic method
+        CodeMemberMethod method = new CodeMemberMethod();
+        CodeTypeParameter sType = new CodeTypeParameter("S");
+        sType.HasConstructorConstraint = true;
+
+        CodeTypeParameter tType = new CodeTypeParameter("T");
+        sType.HasConstructorConstraint = true;
+
+        method.Name = "Calculate";
+        method.TypeParameters.Add(sType);
+        method.TypeParameters.Add(tType);
+        method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "value1"));
+        method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "value2"));
+        method.ReturnType = new CodeTypeReference(typeof(int));
+
+        method.Statements.Add(new CodeMethodReturnStatement(new CodeBinaryOperatorExpression(new 
+                                 CodeVariableReferenceExpression("value1"), CodeBinaryOperatorType.Multiply, new 
+                                 CodeVariableReferenceExpression("value2"))));
+
+
+        method.Attributes = MemberAttributes.Public;
+        class1.Members.Add(method);
+
+
+        CodeTypeDeclaration class2 = new CodeTypeDeclaration();
+        class2.Name = "Test";
+
+        AddScenario ("CheckMyMethod");
+        CodeMemberMethod method2 =  new CodeMemberMethod();
+        method2.Name = "MyMethod";
+        method2.Attributes = MemberAttributes.Public;
+        method2.ReturnType = new CodeTypeReference(typeof(int));
+        method2.Statements.Add( new CodeVariableDeclarationStatement(typeof(int), "dReturn"));
+
+        CodeTypeReference myClass = new CodeTypeReference( "MyDictionary", 
+                                    new CodeTypeReference[] { new CodeTypeReference(typeof(int)), new CodeTypeReference("List", 
+                                    new CodeTypeReference[] {new CodeTypeReference("System.String") })} ); 
+
+        method2.Statements.Add(  new CodeVariableDeclarationStatement( myClass, "dict", new CodeObjectCreateExpression(myClass) ));
+
+        method2.Statements.Add(new CodeAssignStatement( new CodeVariableReferenceExpression("dReturn"), 
+                               new CodeMethodInvokeExpression(
+                               new CodeMethodReferenceExpression( new CodeVariableReferenceExpression("dict"), "Calculate",
+                               new CodeTypeReference[] {
+                               new CodeTypeReference("System.Int32"),
+                               new CodeTypeReference("System.Int32"),}), 
+                               new CodeExpression[]{new CodePrimitiveExpression(25), new CodePrimitiveExpression(11)})));
+
+        method2.Statements.Add (new CodeMethodReturnStatement(new CodeVariableReferenceExpression("dReturn")));
+        class2.Members.Add(method2);
+        ns.Types.Add(class2);
+#endif
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+#if WHIDBEY
+        if (provider.Supports(GeneratorSupport.GenericTypeReference | GeneratorSupport.GenericTypeDeclaration)) {
+            object genObject;
+            Type   genType;
+
+            AddScenario ("InstantiateTest");
+            if (!FindAndInstantiate ("TestNamespace.Test", asm, out genObject, out genType))
+                return;
+            VerifyScenario ("InstantiateTest");
+
+            // verify scenario with 'new' attribute
+            if (VerifyMethod(genType, genObject, "MyMethod", null, 275)) {
+                VerifyScenario ("CheckMyMethod");
+            }
+        }
+#endif
+    }
+}   
+
diff --git a/workyard/tests/codedom/tests/globalkeywordtest.cs b/workyard/tests/codedom/tests/globalkeywordtest.cs
new file mode 100755
index 0000000..0e68de8
--- /dev/null
+++ b/workyard/tests/codedom/tests/globalkeywordtest.cs
@@ -0,0 +1,219 @@
+using System;
+using System.IO;
+using System.CodeDom;
+using System.Reflection;
+using System.Collections;
+using System.CodeDom.Compiler;
+using System.Collections.Specialized;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.JScript;
+
+public class GlobalKeywordTest : CodeDomTestTree {
+
+		public override TestTypes TestType {
+        get {
+            return TestTypes.Whidbey;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "GlobalKeywordTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Test the global keyword used to differentiate global namespaces from local ones.";
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+        if (!(provider is JScriptCodeProvider)) {
+            // GENERATES (C#):
+            //   namespace Foo {
+            //       public class Foo {
+            //
+            //           public int _verifyGlobalGeneration1 = 2147483647;
+            //
+            //           public int System {
+            //              get { return 42; }
+            //           }
+            //   
+            //           public int Property {
+            //               get { return 2147483647; }
+            //           }
+            //
+            //           public int GlobalTestProperty1 {
+            //               get {
+            //                   return _verifyGlobalGeneration1;
+            //               }
+            //               set {
+            //                   _verifyGlobalGeneration1 = value;
+            //               }
+            //           }
+            //         
+            //           public global::System.Nullable<int> GlobalTestProperty2 {
+            //               get {
+            //                   return _verifyGlobalGeneration2;
+            //               }
+            //               set {
+            //                   _verifyGlobalGeneration2 = value;
+            //               }
+            //           }
+            //           
+            //   
+            //           public int TestMethod02() {
+            //               int iReturn;
+            //               iReturn = global::Foo.Foo.Property;
+            //               return iReturn;
+            //           }
+            //   
+            //           public int TestMethod03() {
+            //               int iReturn;
+            //               iReturn = global::System.Math.Abs(-1);
+            //               return iReturn;
+            //           }
+            //
+            //           public int TestMethod04() {
+            //               int iReturn;
+            //               iReturn = System;
+            //               return iReturn;
+            //       }
+            //   }
+
+            CodeNamespace ns = new CodeNamespace ("Foo");
+            ns.Comments.Add (new CodeCommentStatement ("Foo namespace"));
+
+            cu.Namespaces.Add (ns);
+
+            CodeTypeDeclaration cd = new CodeTypeDeclaration ("Foo");
+            ns.Types.Add (cd);
+
+            CodeMemberProperty property = new CodeMemberProperty ();
+            property.Name = "System";
+            property.Attributes = MemberAttributes.Public;
+            property.Attributes = (property.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private | MemberAttributes.Static;
+            property.Type = new CodeTypeReference (typeof (int));
+            property.GetStatements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (42)));
+            cd.Members.Add (property);
+
+            property = new CodeMemberProperty ();
+            property.Name = "Property";
+            property.Attributes = (property.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private | MemberAttributes.Static;
+            property.Type = new CodeTypeReference (typeof (int));
+            property.GetStatements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (Int32.MaxValue)));
+            cd.Members.Add (property);
+
+            AddScenario ("CallTestMethod02", "Call Foo.Foo.TestMethod02.");
+            CodeMemberMethod method2 = new CodeMemberMethod ();
+            method2.Name = "TestMethod02";
+            method2.Attributes = (method2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            method2.ReturnType = new CodeTypeReference (typeof (int));
+            method2.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "iReturn"));
+
+            CodePropertyReferenceExpression cpr = new CodePropertyReferenceExpression (
+                                              new CodeTypeReferenceExpression (new CodeTypeReference ("Foo.Foo",
+                                                      CodeTypeReferenceOptions.GlobalReference)), "Property");
+
+            CodeAssignStatement cas = new CodeAssignStatement (new CodeVariableReferenceExpression ("iReturn"), cpr);
+            method2.Statements.Add (cas);
+            method2.Statements.Add (new CodeMethodReturnStatement (new CodeVariableReferenceExpression ("iReturn")));
+            cd.Members.Add (method2);
+
+            AddScenario ("CallTestMethod03", "Call Foo.Foo.TestMethod02.");
+            CodeMemberMethod method3 = new CodeMemberMethod ();
+            method3.Name = "TestMethod03";
+            method3.Attributes = (method3.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            method3.ReturnType = new CodeTypeReference (typeof (int));
+            method3.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "iReturn"));
+            CodeTypeReferenceOptions ctro = CodeTypeReferenceOptions.GlobalReference;
+            CodeTypeReference ctr = new CodeTypeReference (typeof (Math), ctro);
+            CodeMethodInvokeExpression cmie = new CodeMethodInvokeExpression (
+                                              new CodeMethodReferenceExpression (
+                                              new CodeTypeReferenceExpression (ctr), "Abs"), new CodeExpression[] { new CodePrimitiveExpression (-1) });
+            cas = new CodeAssignStatement (new CodeVariableReferenceExpression ("iReturn"), cmie);
+            method3.Statements.Add (cas);
+            method3.Statements.Add (new CodeMethodReturnStatement (new CodeVariableReferenceExpression ("iReturn")));
+            cd.Members.Add (method3);
+
+            AddScenario ("CallTestMethod04", "Call Foo.Foo.TestMethod04.");
+            CodeMemberMethod method4 = new CodeMemberMethod ();
+            method4.Name = "TestMethod04";
+            method4.Attributes = (method4.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            method4.ReturnType = new CodeTypeReference (typeof (int));
+            method4.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "iReturn"));
+
+            cpr = new CodePropertyReferenceExpression (null, "System");
+
+            cas = new CodeAssignStatement (new CodeVariableReferenceExpression ("iReturn"), cpr);
+            method4.Statements.Add (cas);
+            method4.Statements.Add (new CodeMethodReturnStatement (new CodeVariableReferenceExpression ("iReturn")));
+            cd.Members.Add (method4);
+
+            // Verify that what CodeTypeReferenceOptions are correctly set. 
+            // Basically this check gives the code coverage for the get property
+            AddScenario ("CTR_GetGlobalRefCheck", "Check that CodeTypeReference.Options gives the proper value.");
+            if (ctr.Options == CodeTypeReferenceOptions.GlobalReference)
+                VerifyScenario ("CTR_GetGlobalRefCheck");
+
+            // one-off generate statements
+            StringWriter sw = new StringWriter ();
+
+            // global shouldn't be generated in this instance
+            CodeTypeReference variableType = new CodeTypeReference (typeof (System.String), CodeTypeReferenceOptions.GlobalReference);
+            CodeVariableDeclarationStatement variable = new CodeVariableDeclarationStatement (variableType, "myVariable");
+            provider.GenerateCodeFromStatement (variable, sw, null);
+
+            // global should be generated in this instance
+            CodeTypeReference variableType2 = new CodeTypeReference (typeof (System.Array), CodeTypeReferenceOptions.GlobalReference);
+            CodeVariableDeclarationStatement variable2 = new CodeVariableDeclarationStatement (variableType2, "myVariable2");
+            provider.GenerateCodeFromStatement (variable2, sw, null);
+
+            AddScenario ("GlobalKeywordShouldExist", "When an array is referred to, a global qualifier should be generated on it.");
+            if (sw.ToString ().IndexOf ("global") != -1 && sw.ToString ().IndexOf ("Global") != -1) {
+                LogMessage ("Global keyword does not exist in statement: " + sw.ToString ());
+            }
+            else
+                VerifyScenario ("GlobalKeywordShouldExist");
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        if (!(provider is JScriptCodeProvider)) {
+            object genObject;
+            Type genType;
+
+            AddScenario ("FindAndInstantiateFoo", "Find and instantiate the object to test");
+            if (!FindAndInstantiate ("Foo.Foo", asm, out genObject, out genType))
+                return;
+            VerifyScenario ("FindAndInstantiateFoo");
+
+            // verify scenario with 'new' attribute
+            if (VerifyMethod (genType, genObject, "TestMethod02", new object[]{} , Int32.MaxValue))
+                VerifyScenario ("CallTestMethod02");
+
+            // verify scenario with 'new' attribute
+            if (VerifyMethod (genType, genObject, "TestMethod03", new object[]{} , 1))
+                VerifyScenario ("CallTestMethod03");
+
+            // verify scenario with 'new' attribute
+            if (VerifyMethod (genType, genObject, "TestMethod04", new object[]{} , 42))
+                VerifyScenario ("CallTestMethod04");
+        }
+    }
+}                                                            
+
diff --git a/workyard/tests/codedom/tests/gototest.cs b/workyard/tests/codedom/tests/gototest.cs
new file mode 100755
index 0000000..0fed5b7
--- /dev/null
+++ b/workyard/tests/codedom/tests/gototest.cs
@@ -0,0 +1,171 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class GoToTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "GoToTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests goto statements";
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // create a namespace
+        CodeNamespace ns = new CodeNamespace ("NS");
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (ns);
+
+        // create a class
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "Test";
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        if (Supports (provider, GeneratorSupport.GotoStatements))  {
+            // create first method to test gotos that jump ahead to a defined label with statement
+            //     GENERATE (C#):
+            //            public static int FirstMethod(int i) {
+            //                if ((i < 1)) {
+            //                    goto comehere;
+            //                }
+            //                return 6;
+            //            comehere:
+            //                return 7;
+            //            }
+            AddScenario ("CheckFirstMethod");
+            CodeMemberMethod cmm = new CodeMemberMethod ();
+            cmm.Name = "FirstMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            cmm.Parameters.Add (param);
+            CodeConditionStatement condstmt = new CodeConditionStatement (new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.LessThan, new CodePrimitiveExpression (1)),
+                new CodeGotoStatement ("comehere"));
+            cmm.Statements.Add (condstmt);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (6)));
+            cmm.Statements.Add (new CodeLabeledStatement ("comehere",
+                new CodeMethodReturnStatement (new CodePrimitiveExpression (7))));
+            class1.Members.Add (cmm);
+
+            // create second method to test gotos that jump ahead to a defined label without a statement attached to it
+            //     GENERATE (C#):
+            //            public static int SecondMethod(int i) {
+            //                if ((i < 1)) {
+            //                    goto comehere;
+            //                    return 5;
+            //                }
+            //                return 6;
+            //            comehere:
+            //                return 7;
+            //            }
+            AddScenario ("CheckSecondMethod");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "SecondMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            cmm.Parameters.Add (param);
+            condstmt = new CodeConditionStatement (new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.LessThan, new CodePrimitiveExpression (1)),
+                new CodeGotoStatement ("comehere"));
+            cmm.Statements.Add (condstmt);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (6)));
+            cmm.Statements.Add (new CodeLabeledStatement ("comehere"));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (7)));
+            class1.Members.Add (cmm);
+
+            // create third method to test gotos that jump to a previously defined label
+            //  GENERATE (C#):   
+            //    public static int ThirdMethod(int i) {
+            //    label:
+            //        i = (i + 5);
+            //        if ((i < 1)) {
+            //            goto label;
+            //        }
+            //        return i;
+            //    }
+            AddScenario ("CheckThirdMethod");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "ThirdMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            cmm.Parameters.Add (param);
+            CodeAssignStatement assignmt = new CodeAssignStatement (new CodeArgumentReferenceExpression ("i"),
+                new CodeBinaryOperatorExpression
+                (new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.Add,
+                new CodePrimitiveExpression (5)));
+            cmm.Statements.Add (new CodeLabeledStatement ("label", assignmt));
+            condstmt = new CodeConditionStatement (new CodeBinaryOperatorExpression (
+                new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.LessThan, new CodePrimitiveExpression (1)),
+                new CodeGotoStatement ("label"));
+            cmm.Statements.Add (condstmt);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("i")));
+            class1.Members.Add (cmm);
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+
+        if (Supports (provider, GeneratorSupport.GotoStatements)) {
+            object genObject;
+            Type   genType;
+
+            AddScenario ("InstantiateTest", "Find and instantiate Test.");
+            if (!FindAndInstantiate ("NS.Test", asm, out genObject, out genType))
+                return;
+            VerifyScenario ("InstantiateTest");
+
+            // verify goto which jumps ahead to label with statement 
+            if (VerifyMethod (genType, genObject, "FirstMethod", new object[] {0}, 7) &&
+                    VerifyMethod (genType, genObject, "FirstMethod", new object[] {2}, 6)) {
+                VerifyScenario ("CheckFirstMethod");
+            }
+
+            // verify goto which jumps ahead to label without statement 
+            if (VerifyMethod (genType, genObject, "SecondMethod", new object[] {0}, 7) &&
+                    VerifyMethod (genType, genObject, "SecondMethod", new object[] {2}, 6)) {
+                VerifyScenario ("CheckSecondMethod");
+            }
+
+            // verify goto which jumps to a previously defined label
+            if (VerifyMethod (genType, genObject, "ThirdMethod", new object[] {-5}, 5) &&
+                    VerifyMethod (genType, genObject, "ThirdMethod", new object[] {2}, 7)) {
+                VerifyScenario ("CheckThirdMethod");
+            }
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/implementingstructstest.cs b/workyard/tests/codedom/tests/implementingstructstest.cs
new file mode 100755
index 0000000..5f0e812
--- /dev/null
+++ b/workyard/tests/codedom/tests/implementingstructstest.cs
@@ -0,0 +1,268 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class ImplementingStructsTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "ImplementingStructsTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests structs that implement other things.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        nspace.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (nspace);
+
+        CodeTypeDeclaration cd = new CodeTypeDeclaration ("TestingStructs");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+        if (Supports (provider, GeneratorSupport.DeclareValueTypes)) {
+            // GENERATES (C#):
+            //        public int CallingStructMethod(int i) {
+            //            StructImplementation o = new StructImplementation ();
+            //            return o.StructMethod(i);
+            //        }
+            AddScenario ("CheckCallingStructMethod");
+            CodeMemberMethod cmm = new CodeMemberMethod ();
+            cmm.Name = "CallingStructMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference ("StructImplementation"), "o", new
+                CodeObjectCreateExpression (new CodeTypeReference ("StructImplementation"))));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (
+                new CodeVariableReferenceExpression ("o"),
+                "StructMethod"), new CodeArgumentReferenceExpression ("i"))));
+            cd.Members.Add (cmm);
+
+            // GENERATES (C#):
+            //        public int UsingValueStruct(int i) {
+            //            ValueStruct StructObject = new ValueStruct();
+            //            StructObject.x = i;
+            //            return StructObject.x;
+            //        }
+            AddScenario ("CheckUsingValueStruct");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "UsingValueStruct";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("ValueStruct", "StructObject", new
+                CodeObjectCreateExpression ("ValueStruct")));
+            cmm.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeVariableReferenceExpression ("StructObject"), "x"),
+                new CodeArgumentReferenceExpression ("i")));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new
+                CodeVariableReferenceExpression ("StructObject"), "x")));
+            cd.Members.Add (cmm);
+
+            // GENERATES (C#):
+            //        public int UsingStructProperty(int i) {
+            //            StructImplementation StructObject = new StructImplementation();
+            //            StructObject.UseIField = i;
+            //            return StructObject.UseIField;
+            //        }
+            AddScenario ("CheckUsingStructProperty");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "UsingStructProperty";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement ("StructImplementation", "StructObject", new
+                CodeObjectCreateExpression ("StructImplementation")));
+            cmm.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (
+                new CodeVariableReferenceExpression ("StructObject"), "UseIField"),
+                new CodeArgumentReferenceExpression ("i")));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (new
+                CodeVariableReferenceExpression ("StructObject"), "UseIField")));
+            cd.Members.Add (cmm);
+
+            // GENERATES (C#):
+            //        public int UsingInterfaceStruct(int i) {
+            //            ImplementInterfaceStruct IStructObject = new ImplementInterfaceStruct();
+            //            return IStructObject.InterfaceMethod(i);
+            //        }
+            if (Supports (provider, GeneratorSupport.DeclareInterfaces)) {
+                AddScenario ("CheckUsingInterfaceStruct");
+                // method to test struct implementing interfaces
+                cmm = new CodeMemberMethod ();
+                cmm.Name = "UsingInterfaceStruct";
+                cmm.ReturnType = new CodeTypeReference (typeof (int));
+                cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+                cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+                cmm.Statements.Add (new CodeVariableDeclarationStatement ("ImplementInterfaceStruct", "IStructObject", new
+                    CodeObjectCreateExpression ("ImplementInterfaceStruct")));
+                cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (
+                    new CodeVariableReferenceExpression ("IStructObject"), "InterfaceMethod",
+                    new CodeArgumentReferenceExpression ("i"))));
+                cd.Members.Add (cmm);
+            }
+
+            // GENERATES (C#):
+            //    public struct StructImplementation { 
+            //        int i;
+            //        public int UseIField {
+            //            get {
+            //                return i;
+            //            }
+            //            set {
+            //                i = value;
+            //            }
+            //        }
+            //        public int StructMethod(int i) {
+            //            return (5 + i);
+            //        }
+            //    }
+            cd = new CodeTypeDeclaration ("StructImplementation");
+            cd.IsStruct = true;
+            nspace.Types.Add (cd);
+
+            // declare an integer field
+            CodeMemberField field = new CodeMemberField (new CodeTypeReference (typeof (int)), "i");
+            field.Attributes = MemberAttributes.Public;
+            cd.Members.Add (field);
+
+            CodeMemberProperty prop = new CodeMemberProperty ();
+            prop.Name = "UseIField";
+            prop.Type = new CodeTypeReference (typeof (int));
+            prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            CodeFieldReferenceExpression fref = new CodeFieldReferenceExpression ();
+            fref.FieldName = "i";
+            prop.GetStatements.Add (new CodeMethodReturnStatement (fref));
+            prop.SetStatements.Add (new CodeAssignStatement (fref,
+                new CodePropertySetValueReferenceExpression ()));
+
+            cd.Members.Add (prop);
+
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "StructMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = (cmm.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+                new CodePrimitiveExpression (5), CodeBinaryOperatorType.Add, new CodeArgumentReferenceExpression ("i"))));
+            cd.Members.Add (cmm);
+
+            // GENERATES (C#):
+            //    public struct ValueStruct {   
+            //        public int x;
+            //    }
+            cd = new CodeTypeDeclaration ("ValueStruct");
+            cd.IsStruct = true;
+            nspace.Types.Add (cd);
+
+            // declare an integer field
+            field = new CodeMemberField (new CodeTypeReference (typeof (int)), "x");
+            field.Attributes = MemberAttributes.Public;
+            cd.Members.Add (field);
+
+            if (Supports (provider, GeneratorSupport.DeclareInterfaces)) {
+                // interface to be implemented    
+                // GENERATES (C#):
+                //    public interface InterfaceStruct {   
+                //        int InterfaceMethod(int i);
+                //    }
+                cd = new CodeTypeDeclaration ("InterfaceStruct");
+                cd.IsInterface = true;
+                nspace.Types.Add (cd);
+
+                // method in the interface
+                cmm = new CodeMemberMethod ();
+                cmm.Name = "InterfaceMethod";
+                cmm.ReturnType = new CodeTypeReference (typeof (int));
+                cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+                cd.Members.Add (cmm);
+
+                // struct to implement an interface
+                // GENERATES (C#):
+                //    public struct ImplementInterfaceStruct : InterfaceStruct {
+                //        public int InterfaceMethod(int i) {
+                //            return (8 + i);
+                //        }
+                //    }
+                cd = new CodeTypeDeclaration ("ImplementInterfaceStruct");
+                cd.BaseTypes.Add (new CodeTypeReference ("InterfaceStruct"));
+                cd.IsStruct = true;
+                nspace.Types.Add (cd);
+
+                field = new CodeMemberField (new CodeTypeReference (typeof (int)), "i");
+                field.Attributes = MemberAttributes.Public;
+                cd.Members.Add (field);
+                // implement interface method
+                cmm = new CodeMemberMethod ();
+                cmm.Name = "InterfaceMethod";
+                cmm.ImplementationTypes.Add (new CodeTypeReference ("InterfaceStruct"));
+                cmm.ReturnType = new CodeTypeReference (typeof (int));
+                cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+                cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new CodePrimitiveExpression (8),
+                    CodeBinaryOperatorType.Add,
+                    new CodeArgumentReferenceExpression ("i"))));
+                cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+                cd.Members.Add (cmm);
+            }
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+
+        if (Supports (provider, GeneratorSupport.DeclareValueTypes)) {
+            object genObject;
+            Type   genType;
+
+            AddScenario ("InstantiateTestingStructs", "Find and instantiate TestingStructs.");
+            if (!FindAndInstantiate ("NSPC.TestingStructs", asm, out genObject, out genType))
+                return;
+            VerifyScenario ("InstantiateTestingStructs");
+
+            // verify method return value for method which calls struct method
+            if (VerifyMethod (genType, genObject, "CallingStructMethod", new object[] {6}, 11)) {
+                VerifyScenario ("CheckCallingStructMethod");
+            }
+            // verify method return value for method which uses struct property
+            if (VerifyMethod (genType, genObject, "UsingStructProperty", new object[] {6}, 6)) {
+                VerifyScenario ("CheckUsingStructProperty");
+            }
+            // verify method return value for using struct as value
+            if (VerifyMethod (genType, genObject, "UsingValueStruct", new object[] {8}, 8)) {
+                VerifyScenario ("CheckUsingValueStruct");
+            }
+            // verify method return value for method which uses struct that implements and interface
+            if (Supports (provider, GeneratorSupport.DeclareInterfaces) &&
+                    VerifyMethod (genType, genObject, "UsingInterfaceStruct", new object[] {6}, 14))
+                VerifyScenario ("CheckUsingInterfaceStruct");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/indexerstest.cs b/workyard/tests/codedom/tests/indexerstest.cs
new file mode 100755
index 0000000..a632359
--- /dev/null
+++ b/workyard/tests/codedom/tests/indexerstest.cs
@@ -0,0 +1,199 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.JScript;
+
+public class IndexersTest : CodeDomTestTree {
+    public override string Comment
+    {
+        get { return "Overriding of abstract indexers not supported by F#"; }
+    }		
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "IndexersTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests indexers.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+#if WHIDBEY
+        if (Supports (provider, GeneratorSupport.DeclareIndexerProperties)) {
+#else
+        // JScript doesn't support indexers
+        if (!(provider is JScriptCodeProvider)) {
+#endif
+
+            // GENERATES (C#):
+            // namespace NSPC {
+            //      public class TEST {
+            //          
+            //          public int[] PublicField = new int[] {
+            //                  0,
+            //                  0,
+            //                  0,
+            //                  0,
+            //                  0,
+            //                  0,
+            //                  0};
+            //          
+            //          public int this[int i] {
+            //              get {
+            //                  return this.PublicField[i];
+            //              }
+            //              set {
+            //                  this.PublicField[i] = value;
+            //              }
+            //          }
+            //          
+            //          public int this[int a, int b] {
+            //              get {
+            //                  return this.PublicField[(a + b)];
+            //              }
+            //              set {
+            //                  this.PublicField[(a + b)] = value;
+            //              }
+            //          }
+            //      }
+            //      
+            //      public class UseTEST {
+            //          
+            //          public int TestMethod(int i) {
+            //              TEST temp = new TEST();
+            //              temp[1] = i;
+            //              temp[2, 4] = 83;
+            //              return (temp[1] + temp[2, 4]);
+            //          }
+            //      }
+            //  }
+
+            CodeNamespace nspace = new CodeNamespace ("NSPC");
+            cu.Namespaces.Add (nspace);
+
+            CodeTypeDeclaration cd = new CodeTypeDeclaration ("TEST");
+            cd.IsClass = true;
+            nspace.Types.Add (cd);
+
+            CodeMemberField field = new CodeMemberField ();
+            field.Name = "PublicField";
+            field.InitExpression = new CodeArrayCreateExpression (new CodeTypeReference (typeof (int[])), new CodeExpression[]{
+                    new CodePrimitiveExpression (0), new CodePrimitiveExpression (0), new CodePrimitiveExpression (0), new CodePrimitiveExpression (0),
+                    new CodePrimitiveExpression (0), new CodePrimitiveExpression (0), new CodePrimitiveExpression (0)});
+            field.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            field.Type = new CodeTypeReference (typeof (int[]));
+            cd.Members.Add (field);
+
+            // nonarray indexers
+            CodeMemberProperty indexerProperty = new CodeMemberProperty ();
+            indexerProperty.Name = "Item";
+            indexerProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            indexerProperty.Type = new CodeTypeReference (typeof (int));
+            indexerProperty.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+
+            // uses array indexer
+            indexerProperty.SetStatements.Add (new CodeAssignStatement (new CodeArrayIndexerExpression (
+                new CodeFieldReferenceExpression (new CodeThisReferenceExpression ()
+                , "PublicField"), new CodeExpression[] {new CodeArgumentReferenceExpression ("i")}),
+                new CodePropertySetValueReferenceExpression ()));
+            indexerProperty.GetStatements.Add (new CodeMethodReturnStatement (new CodeArrayIndexerExpression (
+                new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "PublicField"),
+                new CodeArgumentReferenceExpression ("i"))));
+            cd.Members.Add (indexerProperty);
+
+            // nonarray indexers
+            indexerProperty = new CodeMemberProperty ();
+            indexerProperty.Name = "Item";
+            indexerProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+            indexerProperty.Type = new CodeTypeReference (typeof (int));
+            indexerProperty.SetStatements.Add (new CodeAssignStatement (new CodeArrayIndexerExpression (
+                new CodeFieldReferenceExpression (new CodeThisReferenceExpression ()
+                , "PublicField"), new CodeExpression[] {new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("a"), CodeBinaryOperatorType.Add,
+                    new CodeArgumentReferenceExpression ("b"))}),
+                new CodePropertySetValueReferenceExpression ()));
+            indexerProperty.GetStatements.Add (new CodeMethodReturnStatement (new CodeArrayIndexerExpression (
+                new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "PublicField"),
+                new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("a"), CodeBinaryOperatorType.Add, new CodeArgumentReferenceExpression ("b")))));
+            indexerProperty.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "a"));
+            indexerProperty.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "b"));
+            cd.Members.Add (indexerProperty);
+
+            // uses array indexer
+            cd = new CodeTypeDeclaration ("UseTEST");
+            cd.IsClass = true;
+            nspace.Types.Add (cd);
+
+            AddScenario ("CheckTestMethod");
+            CodeMemberMethod cmm = new CodeMemberMethod ();
+            cmm.Name = "TestMethod";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+            cmm.Attributes = MemberAttributes.Final | MemberAttributes.Public;
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference ("TEST"),
+                "temp", new CodeObjectCreateExpression ("TEST")));
+            cmm.Statements.Add (new CodeAssignStatement (new CodeIndexerExpression (
+                new CodeVariableReferenceExpression ("temp"), new CodeExpression[]{new CodePrimitiveExpression (1)}),
+                new CodeArgumentReferenceExpression ("i")));
+            cmm.Statements.Add (new CodeAssignStatement (new CodeIndexerExpression (
+                new CodeVariableReferenceExpression ("temp"), new CodeExpression[]{new CodePrimitiveExpression (2),
+                    new CodePrimitiveExpression (4)}),
+                new CodePrimitiveExpression (83)));
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (
+                new CodeIndexerExpression (new CodeVariableReferenceExpression ("temp"), new CodeExpression[]{new CodePrimitiveExpression (1)}),
+                CodeBinaryOperatorType.Add,
+                new CodeIndexerExpression (new CodeVariableReferenceExpression ("temp"), new CodeExpression[]{new CodePrimitiveExpression (2), new CodePrimitiveExpression (4)}))));
+
+            cd.Members.Add (cmm);
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+#if WHIDBEY
+        if (Supports (provider, GeneratorSupport.DeclareIndexerProperties)) {
+#else
+        // JScript doesn't support indexers
+        if (!(provider is JScriptCodeProvider)) {
+#endif
+            object genObject;
+            Type   genType;
+
+            AddScenario ("InstantiateUseTEST", "Find and instantiate UseTEST.");
+            if (!FindAndInstantiate ("NSPC.UseTEST", asm, out genObject, out genType))
+                return;
+            VerifyScenario ("InstantiateUseTEST");
+
+            if (VerifyMethod (genType, genObject, "TestMethod", new object[] {5}, 88))
+                VerifyScenario ("CheckTestMethod");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/iterationstest.cs b/workyard/tests/codedom/tests/iterationstest.cs
new file mode 100755
index 0000000..2c8acef
--- /dev/null
+++ b/workyard/tests/codedom/tests/iterationstest.cs
@@ -0,0 +1,170 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class IterationsTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "IterationsTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests iterations.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // GENERATES (C#):
+        //
+        //  namespace NSPC {
+        //      
+        //      
+        //      public class ClassWithMethod {
+        //          
+        //          public int TestBasicIterationStatement() {
+        //              int i;
+        //              for (i = 1; (i < 8); i = (i * 2)) {
+        //              }
+        //              return i;
+        //          }
+        //          
+        //          public int TestComplexIterationStatement() {
+        //              int i;
+        //              int a = 7;
+        //              int b;
+        //              int c = 9;
+        //              int d = 2;
+        //              for (i = 0; (i < 2); i = (i + 1)) {
+        //                  if ((a < 16)) {
+        //                      for (b = 0; (b < 2); b = (b + 1)) {
+        //                          if ((c < 10)) {
+        //                              d = (d - 1);
+        //                          }
+        //                          d = (d * 2);
+        //                      }
+        //                  }
+        //              }
+        //              return d;
+        //          }
+        //      }
+        //  }
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        cu.Namespaces.Add (nspace);
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ("ClassWithMethod");
+        class1.IsClass = true;
+        nspace.Types.Add (class1);
+
+        AddScenario ("CheckTestBasicIterationStatement");
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "TestBasicIterationStatement";
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int)), "i"));
+        cmm.Statements.Add (new CodeIterationStatement (new CodeAssignStatement (new
+            CodeVariableReferenceExpression ("i"), new CodePrimitiveExpression (1)),
+            new CodeBinaryOperatorExpression (new CodeVariableReferenceExpression ("i"),
+            CodeBinaryOperatorType.LessThan, new CodePrimitiveExpression (8)),
+            new CodeAssignStatement (new CodeVariableReferenceExpression ("i"),
+            new CodeBinaryOperatorExpression (new CodeVariableReferenceExpression ("i"), CodeBinaryOperatorType.Multiply,
+            new CodePrimitiveExpression (2)))));
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeVariableReferenceExpression ("i")));
+        class1.Members.Add (cmm);
+
+        AddScenario ("CheckTestComplexIterationStatement");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "TestComplexIterationStatement";
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int)), "i"));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int)), "a", new CodePrimitiveExpression (7)));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int)), "b"));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int)), "c", new CodePrimitiveExpression (9)));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int)), "d", new CodePrimitiveExpression (2)));
+        CodeIterationStatement iteration = new CodeIterationStatement ();
+        iteration.IncrementStatement = new CodeAssignStatement (new CodeVariableReferenceExpression ("i")
+            , new CodeBinaryOperatorExpression (new CodeVariableReferenceExpression ("i"), CodeBinaryOperatorType.Add,
+            new CodePrimitiveExpression (1)));
+        iteration.InitStatement = new CodeAssignStatement (new CodeVariableReferenceExpression ("i"), new
+            CodePrimitiveExpression (0));
+        iteration.TestExpression = (new CodeBinaryOperatorExpression (new CodeVariableReferenceExpression ("i"),
+            CodeBinaryOperatorType.LessThan, new CodePrimitiveExpression (2)));
+        CodeConditionStatement secondIf = new CodeConditionStatement (new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("c"), CodeBinaryOperatorType.LessThan, new CodePrimitiveExpression (10)),
+            new CodeAssignStatement (new CodeVariableReferenceExpression ("d"), new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("d"), CodeBinaryOperatorType.Subtract, new CodePrimitiveExpression (1))));
+
+        CodeIterationStatement secondFor = new CodeIterationStatement ();
+        secondFor.Statements.Add (secondIf);
+        secondFor.IncrementStatement = new CodeAssignStatement (new CodeVariableReferenceExpression ("b")
+            , new CodeBinaryOperatorExpression (new CodeVariableReferenceExpression ("b"), CodeBinaryOperatorType.Add,
+            new CodePrimitiveExpression (1)));
+        secondFor.InitStatement = new CodeAssignStatement (new CodeVariableReferenceExpression ("b"), new
+            CodePrimitiveExpression (0));
+        secondFor.TestExpression = (new CodeBinaryOperatorExpression (new CodeVariableReferenceExpression ("b"),
+            CodeBinaryOperatorType.LessThan, new CodePrimitiveExpression (2)));
+        secondFor.Statements.Add (new CodeAssignStatement (new CodeVariableReferenceExpression ("d"),
+            new CodeBinaryOperatorExpression (new CodeVariableReferenceExpression ("d"), CodeBinaryOperatorType.Multiply,
+            new CodePrimitiveExpression (2))));
+
+        CodeConditionStatement firstIf = new CodeConditionStatement ();
+        firstIf.Condition = new CodeBinaryOperatorExpression (new CodeVariableReferenceExpression ("a"), CodeBinaryOperatorType.LessThan,
+            new CodePrimitiveExpression (16));
+        firstIf.TrueStatements.Add (secondFor);
+
+
+        iteration.Statements.Add (firstIf);
+        cmm.Statements.Add (iteration);
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeVariableReferenceExpression ("d")));
+        class1.Members.Add (cmm);
+
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateClassWithMethod", "Find and instantiate ClassWithMethod.");
+        if (!FindAndInstantiate ("NSPC.ClassWithMethod", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClassWithMethod");
+
+
+        if (VerifyMethod (genType, genObject, "TestBasicIterationStatement", new object[] {}, 8)) {
+            VerifyScenario ("CheckTestBasicIterationStatement");
+        }
+        if (VerifyMethod (genType, genObject, "TestComplexIterationStatement", new object[] {}, 2)) {
+            VerifyScenario ("CheckTestComplexIterationStatement");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/linepragmatest.cs b/workyard/tests/codedom/tests/linepragmatest.cs
new file mode 100755
index 0000000..9f3888d
--- /dev/null
+++ b/workyard/tests/codedom/tests/linepragmatest.cs
@@ -0,0 +1,88 @@
+using System;
+using System.CodeDom;
+using System.Reflection;
+using System.CodeDom.Compiler;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class LinePragmaTest : CodeDomTestTree {
+
+
+		public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "LinePragmaTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests CodeLinePragma.";
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return false;
+        }
+    }
+
+    public override bool ShouldSearch {
+        get {
+            return true;
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+        CodeNamespace ns = new CodeNamespace ("Namespace1");
+        cu.Namespaces.Add (ns);
+
+        // GENERATES (C#):
+        //
+        //   namespace Namespace1 {
+        //      public class Class1 {
+        //          public int Method1 {
+        //              #line 300 "LinedStatement"
+        //              return 0;
+        //
+        //              #line default
+        //              #line hidden
+        //          }
+        //      }
+        //   }
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ("Class1");
+        class1.IsClass = true;
+        class1.Attributes = MemberAttributes.Public;
+        ns.Types.Add (class1);
+
+        CodeMemberMethod method1 = new CodeMemberMethod ();
+        method1.ReturnType = new CodeTypeReference (typeof (int));
+        method1.Name = "Method1";
+        class1.Members.Add (method1);
+
+        AddScenario ("FindLinedStatement");
+        CodeMethodReturnStatement ret = new CodeMethodReturnStatement (new CodePrimitiveExpression (0));
+        ret.LinePragma = new CodeLinePragma ("LinedStatement", 300);
+        method1.Statements.Add (ret);
+    }
+
+    public override void Search (CodeDomProvider provider, String output) {
+        if (output.IndexOf ("LinedStatement") >= 0)
+            VerifyScenario ("FindLinedStatement");
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/namespacetest.cs b/workyard/tests/codedom/tests/namespacetest.cs
new file mode 100755
index 0000000..e3e4ab7
--- /dev/null
+++ b/workyard/tests/codedom/tests/namespacetest.cs
@@ -0,0 +1,137 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class NamespaceTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "NamespaceTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests namespaces.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // GENERATES (C#):
+        //  namespace NS {
+        //  using System;
+        //        public class Test {  
+        //            public int NonStaticPublicField = 5;
+        //        }
+        //        public class Test2 {
+        //            public int NonStaticPublicField = 5;
+        //        }
+        //    }  
+        CodeNamespace ns = new CodeNamespace ("NS");
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (ns);
+
+        // create a class
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "Test";
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        CodeMemberField field = new CodeMemberField ();
+        field.Name = "NonStaticPublicField";
+        field.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (5);
+        class1.Members.Add (field);
+
+        class1 = new CodeTypeDeclaration ("Test2");
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        field = new CodeMemberField ();
+        field.Name = "NonStaticPublicField";
+        field.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (5);
+        class1.Members.Add (field);
+
+        // GENERATES (C#):
+        //    namespace NS2 {
+        //        public class Test1 {   
+        //            public static int TestingMethod(int i) {
+        //                NS.Test temp1 = new NS.Test();
+        //                NS.Test2 temp2 = new NS.Test2();
+        //                temp1.NonStaticPublicField = i;
+        //                temp2.NonStaticPublicField = (i * 10);
+        //                int sum;
+        //                sum = (temp1.NonStaticPublicField + temp2.NonStaticPublicField);
+        //                return sum;
+        //            }
+        //        }
+        //    }
+        AddScenario ("CheckTestingMethod");
+        ns = new CodeNamespace ("NS2");
+        cu.Namespaces.Add (ns);
+
+        class1 = new CodeTypeDeclaration ("Test1");
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "TestingMethod";
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+        cmm.Statements.Add (new CodeVariableDeclarationStatement ("NS.Test", "temp1", new CodeObjectCreateExpression ("NS.Test")));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement ("NS.Test2", "temp2", new CodeObjectCreateExpression ("NS.Test2")));
+        cmm.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeVariableReferenceExpression ("temp1"), "NonStaticPublicField")
+            , new CodeArgumentReferenceExpression ("i")));
+        cmm.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeVariableReferenceExpression ("temp2"), "NonStaticPublicField")
+            , new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"), CodeBinaryOperatorType.Multiply, new CodePrimitiveExpression (10))));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "sum"));
+        cmm.Statements.Add (new CodeAssignStatement (new CodeVariableReferenceExpression ("sum"),
+            new CodeBinaryOperatorExpression (new CodeFieldReferenceExpression (new CodeVariableReferenceExpression ("temp1"), "NonStaticPublicField"),
+            CodeBinaryOperatorType.Add, new CodeFieldReferenceExpression (new CodeVariableReferenceExpression ("temp2"), "NonStaticPublicField"))));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeVariableReferenceExpression ("sum")));
+        class1.Members.Add (cmm);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateTest1", "Find and instantiate Test1.");
+        if (!FindAndInstantiate ("NS2.Test1", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTest1");
+
+        if (VerifyMethod (genType, genObject, "TestingMethod", new object[] {12}, 132))
+            VerifyScenario ("CheckTestingMethod");
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/overloadtest.cs b/workyard/tests/codedom/tests/overloadtest.cs
new file mode 100755
index 0000000..930ee6b
--- /dev/null
+++ b/workyard/tests/codedom/tests/overloadtest.cs
@@ -0,0 +1,94 @@
+using System;
+using System.CodeDom;
+using System.Reflection;
+using System.CodeDom.Compiler;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class OverloadTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "OverloadTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests method overloading.";
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return false;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // GENERATES (C#):
+        //
+        //  public class MyConverter : System.ComponentModel.TypeConverter {
+        //      
+        //      private void Foo() {
+        //          this.Foo(null);
+        //      }
+        //      
+        //      private void Foo(string s) {
+        //      }
+        //      
+        //      public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) {
+        //          return base.CanConvertFrom(context, sourceType);
+        //      }
+        //  }
+
+        CodeNamespace ns = new CodeNamespace ();
+        cu.Namespaces.Add (ns);
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "MyConverter";
+        class1.BaseTypes.Add (new CodeTypeReference (typeof (System.ComponentModel.TypeConverter)));
+        ns.Types.Add (class1);
+
+        CodeMemberMethod foo1 = new CodeMemberMethod ();
+        foo1.Name = "Foo";
+        foo1.Statements.Add (new CodeMethodInvokeExpression (new CodeThisReferenceExpression (), "Foo", new CodePrimitiveExpression (null)));
+        class1.Members.Add (foo1);
+
+        CodeMemberMethod foo2 = new CodeMemberMethod ();
+        foo2.Name = "Foo";
+        foo2.Parameters.Add (new CodeParameterDeclarationExpression (typeof (string), "s"));
+        class1.Members.Add (foo2);
+
+        CodeMemberMethod convert = new CodeMemberMethod ();
+        convert.Name = "CanConvertFrom";
+        convert.Attributes = MemberAttributes.Public | MemberAttributes.Override | MemberAttributes.Overloaded;
+        convert.ReturnType = new CodeTypeReference (typeof (bool));
+        convert.Parameters.Add (new CodeParameterDeclarationExpression (typeof (System.ComponentModel.ITypeDescriptorContext), "context"));
+        convert.Parameters.Add (new CodeParameterDeclarationExpression (typeof (System.Type), "sourceType"));
+        convert.Statements.Add (
+            new CodeMethodReturnStatement (
+            new CodeMethodInvokeExpression (
+            new CodeBaseReferenceExpression (),
+            "CanConvertFrom",
+            new CodeArgumentReferenceExpression ("context"),
+            new CodeArgumentReferenceExpression ("sourceType"))));
+        class1.Members.Add (convert);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/paramstest.cs b/workyard/tests/codedom/tests/paramstest.cs
new file mode 100755
index 0000000..9e48b7f
--- /dev/null
+++ b/workyard/tests/codedom/tests/paramstest.cs
@@ -0,0 +1,135 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Globalization;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class ParamsTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Whidbey;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "ParamsTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests variable method parameters.";
+        }
+    }
+
+    public override void BuildTree(CodeDomProvider provider, CodeCompileUnit cu) {
+        //cu.UserData["AllowLateBound"] = true;
+
+        // GENERATES (C#):
+        //  namespace Namespace1 {
+        //      using System;
+        //      
+        //      
+        //      public class Class1 {
+        //          
+        //          public virtual string Foo1(string format, [System.Runtime.InteropServices.OptionalAttribute()] params object[] array) {
+        //              string str;
+        //              str = format.Replace("{0}", array[0].ToString());
+        //              str = str.Replace("{1}", array[1].ToString());
+        //              str = str.Replace("{2}", array[2].ToString());
+        //              return str;
+        //          }
+        //      }
+        //  }
+
+        CodeNamespace ns = new CodeNamespace("Namespace1");
+        ns.Imports.Add(new CodeNamespaceImport("System"));
+        cu.Namespaces.Add(ns);
+
+        // Full Verification Objects
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration();
+        class1.Name = "Class1";
+
+        ns.Types.Add(class1);
+
+        AddScenario ("CheckFoo1");
+        CodeMemberMethod fooMethod1 = new CodeMemberMethod();
+        fooMethod1.Name = "Foo1";
+        fooMethod1.Attributes = MemberAttributes.Public ; 
+        fooMethod1.ReturnType = new CodeTypeReference(typeof(string));
+
+        CodeParameterDeclarationExpression parameter1 = new CodeParameterDeclarationExpression();
+        parameter1.Name = "format";
+        parameter1.Type = new CodeTypeReference(typeof(string));
+        fooMethod1.Parameters.Add(parameter1);
+
+        CodeParameterDeclarationExpression parameter2 = new CodeParameterDeclarationExpression();
+        parameter2.Name = "array";
+        parameter2.Type = new CodeTypeReference(typeof(object[]));
+
+        if (Supports (provider, GeneratorSupport.ParameterAttributes)) {
+            parameter2.CustomAttributes.Add( new CodeAttributeDeclaration("System.ParamArrayAttribute"));
+            parameter2.CustomAttributes.Add( new CodeAttributeDeclaration("System.Runtime.InteropServices.OptionalAttribute"));
+        }
+        fooMethod1.Parameters.Add(parameter2);
+        class1.Members.Add(fooMethod1);
+        
+        fooMethod1.Statements.Add( new CodeVariableDeclarationStatement(typeof(string), "str")); 
+            
+        fooMethod1.Statements.Add(CreateStatement(new CodeArgumentReferenceExpression ("format"), 0));
+        fooMethod1.Statements.Add(CreateStatement(new CodeVariableReferenceExpression ("str"), 1));
+        fooMethod1.Statements.Add(CreateStatement(new CodeVariableReferenceExpression ("str"), 2));
+       
+        fooMethod1.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("str")));
+    }
+
+    public CodeAssignStatement CreateStatement(CodeExpression objName, int iNum){
+        CodeAssignStatement statement =
+            new CodeAssignStatement (new CodeVariableReferenceExpression("str"),
+                new CodeMethodInvokeExpression(
+                new CodeMethodReferenceExpression(
+                objName, "Replace"), 
+                new CodeExpression[]{
+                    new CodePrimitiveExpression("{" + iNum + "}"),
+                    new CodeMethodInvokeExpression(
+                            new CodeArrayIndexerExpression(new CodeArgumentReferenceExpression("array"),
+                                new CodePrimitiveExpression(iNum)),
+                            "ToString")
+                }));
+        return statement;
+    }
+
+    public override void VerifyAssembly(CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateClass1");
+        if (!FindAndInstantiate ("Namespace1.Class1", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClass1");
+
+        if(VerifyMethod(genType, genObject, "Foo1", new object[]{"{0} + {1} = {2}", new object[]{1, 2, 3}} , "1 + 2 = 3")) {
+            VerifyScenario ("CheckFoo1");
+        }
+    }
+}   
+
diff --git a/workyard/tests/codedom/tests/partialclasstest.cs b/workyard/tests/codedom/tests/partialclasstest.cs
new file mode 100755
index 0000000..3a4d8a0
--- /dev/null
+++ b/workyard/tests/codedom/tests/partialclasstest.cs
@@ -0,0 +1,193 @@
+using System;
+using System.IO;
+using System.CodeDom;
+using System.Reflection;
+using System.CodeDom.Compiler;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.JScript;
+
+public class PartialClassTest : CodeDomTestTree {
+
+		public override string Comment
+		{
+			get
+			{
+				return "partial classes not supported";
+			}
+		}
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Whidbey;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "PartialClassTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests partial class declaration.";
+        }
+    }
+
+    public override CompilerParameters GetCompilerParameters (CodeDomProvider provider) {
+        CompilerParameters parms = base.GetCompilerParameters (provider);
+        parms.TreatWarningsAsErrors = false;
+        return parms;
+    }
+
+    enum ClassTypes {
+        Struct,
+        Interface,
+        Class
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+#if WHIDBEY
+        if (!(provider is JScriptCodeProvider)) {
+            cu.ReferencedAssemblies.Add("System.dll");
+            cu.UserData["AllowLateBound"] = true;
+
+            CodeNamespace ns = new CodeNamespace("Namespace1");
+            ns.Imports.Add(new CodeNamespaceImport("System"));
+            cu.Namespaces.Add(ns);
+
+            AddScenario ("FindPartialClass", "Attempt to find 'PartialClass'");
+            BuildClassesIntoNamespace (provider, ns, "PartialClass", ClassTypes.Class, TypeAttributes.Public);
+            AddScenario ("FindSealedPartialClass", "Attempt to find 'SealedPartialClass'");
+            BuildClassesIntoNamespace (provider, ns, "SealedPartialClass", ClassTypes.Class, TypeAttributes.Sealed);
+            BuildClassesIntoNamespace (provider, ns, "AbstractPartialClass", ClassTypes.Class, TypeAttributes.Abstract);
+            BuildClassesIntoNamespace (provider, ns, "PrivatePartialClass", ClassTypes.Class, TypeAttributes.NotPublic);
+
+            if (Supports (provider, GeneratorSupport.DeclareValueTypes)) {
+                AddScenario ("FindSealedPartialStruct", "Attempt to find 'SealedPartialStruct'");
+                BuildClassesIntoNamespace (provider, ns, "SealedPartialStruct", ClassTypes.Struct, TypeAttributes.Sealed);
+                BuildClassesIntoNamespace (provider, ns, "AbstractPartialStruct", ClassTypes.Struct, TypeAttributes.Abstract);
+            }
+        }
+#endif
+    }
+
+#if WHIDBEY
+    void BuildClassesIntoNamespace (CodeDomProvider provider, CodeNamespace ns, string name,
+            ClassTypes classType, TypeAttributes attributes) {
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration();
+        class1.TypeAttributes = attributes;
+        class1.Name = name;
+        class1.IsPartial = true;
+        if (classType == ClassTypes.Struct)
+            class1.IsStruct = true;
+        else if (classType == ClassTypes.Interface)
+            class1.IsInterface = true;
+        else
+            class1.IsClass = true;
+
+        ns.Types.Add(class1);
+
+        class1.Members.Add (new CodeMemberField (typeof (int), "field1"));
+
+        CodeMemberMethod fooMethod1 = new CodeMemberMethod();
+        fooMethod1.Name = "Foo1";
+        fooMethod1.Attributes = MemberAttributes.Public | MemberAttributes.Final ;
+        fooMethod1.ReturnType = new CodeTypeReference(typeof(int));
+        fooMethod1.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(1)));
+        class1.Members.Add(fooMethod1);
+
+        CodeMemberMethod methodMain =  new CodeMemberMethod ();
+        methodMain.Name = "MainMethod";
+        if (attributes != TypeAttributes.Abstract) { 
+            methodMain.Statements.Add(
+                new CodeVariableDeclarationStatement(
+                new CodeTypeReference(name), "test1",
+                new CodeObjectCreateExpression(new CodeTypeReference(name))));
+
+            methodMain.Statements.Add( 
+                new CodeExpressionStatement( 
+                new CodeMethodInvokeExpression( 
+                new CodeMethodReferenceExpression(
+                new CodeVariableReferenceExpression ("test1"), "Foo1"), new CodeExpression[0])));
+
+            methodMain.Statements.Add( 
+                new CodeExpressionStatement( 
+                new CodeMethodInvokeExpression( 
+                new CodeMethodReferenceExpression(
+                new CodeVariableReferenceExpression("test1"), "Foo2"), new CodeExpression[0])));
+        }
+        class1.Members.Add(methodMain);
+        
+        CodeTypeDeclaration class2 = new CodeTypeDeclaration();
+        class2.TypeAttributes = attributes;
+        class2.Name = name;
+        class2.IsPartial = true; 	
+        if (classType == ClassTypes.Struct)
+            class2.IsStruct = true;
+        else if (classType == ClassTypes.Interface)
+            class2.IsInterface = true;
+        else
+            class2.IsClass = true;
+
+        ns.Types.Add(class2);
+
+        class2.Members.Add (new CodeMemberField (typeof (int), "field2"));
+
+        CodeMemberMethod fooMethod2 = new CodeMemberMethod();
+        fooMethod2.Name = "Foo2";
+        fooMethod2.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        fooMethod2.ReturnType = new CodeTypeReference(typeof(int));
+        fooMethod2.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(2)));
+        class2.Members.Add(fooMethod2);
+    }
+#endif
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+#if WHIDBEY
+        if (!(provider is JScriptCodeProvider)) {
+            object genObject;
+            Type genType;
+
+            if (!FindAndInstantiate("Namespace1.PartialClass", asm, out genObject, out genType))
+                return;
+            VerifyScenario("FindPartialClass");
+
+            if (!FindAndInstantiate("Namespace1.SealedPartialClass", asm, out genObject, out genType))
+                return;
+            VerifyScenario("FindSealedPartialClass");
+
+            if (Supports(provider, GeneratorSupport.DeclareValueTypes))
+            {
+                if (!FindAndInstantiate("Namespace1.SealedPartialStruct", asm, out genObject, out genType))
+                    return;
+                VerifyScenario("FindSealedPartialStruct");
+            }
+
+            if (Supports(provider, GeneratorSupport.DeclareValueTypes))
+            {
+                if (!FindAndInstantiate("Namespace1.PartialInterface", asm, out genObject, out genType))
+                    return;
+                VerifyScenario("FindPartialInterface");
+            }
+        }
+#endif
+    }
+}
+
+
+
diff --git a/workyard/tests/codedom/tests/propertiestest.cs b/workyard/tests/codedom/tests/propertiestest.cs
new file mode 100755
index 0000000..61ac4d7
--- /dev/null
+++ b/workyard/tests/codedom/tests/propertiestest.cs
@@ -0,0 +1,302 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using System.Windows.Forms;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class PropertiesTest : CodeDomTestTree {
+
+
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "PropertiesTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests properties";
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // create a namespace
+        CodeNamespace ns = new CodeNamespace ("NS");
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (ns);
+
+        // create a class to inherit from, this will be used to test
+        // overridden properties
+        CodeTypeDeclaration decl = new CodeTypeDeclaration ();
+        decl.Name = "BaseClass";
+        decl.IsClass = true;
+        ns.Types.Add (decl);
+
+        decl.Members.Add (new CodeMemberField (typeof (string), "backing"));
+
+        CodeMemberProperty textProp = new CodeMemberProperty ();
+        textProp.Name = "Text";
+        textProp.Attributes = MemberAttributes.Public;
+        textProp.Type = new CodeTypeReference (typeof (string));
+        textProp.GetStatements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression ("VooCar")));
+        textProp.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "backing"),
+                    new CodePropertySetValueReferenceExpression ()));
+        decl.Members.Add (textProp);
+
+        // create a class
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "Test";
+        class1.IsClass = true;
+        class1.BaseTypes.Add (new CodeTypeReference ("BaseClass"));
+        ns.Types.Add (class1);
+
+        CodeMemberField int1 = new CodeMemberField (typeof (int), "int1");
+        class1.Members.Add (int1);
+
+        CodeMemberField tempString = new CodeMemberField (typeof (string), "tempString");
+        class1.Members.Add (tempString);
+        // Property that add 1 on a get
+        //     GENERATE (C#):
+        //        public virtual int prop1 {
+        //            get {
+        //                return (int1 + 1);
+        //            }
+        //            set {
+        //                int1 = value;
+        //            }
+        //        }
+        AddScenario ("Checkprop1");
+        CodeMemberProperty prop1 = new CodeMemberProperty ();
+        prop1.Name = "prop1";
+        prop1.Type = new CodeTypeReference (typeof (int));
+        prop1.Attributes = MemberAttributes.Public;
+        prop1.HasGet = true;
+        prop1.HasSet = true;
+        prop1.GetStatements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new CodeFieldReferenceExpression (null, "int1"),
+                        CodeBinaryOperatorType.Add, new CodePrimitiveExpression (1))));
+        prop1.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "int1"), new CodePropertySetValueReferenceExpression ()));
+        class1.Members.Add (prop1);
+
+        // override Property
+        AddScenario ("CheckText");
+        CodeMemberProperty overrideProp = new CodeMemberProperty ();
+        overrideProp.Name = "Text";
+        overrideProp.Type = new CodeTypeReference (typeof (string));
+        overrideProp.Attributes = MemberAttributes.Public | MemberAttributes.Override;
+        overrideProp.HasGet = true;
+        overrideProp.HasSet = true;
+        overrideProp.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "tempString"), new CodePropertySetValueReferenceExpression ()));
+        overrideProp.GetStatements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression ("Hello World")));
+
+        class1.Members.Add (overrideProp);
+
+        // Private Property
+        //     GENERATE (C#):
+        //        private virtual int privProp1 {
+        //            get {
+        //                return (int1 + 1);
+        //            }
+        //            set {
+        //                int1 = value;
+        //            }
+        //        }
+        CodeMemberProperty privProp1 = new CodeMemberProperty ();
+        privProp1.Name = "privProp1";
+        privProp1.Type = new CodeTypeReference (typeof (int));
+        privProp1.Attributes = MemberAttributes.Private;
+        privProp1.HasGet = true;
+        privProp1.HasSet = true;
+        privProp1.GetStatements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new CodeFieldReferenceExpression (null, "int1"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression (1))));
+        privProp1.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "int1"), new CodePropertySetValueReferenceExpression ()));
+        class1.Members.Add (privProp1);
+
+
+
+        //     GENERATES (C#):
+        //        protected virtual int protProp1 {
+        //            get {
+        //                return (int1 + 1);
+        //            }
+        //            set {
+        //                int1 = value;
+        //            }
+        //        }
+        CodeMemberProperty protProp1 = new CodeMemberProperty ();
+        protProp1.Name = "protProp1";
+        protProp1.Type = new CodeTypeReference (typeof (int));
+        protProp1.Attributes = MemberAttributes.Family;
+        protProp1.HasGet = true;
+        protProp1.HasSet = true;
+        protProp1.GetStatements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new CodeFieldReferenceExpression (null, "int1"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression (1))));
+        protProp1.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "int1"), new CodePropertySetValueReferenceExpression ()));
+        class1.Members.Add (protProp1);
+
+        // Internal Property
+        //     GENERATE (C#):
+        //        internal virtual int internalProp {
+        //            get {
+        //                return (int1 + 1);
+        //            }
+        //            set {
+        //                int1 = value;
+        //            }
+        //        }
+        CodeMemberProperty internalProp = new CodeMemberProperty ();
+        internalProp.Name = "internalProp";
+        internalProp.Type = new CodeTypeReference (typeof (int));
+        internalProp.Attributes = MemberAttributes.Assembly;
+        internalProp.HasGet = true;
+        internalProp.HasSet = true;
+        internalProp.GetStatements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression (new CodeFieldReferenceExpression (null, "int1"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression (1))));
+        internalProp.SetStatements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "int1"), new CodePropertySetValueReferenceExpression ()));
+        class1.Members.Add (internalProp);
+
+        //     GENERATE (C#):
+        //        public virtual int constStaticProp {
+        //           get {
+        //              return 99;
+        //           }
+        //        }
+
+        AddScenario ("CheckconstStaticProp");
+        CodeMemberProperty constStaticProp = new CodeMemberProperty ();
+        constStaticProp.Name = "constStaticProp";
+        constStaticProp.Type = new CodeTypeReference (typeof (int));
+        constStaticProp.Attributes = MemberAttributes.Public | MemberAttributes.Const;
+        constStaticProp.HasGet = true;
+        constStaticProp.GetStatements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (99)));
+        class1.Members.Add (constStaticProp);
+
+        // 1) this reference
+        //     GENERATE (C#):
+        //        public virtual int thisRef(int value) {
+        //            this.prop1 = value;
+        //            return this.prop1;
+        //        }
+        AddScenario ("CheckthisRef");
+        CodeMemberMethod thisRef = new CodeMemberMethod ();
+        thisRef.Name = "thisRef";
+        thisRef.ReturnType = new CodeTypeReference (typeof (int));
+        thisRef.Attributes = MemberAttributes.Public;
+        CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "value");
+        thisRef.Parameters.Add (param);
+
+        thisRef.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (), "privProp1"), new CodeArgumentReferenceExpression ("value")));
+        thisRef.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (), "privProp1")));
+        class1.Members.Add (thisRef);
+
+
+        // 1) protected
+        //     GENERATE (C#):
+        AddScenario ("CheckprotPropMethod");
+        CodeMemberMethod protPropMethod = new CodeMemberMethod ();
+        protPropMethod.Name = "protPropMethod";
+        protPropMethod.ReturnType = new CodeTypeReference (typeof (int));
+        protPropMethod.Attributes = MemberAttributes.Public;
+        CodeParameterDeclarationExpression param2 = new CodeParameterDeclarationExpression (typeof (int), "value");
+        protPropMethod.Parameters.Add (param2);
+
+        protPropMethod.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (), "protProp1"), new CodeArgumentReferenceExpression ("value")));
+        protPropMethod.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (), "protProp1")));
+        class1.Members.Add (protPropMethod);
+
+        // 1) internal
+        //     GENERATE (C#):
+        AddScenario ("CheckinternalPropMethod");
+        CodeMemberMethod internalPropMethod = new CodeMemberMethod ();
+        internalPropMethod.Name = "internalPropMethod";
+        internalPropMethod.ReturnType = new CodeTypeReference (typeof (int));
+        internalPropMethod.Attributes = MemberAttributes.Public;
+        CodeParameterDeclarationExpression param3 = new CodeParameterDeclarationExpression (typeof (int), "value");
+        internalPropMethod.Parameters.Add (param3);
+
+        internalPropMethod.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (), "internalProp"), new CodeArgumentReferenceExpression ("value")));
+        internalPropMethod.Statements.Add (new CodeMethodReturnStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (), "internalProp")));
+        class1.Members.Add (internalPropMethod);
+
+        // 2) set value
+        //     GENERATE (C#):
+        //        public virtual int setProp(int value) {
+        //            prop1 = value;
+        //            return int1;
+        //        }
+        AddScenario ("ChecksetProp");
+        CodeMemberMethod setProp = new CodeMemberMethod ();
+        setProp.Name = "setProp";
+        setProp.ReturnType = new CodeTypeReference (typeof (int));
+        setProp.Attributes = MemberAttributes.Public;
+        CodeParameterDeclarationExpression intParam = new CodeParameterDeclarationExpression (typeof (int), "value");
+        setProp.Parameters.Add (intParam);
+
+        setProp.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeThisReferenceExpression (), "prop1"), new CodeArgumentReferenceExpression ("value")));
+        setProp.Statements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (null, "int1")));
+        class1.Members.Add (setProp);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateTest", "Find and instantiate Test.");
+        if (!FindAndInstantiate ("NS.Test", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTest");
+
+
+        int i1 = 392;
+        if (VerifyMethod (genType, genObject, "thisRef", new object[] {i1}, i1 + 1)) {
+            VerifyScenario ("CheckthisRef");
+        }
+
+        int i3 = -213;
+        if (VerifyPropertySet (genType, genObject, "prop1", i3) &&
+                VerifyPropertyGet (genType, genObject, "prop1", i3 + 1)) {
+            VerifyScenario ("Checkprop1");
+        }
+
+        if (VerifyPropertyGet (genType, genObject, "constStaticProp", 99)) {
+            VerifyScenario ("CheckconstStaticProp");
+        }
+
+        if (VerifyMethod (genType, genObject, "protPropMethod", new object[] {2317}, 2318)) {
+            VerifyScenario ("CheckprotPropMethod");
+        }
+
+        if (VerifyMethod (genType, genObject, "internalPropMethod", new object[] {1}, 2)) {
+            VerifyScenario ("CheckinternalPropMethod");
+        }
+
+        if (VerifyPropertyGet (genType, genObject, "Text", "Hello World")) {
+            VerifyScenario ("CheckText");
+        }
+
+        if (VerifyMethod (genType, genObject, "setProp", new object[] {1}, 1)) {
+            VerifyScenario ("ChecksetProp");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/regiondirectivetest.cs b/workyard/tests/codedom/tests/regiondirectivetest.cs
new file mode 100755
index 0000000..4381549
--- /dev/null
+++ b/workyard/tests/codedom/tests/regiondirectivetest.cs
@@ -0,0 +1,597 @@
+// F#: No regions in F#
+
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text.RegularExpressions;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.JScript;
+
+
+public class RegionDirectiveTest : CodeDomTestTree {
+
+		public override string Comment
+		{
+			get { return "#region isn't supported by F#"; }
+		}		
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Whidbey;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "RegionDirectiveTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests region directives on various code constructs.";
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldSearch {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return false;
+        }
+    }
+
+    public override CodeGeneratorOptions GetGeneratorOptions (CodeDomProvider provider) {
+        CodeGeneratorOptions generatorOptions = base.GetGeneratorOptions (provider);
+#if WHIDBEY
+        generatorOptions.VerbatimOrder = true;
+#endif
+        return generatorOptions;
+    }
+
+    public override CompilerParameters GetCompilerParameters (CodeDomProvider provider) {
+        CompilerParameters parms = base.GetCompilerParameters (provider);
+        parms.GenerateExecutable = true;
+        return parms;
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+#if WHIDBEY
+        if (!(provider is JScriptCodeProvider)) {
+            // GENERATES (C#):
+            //
+            //  #region Compile Unit Region
+            //  
+            //  namespace Namespace1 {
+            //      
+            //      
+            //      #region Outer Type Region
+            //      // Outer Type Comment
+            //      public class Class1 {
+            //          
+            //          // Field 1 Comment
+            //          private string field1;
+            //          
+            //          public void Method1() {
+            //              this.Event1(this, System.EventArgs.Empty);
+            //          }
+            //          
+            //          #region Constructor Region
+            //          public Class1() {
+            //              #region Statements Region
+            //              this.field1 = "value1";
+            //              this.field2 = "value2";
+            //              #endregion
+            //          }
+            //          #endregion
+            //          
+            //          public string Property1 {
+            //              get {
+            //                  return this.field1;
+            //              }
+            //          }
+            //          
+            //          public static void Main() {
+            //          }
+            //          
+            //          public event System.EventHandler Event1;
+            //          
+            //          public class NestedClass1 {
+            //          }
+            //          
+            //          public delegate void nestedDelegate1(object sender, System.EventArgs e);
+            //          
+            //  
+            //          
+            //          #region Field Region
+            //          private string field2;
+            //          #endregion
+            //          
+            //          #region Method Region
+            //          // Method 2 Comment
+            //          
+            //          #line 500 "MethodLinePragma.txt"
+            //          public void Method2() {
+            //              this.Event2(this, System.EventArgs.Empty);
+            //          }
+            //          
+            //          #line default
+            //          #line hidden
+            //          #endregion
+            //          
+            //          public Class1(string value1, string value2) {
+            //          }
+            //          
+            //          #region Property Region
+            //          public string Property2 {
+            //              get {
+            //                  return this.field2;
+            //              }
+            //          }
+            //          #endregion
+            //          
+            //          #region Type Constructor Region
+            //          static Class1() {
+            //          }
+            //          #endregion
+            //          
+            //          #region Event Region
+            //          public event System.EventHandler Event2;
+            //          #endregion
+            //          
+            //          #region Nested Type Region
+            //          // Nested Type Comment
+            //          
+            //          #line 400 "NestedTypeLinePragma.txt"
+            //          public class NestedClass2 {
+            //          }
+            //          
+            //          #line default
+            //          #line hidden
+            //          #endregion
+            //          
+            //          #region Delegate Region
+            //          public delegate void nestedDelegate2(object sender, System.EventArgs e);
+            //          #endregion
+            //          
+            //          #region Snippet Region
+            //  
+            //          #endregion
+            //      }
+            //      #endregion
+            //  }
+            //  #endregion
+
+            CodeNamespace ns = new CodeNamespace ("Namespace1");
+
+            cu.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Compile Unit Region"));
+            cu.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+            cu.Namespaces.Add (ns);
+
+            CodeTypeDeclaration cd = new CodeTypeDeclaration ("Class1");
+            ns.Types.Add (cd);
+
+            cd.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Outer Type Region"));
+            cd.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+            cd.Comments.Add (new CodeCommentStatement ("Outer Type Comment"));
+
+            CodeMemberField field1 = new CodeMemberField (typeof (String), "field1");
+            CodeMemberField field2 = new CodeMemberField (typeof (String), "field2");
+            field1.Comments.Add (new CodeCommentStatement ("Field 1 Comment"));
+            field2.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Field Region"));
+            field2.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+            CodeMemberEvent evt1 = new CodeMemberEvent ();
+            evt1.Name = "Event1";
+            evt1.Type = new CodeTypeReference (typeof (System.EventHandler));
+            evt1.Attributes = (evt1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+
+            CodeMemberEvent evt2 = new CodeMemberEvent ();
+            evt2.Name = "Event2";
+            evt2.Type = new CodeTypeReference (typeof (System.EventHandler));
+            evt2.Attributes = (evt2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+
+            evt2.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Event Region"));
+            evt2.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+
+            CodeMemberMethod method1 = new CodeMemberMethod ();
+            method1.Name = "Method1";
+            method1.Attributes = (method1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            if (provider.Supports (GeneratorSupport.DeclareEvents)) {
+                method1.Statements.Add (
+                    new CodeDelegateInvokeExpression (
+                        new CodeEventReferenceExpression (new CodeThisReferenceExpression (), "Event1"),
+                        new CodeExpression[] {
+                        new CodeThisReferenceExpression(),
+                        new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("System.EventArgs"), "Empty")
+                    }));
+            }
+
+
+            CodeMemberMethod method2 = new CodeMemberMethod ();
+            method2.Name = "Method2";
+            method2.Attributes = (method2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            if (provider.Supports (GeneratorSupport.DeclareEvents)) {
+                method2.Statements.Add (
+                    new CodeDelegateInvokeExpression (
+                        new CodeEventReferenceExpression (new CodeThisReferenceExpression (), "Event2"),
+                        new CodeExpression[] {
+                        new CodeThisReferenceExpression(),
+                        new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("System.EventArgs"), "Empty")
+                    }));
+            }
+            method2.LinePragma = new CodeLinePragma ("MethodLinePragma.txt", 500);
+            method2.Comments.Add (new CodeCommentStatement ("Method 2 Comment"));
+
+            method2.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Method Region"));
+            method2.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+
+            CodeMemberProperty property1 = new CodeMemberProperty ();
+            property1.Name = "Property1";
+            property1.Type = new CodeTypeReference (typeof (string));
+            property1.Attributes = (property1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            property1.GetStatements.Add (
+                new CodeMethodReturnStatement (
+                    new CodeFieldReferenceExpression (
+                        new CodeThisReferenceExpression (),
+                        "field1")));
+
+            CodeMemberProperty property2 = new CodeMemberProperty ();
+            property2.Name = "Property2";
+            property2.Type = new CodeTypeReference (typeof (string));
+            property2.Attributes = (property2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            property2.GetStatements.Add (
+                new CodeMethodReturnStatement (
+                    new CodeFieldReferenceExpression (
+                        new CodeThisReferenceExpression (),
+                        "field2")));
+
+            property2.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Property Region"));
+            property2.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+
+            CodeConstructor constructor1 = new CodeConstructor ();
+            constructor1.Attributes = (constructor1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            CodeStatement conState1 = new CodeAssignStatement (
+                                        new CodeFieldReferenceExpression (
+                                            new CodeThisReferenceExpression (),
+                                            "field1"),
+                                        new CodePrimitiveExpression ("value1"));
+            conState1.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Statements Region"));
+            constructor1.Statements.Add (conState1);
+            CodeStatement conState2 = new CodeAssignStatement (
+                                        new CodeFieldReferenceExpression (
+                                            new CodeThisReferenceExpression (),
+                                            "field2"),
+                                        new CodePrimitiveExpression ("value2"));
+            conState2.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+            constructor1.Statements.Add (conState2);
+
+            constructor1.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Constructor Region"));
+            constructor1.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+            CodeConstructor constructor2 = new CodeConstructor ();
+            constructor2.Attributes = (constructor2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            constructor2.Parameters.Add (new CodeParameterDeclarationExpression (typeof (string), "value1"));
+            constructor2.Parameters.Add (new CodeParameterDeclarationExpression (typeof (string), "value2"));
+
+            CodeTypeConstructor typeConstructor2 = new CodeTypeConstructor ();
+
+            typeConstructor2.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Type Constructor Region"));
+            typeConstructor2.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+
+            CodeEntryPointMethod methodMain = new CodeEntryPointMethod ();
+
+            CodeTypeDeclaration nestedClass1 = new CodeTypeDeclaration ("NestedClass1");
+            CodeTypeDeclaration nestedClass2 = new CodeTypeDeclaration ("NestedClass2");
+            nestedClass2.LinePragma = new CodeLinePragma ("NestedTypeLinePragma.txt", 400);
+            nestedClass2.Comments.Add (new CodeCommentStatement ("Nested Type Comment"));
+
+            nestedClass2.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Nested Type Region"));
+            nestedClass2.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+
+
+            CodeTypeDelegate delegate1 = new CodeTypeDelegate ();
+            delegate1.Name = "nestedDelegate1";
+            delegate1.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference ("System.Object"), "sender"));
+            delegate1.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference ("System.EventArgs"), "e"));
+
+            CodeTypeDelegate delegate2 = new CodeTypeDelegate ();
+            delegate2.Name = "nestedDelegate2";
+            delegate2.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference ("System.Object"), "sender"));
+            delegate2.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference ("System.EventArgs"), "e"));
+
+            delegate2.StartDirectives.Add (new CodeRegionDirective (CodeRegionMode.Start, "Delegate Region"));
+            delegate2.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+
+            CodeSnippetTypeMember snippet1 = new CodeSnippetTypeMember ();
+            CodeSnippetTypeMember snippet2 = new CodeSnippetTypeMember ();
+
+            CodeRegionDirective regionStart = new CodeRegionDirective (CodeRegionMode.End, "");
+            regionStart.RegionText = "Snippet Region";
+            regionStart.RegionMode = CodeRegionMode.Start;
+            snippet2.StartDirectives.Add (regionStart);
+            snippet2.EndDirectives.Add (new CodeRegionDirective (CodeRegionMode.End, string.Empty));
+
+
+            cd.Members.Add (field1);
+            cd.Members.Add (method1);
+            cd.Members.Add (constructor1);
+            cd.Members.Add (property1);
+            cd.Members.Add (methodMain);
+
+            if (Supports (provider, GeneratorSupport.DeclareEvents)) {
+                cd.Members.Add (evt1);
+            }
+
+            if (Supports (provider, GeneratorSupport.NestedTypes)) {
+                cd.Members.Add (nestedClass1);
+                if (Supports (provider, GeneratorSupport.DeclareDelegates)) {
+                    cd.Members.Add (delegate1);
+                }
+            }
+
+            cd.Members.Add (snippet1);
+
+            cd.Members.Add (field2);
+            cd.Members.Add (method2);
+            cd.Members.Add (constructor2);
+            cd.Members.Add (property2);
+
+
+            if (Supports (provider, GeneratorSupport.StaticConstructors)) {
+                cd.Members.Add (typeConstructor2);
+            }
+
+            if (Supports (provider, GeneratorSupport.DeclareEvents)) {
+                cd.Members.Add (evt2);
+            }
+            if (Supports (provider, GeneratorSupport.NestedTypes)) {
+                cd.Members.Add (nestedClass2);
+                if (Supports (provider, GeneratorSupport.DeclareDelegates)) {
+                    cd.Members.Add (delegate2);
+                }
+            }
+            cd.Members.Add (snippet2);
+        }
+#endif
+    }
+
+    private string[] GetScenarios (CodeDomProvider provider, bool verbatimOrder) {
+        ArrayList arrList = new ArrayList();
+
+        if(verbatimOrder) {
+            arrList.Add("FindCompileUnitRegion");
+            AddScenario("FindCompileUnitRegion");
+            arrList.Add("FindOuterTypeRegion");
+            AddScenario("FindOuterTypeRegion");
+            arrList.Add("FindConstructorRegion");
+            AddScenario("FindConstructorRegion");
+            if (!(provider is Microsoft.VisualBasic.VBCodeProvider)) { 
+                arrList.Add("FindStatementsRegion");
+                AddScenario("FindStatementsRegion");
+                arrList.Add("FindEndRegion1");
+                AddScenario("FindEndRegion1");
+            }
+            arrList.Add("FindEndRegion2");
+            AddScenario("FindEndRegion2");
+            arrList.Add("FindFieldRegion");
+            AddScenario("FindFieldRegion");
+            arrList.Add("FindEndRegion3");
+            AddScenario("FindEndRegion3");
+            arrList.Add("FindMethodRegion");
+            AddScenario("FindMethodRegion");
+            arrList.Add("FindEndRegion4");
+            AddScenario("FindEndRegion4");
+            arrList.Add("FindPropertyRegion");
+            AddScenario("FindPropertyRegion");
+            arrList.Add("FindEndRegion5");
+            AddScenario("FindEndRegion5");
+            arrList.Add("FindTypeConstructorRegion");
+            AddScenario("FindTypeConstructorRegion");
+            arrList.Add("FindEndRegion6");
+            AddScenario("FindEndRegion6");
+            arrList.Add("FindEventRegion");
+            AddScenario("FindEventRegion");
+            arrList.Add("FindEndRegion7");
+            AddScenario("FindEndRegion7");
+            arrList.Add("FindNestedTypeRegion");
+            AddScenario("FindNestedTypeRegion");
+            arrList.Add("FindEndRegion8");
+            AddScenario("FindEndRegion8");
+            arrList.Add("FindDelegateRegion");
+            AddScenario("FindDelegateRegion");
+            arrList.Add("FindEndRegion9");
+            AddScenario("FindEndRegion9");
+            arrList.Add("FindSnippetRegion");
+            AddScenario("FindSnippetRegion");
+            arrList.Add("FindEndRegion10");
+            AddScenario("FindEndRegion10");
+            arrList.Add("FindEndRegion11");
+            AddScenario("FindEndRegion11");
+            arrList.Add("FindEndRegion12");
+            AddScenario("FindEndRegion12");
+        } else {
+            arrList.Add("FindCompileUnitRegion");
+            AddScenario("FindCompileUnitRegion");
+            arrList.Add("FindOuterTypeRegion");
+            AddScenario("FindOuterTypeRegion");
+            arrList.Add("FindFieldRegion");
+            AddScenario("FindFieldRegion");
+            arrList.Add("FindEndRegion1");
+            AddScenario("FindEndRegion1");
+            arrList.Add("FindSnippetRegion");
+            AddScenario("FindSnippetRegion");
+            arrList.Add("FindEndRegion2");
+            AddScenario("FindEndRegion2");
+            arrList.Add("FindTypeConstructorRegion");
+            AddScenario("FindTypeConstructorRegion");
+            arrList.Add("FindEndRegion3");
+            AddScenario("FindEndRegion3");
+            arrList.Add("FindConstructorRegion");
+            AddScenario("FindConstructorRegion");
+            if (!(provider is Microsoft.VisualBasic.VBCodeProvider)) { 
+                arrList.Add("FindStatementsRegion");
+                AddScenario("FindStatementsRegion");
+                arrList.Add("FindEndRegion4");
+                AddScenario("FindEndRegion4");
+            }
+            arrList.Add("FindEndRegion5");
+            AddScenario("FindEndRegion5");
+            arrList.Add("FindPropertyRegion");
+            AddScenario("FindPropertyRegion");
+            arrList.Add("FindEndRegion6");
+            AddScenario("FindEndRegion6");
+            arrList.Add("FindEventRegion");
+            AddScenario("FindEventRegion");
+            arrList.Add("FindEndRegion7");
+            AddScenario("FindEndRegion7");
+            arrList.Add("FindMethodRegion");
+            AddScenario("FindMethodRegion");
+            arrList.Add("FindEndRegion8");
+            AddScenario("FindEndRegion8");
+            arrList.Add("FindNestedTypeRegion");
+            AddScenario("FindNestedTypeRegion");
+            arrList.Add("FindEndRegion9");
+            AddScenario("FindEndRegion9");
+            arrList.Add("FindDelegateRegion");
+            AddScenario("FindDelegateRegion");
+            arrList.Add("FindEndRegion10");
+            AddScenario("FindEndRegion10");
+            arrList.Add("FindEndRegion11");
+            AddScenario("FindEndRegion11");
+        }
+        return(string[]) arrList.ToArray(typeof(string)) ;
+    }
+
+    private string[] GetTokenOrder (CodeDomProvider provider, bool verbatimOrder) {
+        ArrayList arrList = new ArrayList();
+
+        if (verbatimOrder) {
+            arrList.Add(AddBeginRegion (provider, "Compile Unit Region"));
+            arrList.Add(AddBeginRegion (provider, "Outer Type Region"));
+            arrList.Add(AddBeginRegion (provider, "Constructor Region"));
+            if (!(provider is Microsoft.VisualBasic.VBCodeProvider)) { 
+                arrList.Add(AddBeginRegion (provider, "Statements Region"));
+                arrList.Add(AddEndRegion (provider));
+            }
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Field Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Method Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Property Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Type Constructor Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Event Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Nested Type Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Delegate Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Snippet Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddEndRegion (provider));
+        } else {
+            arrList.Add(AddBeginRegion (provider, "Compile Unit Region"));
+            arrList.Add(AddBeginRegion (provider, "Outer Type Region"));
+            arrList.Add(AddBeginRegion (provider, "Field Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Snippet Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Type Constructor Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Constructor Region"));
+            if (!(provider is Microsoft.VisualBasic.VBCodeProvider)) { 
+                arrList.Add(AddBeginRegion (provider, "Statements Region"));
+                arrList.Add(AddEndRegion (provider));
+            }
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Property Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Event Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Method Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Nested Type Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddBeginRegion (provider, "Delegate Region"));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddEndRegion (provider));
+            arrList.Add(AddEndRegion (provider));
+        }
+        return (string[]) arrList.ToArray(typeof(string)) ;
+    }
+    
+    public string AddBeginRegion (CodeDomProvider provider, string regionText)  {
+        string regionFind = String.Empty;
+
+        if (provider is Microsoft.CSharp.CSharpCodeProvider)
+            regionFind = String.Format ("#region {0}", regionText);
+        else if (provider is Microsoft.VisualBasic.VBCodeProvider) 
+            regionFind = String.Format ("#Region \"{0}\"", regionText);
+        else
+            regionFind = regionText;
+
+        return regionFind; 
+    }
+
+    public string AddEndRegion (CodeDomProvider provider)  {
+        string regionFind = String.Empty;
+
+        if (provider is Microsoft.CSharp.CSharpCodeProvider)            
+            regionFind = "#endregion";
+        else if (provider is Microsoft.VisualBasic.VBCodeProvider) 
+            regionFind = "#End Region";
+
+        return regionFind; 
+    }
+
+    public override void Search (CodeDomProvider provider, string strGeneratedCode)  {
+#if WHIDBEY
+        if (!(provider is JScriptCodeProvider)) {
+            int searchIndex = 0;
+
+            string[] tokens = GetTokenOrder (provider, true);
+            string[] scenarios = GetScenarios (provider, true);
+
+            for (int i = 0; i < tokens.Length; i++) {
+                searchIndex = strGeneratedCode.IndexOf (tokens[i], searchIndex);
+                if (searchIndex > -1) {
+                    searchIndex += tokens[i].Length;
+                    VerifyScenario (scenarios[i]);
+                }
+                else
+                    break;
+            }
+        }
+#endif
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+    }
+}	
\ No newline at end of file
diff --git a/workyard/tests/codedom/tests/structtest.cs b/workyard/tests/codedom/tests/structtest.cs
new file mode 100755
index 0000000..4471be5
--- /dev/null
+++ b/workyard/tests/codedom/tests/structtest.cs
@@ -0,0 +1,174 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using System.Drawing;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class StructTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "StructTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests structs";
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // create a namespace
+        CodeNamespace ns = new CodeNamespace ("NS");
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        ns.Imports.Add (new CodeNamespaceImport ("System.Drawing"));
+        cu.Namespaces.Add (ns);
+
+        cu.ReferencedAssemblies.Add ("System.Drawing.dll");
+
+        // create a class
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "Test";
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+        if (Supports (provider, GeneratorSupport.DeclareValueTypes)) {
+
+            // create first struct to test nested structs
+            //     GENERATE (C#):
+            //	public struct structA {
+            //		public structB innerStruct;
+            //		public struct structB {
+            //    		public int int1;
+            //		}
+            //	}
+            CodeTypeDeclaration structA = new CodeTypeDeclaration ("structA");
+            structA.IsStruct = true;
+
+            CodeTypeDeclaration structB = new CodeTypeDeclaration ("structB");
+            structB.Attributes = MemberAttributes.Public;
+            structB.IsStruct = true;
+
+            CodeMemberField firstInt = new CodeMemberField (typeof (int), "int1");
+            firstInt.Attributes = MemberAttributes.Public;
+            structB.Members.Add (firstInt);
+
+            CodeMemberField innerStruct = new CodeMemberField ("structB", "innerStruct");
+            innerStruct.Attributes = MemberAttributes.Public;
+
+            structA.Members.Add (structB);
+            structA.Members.Add (innerStruct);
+            class1.Members.Add (structA);
+
+            // create second struct to test tructs of non-primitive types
+            //     GENERATE (C#):
+            //         public struct structC {
+            //              public Point pt1;
+            //              public Point pt2;
+            //         }
+            CodeTypeDeclaration structC = new CodeTypeDeclaration ("structC");
+            structC.IsStruct = true;
+
+            CodeMemberField firstPt = new CodeMemberField ("Point", "pt1");
+            firstPt.Attributes = MemberAttributes.Public;
+            structC.Members.Add (firstPt);
+
+            CodeMemberField secondPt = new CodeMemberField ("Point", "pt2");
+            secondPt.Attributes = MemberAttributes.Public;
+            structC.Members.Add (secondPt);
+            class1.Members.Add (structC);
+
+            // create method to test nested struct
+            //     GENERATE (C#):
+            //          public static int NestedStructMethod() {
+            //               structA varStructA;
+            //               varStructA.innerStruct.int1 = 3;
+            //               return varStructA.innerStruct.int1;
+            //          }
+            AddScenario ("CheckNestedStructMethod");
+            CodeMemberMethod nestedStructMethod = new CodeMemberMethod ();
+            nestedStructMethod.Name = "NestedStructMethod";
+            nestedStructMethod.ReturnType = new CodeTypeReference (typeof (int));
+            nestedStructMethod.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            CodeVariableDeclarationStatement varStructA = new CodeVariableDeclarationStatement ("structA", "varStructA");
+            nestedStructMethod.Statements.Add (varStructA);
+            nestedStructMethod.Statements.Add (
+                new CodeAssignStatement (
+                /* Expression1 */ new CodeFieldReferenceExpression (new CodeFieldReferenceExpression (new CodeVariableReferenceExpression ("varStructA"), "innerStruct"), "int1"),
+                /* Expression1 */ new CodePrimitiveExpression (3))
+                );
+            nestedStructMethod.Statements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeFieldReferenceExpression (new CodeVariableReferenceExpression ("varStructA"), "innerStruct"), "int1")));
+            class1.Members.Add (nestedStructMethod);
+
+
+            // create method to test nested non primitive struct member
+            //     GENERATE (C#):
+            //          public static System.Drawing.Point NonPrimitiveStructMethod() {
+            //               structC varStructC;
+            //               varStructC.pt1 = new Point(1, -1);
+            //               return varStructC.pt1;
+            //          }
+            AddScenario ("CheckNonPrimitiveStructMethod");
+            CodeMemberMethod nonPrimitiveStructMethod = new CodeMemberMethod ();
+            nonPrimitiveStructMethod.Name = "NonPrimitiveStructMethod";
+            nonPrimitiveStructMethod.ReturnType = new CodeTypeReference (typeof (Point));
+            nonPrimitiveStructMethod.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            CodeVariableDeclarationStatement varStructC = new CodeVariableDeclarationStatement ("structC", "varStructC");
+            nonPrimitiveStructMethod.Statements.Add (varStructC);
+            nonPrimitiveStructMethod.Statements.Add (
+                new CodeAssignStatement (
+                /* Expression1 */ new CodeFieldReferenceExpression (
+                new CodeVariableReferenceExpression ("varStructC"),
+                "pt1"),
+                /* Expression2 */ new CodeObjectCreateExpression ("Point", new CodeExpression[] {new CodePrimitiveExpression (1), new CodePrimitiveExpression (-1)})
+                ));
+            nonPrimitiveStructMethod.Statements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeVariableReferenceExpression ("varStructC"), "pt1")));
+            class1.Members.Add (nonPrimitiveStructMethod);
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        if (Supports (provider, GeneratorSupport.DeclareValueTypes)) {
+            object genObject;
+            Type   genType;
+
+            AddScenario ("InstantiateTest", "Find and instantiate Test.");
+            if (!FindAndInstantiate ("NS.Test", asm, out genObject, out genType))
+                return;
+            VerifyScenario ("InstantiateTest");
+
+            // verify goto which jumps ahead to label with statement 
+            if (VerifyMethod (genType, genObject, "NestedStructMethod", new object[] {}, 3)) {
+                VerifyScenario ("CheckNestedStructMethod");
+            }
+
+            if (VerifyMethod (genType, genObject, "NonPrimitiveStructMethod", new object[] {}, new Point (1, -1))) {
+                VerifyScenario ("CheckNonPrimitiveStructMethod");
+            }
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/subsetarraytest.cs b/workyard/tests/codedom/tests/subsetarraytest.cs
new file mode 100755
index 0000000..f2691f5
--- /dev/null
+++ b/workyard/tests/codedom/tests/subsetarraytest.cs
@@ -0,0 +1,174 @@
+// F#: test originally generated: (a:int[]).[0] + (b:int64[]).[0] 
+//     which is incorrect, so I changed all numerical types to int
+
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class SubsetArrayTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "SubsetArrayTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests arrays while conforming to the subset.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        CodeNamespace ns = new CodeNamespace ("Namespace1");
+        cu.Namespaces.Add (ns);
+
+        // Generate Class1
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ("Class1");
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        // GENERATES (C#):
+        //       public int ArrayMethod(int parameter) {
+        //                int arraySize = 3;
+        //                int[] array1;
+        //                int[] array2 = new int[3];
+        //                int[] array3 = new int[] {1,
+        //                        4,
+        //                        9};
+        //                array1 = new int[arraySize];
+        //                int retValue = 0;
+        //                int i;
+        //                for (i = 0; (i < array1.Length); i = (i + 1)) {
+        //                    array1[i] = (i * i);
+        //                    array2[i] = (array1[i] - i);
+        //                    retValue = retValue + array1[i];
+        //                    retValue = retValue + array2[i];
+        //                    retValue = retValue + array3[i];
+        //                }
+        //                return retValue;
+        //            }
+        AddScenario ("ArrayMethod", "Tests sized arrays, initialized arrays, standard arrays of small size");
+        CodeMemberMethod arrayMethod = new CodeMemberMethod ();
+        arrayMethod.Name = "ArrayMethod";
+        arrayMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "parameter"));
+        arrayMethod.Attributes = (arrayMethod.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        arrayMethod.ReturnType = new CodeTypeReference (typeof (System.Int32));
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (typeof (int), "arraySize", new CodePrimitiveExpression (3)));
+
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (typeof (int[]), "array1"));
+
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (
+            new CodeTypeReference ("System.Int32", 1),
+            "array2",
+            new CodeArrayCreateExpression (typeof (int[]), new CodePrimitiveExpression (3))));
+
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (
+            new CodeTypeReference ("System.Int32", 1),
+            "array3",
+            new CodeArrayCreateExpression (
+            new CodeTypeReference ("System.Int32", 1),
+            new CodeExpression[] {
+                new CodePrimitiveExpression (1),
+                new CodePrimitiveExpression (4),
+                new CodePrimitiveExpression (9)})));
+
+        arrayMethod.Statements.Add (
+            new CodeAssignStatement (
+            new CodeVariableReferenceExpression ("array1"),
+            new CodeArrayCreateExpression (typeof (int[]), new CodeVariableReferenceExpression ("arraySize"))));
+
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (typeof (System.Int32), "retValue", new CodePrimitiveExpression (0)));
+
+        arrayMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (typeof (int), "i"));
+
+        arrayMethod.Statements.Add (
+            new CodeIterationStatement (
+            new CodeAssignStatement (new CodeVariableReferenceExpression ("i"), new CodePrimitiveExpression (0)),
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("i"),
+            CodeBinaryOperatorType.LessThan,
+            new CodePropertyReferenceExpression (
+            new CodeVariableReferenceExpression ("array1"),
+            "Length")),
+            new CodeAssignStatement (
+            new CodeVariableReferenceExpression ("i"),
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("i"),
+            CodeBinaryOperatorType.Add,
+            new CodePrimitiveExpression (1))),
+            new CodeAssignStatement (
+            new CodeArrayIndexerExpression (
+            new CodeVariableReferenceExpression ("array1"),
+            new CodeVariableReferenceExpression ("i")),
+            new CodeBinaryOperatorExpression (
+            new CodeVariableReferenceExpression ("i"),
+            CodeBinaryOperatorType.Multiply,
+            new CodeVariableReferenceExpression ("i"))),
+            new CodeAssignStatement (
+            new CodeArrayIndexerExpression (
+            new CodeVariableReferenceExpression ("array2"),
+            new CodeVariableReferenceExpression ("i")),
+            new CodeBinaryOperatorExpression (
+            new CodeArrayIndexerExpression (
+            new CodeVariableReferenceExpression ("array1"),
+            new CodeVariableReferenceExpression ("i")),
+            CodeBinaryOperatorType.Subtract,
+            new CodeVariableReferenceExpression ("i"))),
+            CDHelper.CreateIncrementByStatement ("retValue",
+                    CDHelper.CreateArrayRef ("array1", "i")),
+            CDHelper.CreateIncrementByStatement ("retValue",
+                    CDHelper.CreateArrayRef ("array2", "i")),
+            CDHelper.CreateIncrementByStatement ("retValue",
+                    CDHelper.CreateArrayRef ("array3", "i"))));
+
+        arrayMethod.Statements.Add (
+            new CodeMethodReturnStatement (new CodeVariableReferenceExpression ("retValue")));
+        class1.Members.Add (arrayMethod);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateClass1", "Make sure Class1 was instantiated before doing anything.");
+        if (!FindAndInstantiate ("Namespace1.Class1", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClass1");
+
+        // Verify Array Operations
+        if (VerifyMethod (genType, genObject, "ArrayMethod", new object[] {0}, 21))
+            VerifyScenario ("ArrayMethod");
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/subsetattributestest.cs b/workyard/tests/codedom/tests/subsetattributestest.cs
new file mode 100755
index 0000000..4db6778
--- /dev/null
+++ b/workyard/tests/codedom/tests/subsetattributestest.cs
@@ -0,0 +1,321 @@
+// F#: The CodeDOM provider ignores type constructors (static constructors), 
+//     but this is handled because test suite checks for "Supports" flags
+//
+//     Next issue is that F# generates properties instead of fields (modified lookup in the test)
+
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using System.Xml.Serialization;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.CSharp;
+using Microsoft.VisualBasic;
+using Microsoft.JScript;
+
+public class SubsetAttributesTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "SubsetAttributesTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests metadata attributes while staying in the subset.";
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // GENERATES (C#):
+        // [assembly: System.Reflection.AssemblyTitle("MyAssembly")]
+        // [assembly: System.Reflection.AssemblyVersion("1.0.6.2")]
+        // [assembly: System.CLSCompliantAttribute(false)]
+        // 
+        // namespace MyNamespace {
+        //     using System;
+        //     using System.Drawing;
+        //     using System.Windows.Forms;
+        //     using System.ComponentModel;
+        //
+        CodeNamespace ns = new CodeNamespace ();
+        ns.Name = "MyNamespace";
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        ns.Imports.Add (new CodeNamespaceImport ("System.Drawing"));
+        ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+        ns.Imports.Add (new CodeNamespaceImport ("System.ComponentModel"));
+        cu.Namespaces.Add (ns);
+
+        cu.ReferencedAssemblies.Add ("System.Xml.dll");
+        cu.ReferencedAssemblies.Add ("System.Drawing.dll");
+        cu.ReferencedAssemblies.Add ("System.Windows.Forms.dll");
+
+        // Assembly Attributes
+        if (Supports (provider, GeneratorSupport.AssemblyAttributes)) {
+            AddScenario ("CheckAssemblyAttributes", "Check that assembly attributes get generated properly.");
+            CodeAttributeDeclarationCollection attrs = cu.AssemblyCustomAttributes;
+            attrs.Add (new CodeAttributeDeclaration ("System.Reflection.AssemblyTitle", new
+                CodeAttributeArgument (new CodePrimitiveExpression ("MyAssembly"))));
+            attrs.Add (new CodeAttributeDeclaration ("System.Reflection.AssemblyVersion", new
+                CodeAttributeArgument (new CodePrimitiveExpression ("1.0.6.2"))));
+            attrs.Add (new CodeAttributeDeclaration ("System.CLSCompliantAttribute", new
+                CodeAttributeArgument (new CodePrimitiveExpression (false))));
+        }
+
+        // GENERATES (C#):
+        //     [System.Serializable()]
+        //     [System.Obsolete("Don\'t use this Class")]
+        //     [System.Windows.Forms.AxHost.ClsidAttribute("Class.ID")]
+        //     public class MyClass {
+        //
+
+#if !WHIDBEY
+        if (!(provider is CSharpCodeProvider) && !(provider is VBCodeProvider) && !(provider is JScriptCodeProvider))
+            AddScenario ("CheckClassAttributes", "Check that class attributes get generated properly.");
+#else
+        AddScenario ("CheckClassAttributes", "Check that class attributes get generated properly.");
+#endif
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "MyClass";
+        class1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Serializable"));
+        class1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+            CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Class"))));
+        class1.CustomAttributes.Add (new
+            CodeAttributeDeclaration (typeof (System.Windows.Forms.AxHost.ClsidAttribute).FullName,
+            new CodeAttributeArgument (new CodePrimitiveExpression ("Class.ID"))));
+        ns.Types.Add (class1);
+
+        // GENERATES (C#):
+        //         [System.Obsolete("Don\'t use this Method")]
+        //         [System.ComponentModel.Editor("This", "That")]
+        //         public void MyMethod(string blah, int[] arrayit) {
+        //         }
+        AddScenario ("CheckMyMethodAttributes", "Check that attributes are generated properly on MyMethod().");
+        CodeMemberMethod method1 = new CodeMemberMethod ();
+        method1.Attributes = (method1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        method1.Name = "MyMethod";
+        method1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+            CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Method"))));
+        method1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.ComponentModel.Editor", new
+            CodeAttributeArgument (new CodePrimitiveExpression ("This")), new CodeAttributeArgument (new
+            CodePrimitiveExpression ("That"))));
+        CodeParameterDeclarationExpression param1 = new CodeParameterDeclarationExpression (typeof (string), "blah");
+
+        method1.Parameters.Add (param1);
+        CodeParameterDeclarationExpression param2 = new CodeParameterDeclarationExpression (typeof (int[]), "arrayit");
+
+        method1.Parameters.Add (param2);
+        class1.Members.Add (method1);
+
+        // GENERATES (C#):
+        //         [System.Xml.Serialization.XmlElementAttribute()]
+        //         private string myField = "hi!";
+        //
+        AddScenario ("CheckMyFieldAttributes", "Check that attributes are generated properly on MyField.");
+        CodeMemberField field1 = new CodeMemberField ();
+        field1.Name = "myField";
+        field1.Attributes = MemberAttributes.Public;
+        field1.Type = new CodeTypeReference (typeof (string));
+        field1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Xml.Serialization.XmlElementAttribute"));
+        field1.InitExpression = new CodePrimitiveExpression ("hi!");
+        class1.Members.Add (field1);
+
+
+        // GENERATES (C#):
+        //         [System.Obsolete("Don\'t use this Property")]
+        //         public string MyProperty {
+        //             get {
+        //                 return this.myField;
+        //             }
+        //         }
+        AddScenario ("CheckMyPropertyAttributes", "Check that attributes are generated properly on MyProperty.");
+        CodeMemberProperty prop1 = new CodeMemberProperty ();
+        prop1.Attributes = MemberAttributes.Public;
+        prop1.Name = "MyProperty";
+        prop1.Type = new CodeTypeReference (typeof (string));
+        prop1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+            CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Property"))));
+        prop1.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "myField")));
+        class1.Members.Add (prop1);
+
+        // GENERATES (C#):
+        //         [System.Obsolete("Don\'t use this Constructor")]
+        //         public MyClass() {
+        //         }
+        //     }
+
+        if (!(provider is JScriptCodeProvider))
+            AddScenario ("CheckConstructorAttributes", "Check that attributes are generated properly on the constructor.");
+        CodeConstructor const1 = new CodeConstructor ();
+        const1.Attributes = MemberAttributes.Public;
+        const1.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Obsolete", new
+            CodeAttributeArgument (new CodePrimitiveExpression ("Don't use this Constructor"))));
+        class1.Members.Add (const1);
+
+        if (Supports (provider, GeneratorSupport.DeclareEvents)) {
+            // GENERATES (C#):
+            //     public class Test : Form {
+            //         
+            //         private Button b = new Button();
+            //
+            // 
+            AddScenario ("CheckEventAttributes", "test attributes on an event");
+            class1 = new CodeTypeDeclaration ("Test");
+            class1.IsClass = true;
+            class1.BaseTypes.Add (new CodeTypeReference ("Form"));
+            ns.Types.Add (class1);
+            CodeMemberField mfield = new CodeMemberField (new CodeTypeReference ("Button"), "b");
+            mfield.InitExpression = new CodeObjectCreateExpression (new CodeTypeReference ("Button"));
+            class1.Members.Add (mfield);
+
+            // GENERATES (C#):
+            //         public Test() {
+            //             this.Size = new Size(600, 600);
+            //             b.Text = "Test";
+            //             b.TabIndex = 0;
+            //             b.Location = new Point(400, 525);
+            //             this.MyEvent += new EventHandler(this.b_Click);
+            //         }
+            //
+            CodeConstructor ctor = new CodeConstructor ();
+            ctor.Attributes = MemberAttributes.Public;
+            ctor.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (),
+                "Size"), new CodeObjectCreateExpression (new CodeTypeReference ("Size"),
+                new CodePrimitiveExpression (600), new CodePrimitiveExpression (600))));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Text"), new CodePrimitiveExpression ("Test")));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "TabIndex"), new CodePrimitiveExpression (0)));
+            ctor.Statements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeFieldReferenceExpression (null, "b"),
+                "Location"), new CodeObjectCreateExpression (new CodeTypeReference ("Point"),
+                new CodePrimitiveExpression (400), new CodePrimitiveExpression (525))));
+            ctor.Statements.Add (new CodeAttachEventStatement (new CodeEventReferenceExpression (new
+                CodeThisReferenceExpression (), "MyEvent"), new CodeDelegateCreateExpression (new CodeTypeReference ("EventHandler")
+                , new CodeThisReferenceExpression (), "b_Click")));
+            class1.Members.Add (ctor);
+
+            // GENERATES (C#):
+            //         [System.CLSCompliantAttribute(false)]
+            //         public event System.EventHandler MyEvent;
+            CodeMemberEvent evt = new CodeMemberEvent ();
+            evt.Name = "MyEvent";
+            evt.Type = new CodeTypeReference ("System.EventHandler");
+            evt.Attributes = MemberAttributes.Public;
+            evt.CustomAttributes.Add (new CodeAttributeDeclaration ("System.CLSCompliantAttribute", new CodeAttributeArgument (new CodePrimitiveExpression (false))));
+            class1.Members.Add (evt);
+
+            // GENERATES (C#):
+            //         private void b_Click(object sender, System.EventArgs e) {
+            //         }
+            //     }
+            // }
+            //
+            CodeMemberMethod cmm = new CodeMemberMethod ();
+            cmm.Name = "b_Click";
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (object), "sender"));
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (EventArgs), "e"));
+            class1.Members.Add (cmm);
+        }
+
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        Type genType;
+
+        // Verifying Assembly Attributes
+        if (Supports (provider, GeneratorSupport.AssemblyAttributes)) {
+            object[] attributes = asm.GetCustomAttributes (true);
+            bool verifiedAssemblyAttributes = VerifyAttribute (attributes, typeof (AssemblyTitleAttribute), "Title", "MyAssembly");
+            verifiedAssemblyAttributes &=
+                VerifyAttribute (attributes, typeof (AssemblyVersionAttribute), "Version", "1.0.6.2") ||
+                asm.GetName ().Version.Equals (new Version (1, 0, 6, 2));
+            if (verifiedAssemblyAttributes) {
+                VerifyScenario ("CheckAssemblyAttributes");
+            }
+        }
+
+        object[] customAttributes;
+        object[] customAttributes2;
+        object[] customAttributesAll;
+
+        if (FindType ("MyNamespace.MyClass", asm, out genType)) {
+            customAttributes    = genType.GetCustomAttributes (typeof (System.ObsoleteAttribute), true);
+            customAttributes2   = genType.GetCustomAttributes (typeof (System.SerializableAttribute), true);
+            customAttributesAll = genType.GetCustomAttributes (true);
+
+#if !WHIDBEY
+            if (!(provider is CSharpCodeProvider) && !(provider is VBCodeProvider) && !(provider is JScriptCodeProvider)) {
+#endif
+                if (customAttributes.GetLength (0) == 1 &&
+                        customAttributes2.GetLength (0) >= 1 &&
+                        customAttributesAll.GetLength (0) >= 3) {
+                    VerifyScenario ("CheckClassAttributes");
+                }
+#if !WHIDBEY
+            }
+#endif
+
+            // verify method attributes
+            MethodInfo methodInfo = genType.GetMethod ("MyMethod");
+            if (methodInfo != null &&
+                    methodInfo.GetCustomAttributes (typeof (System.ObsoleteAttribute), true).GetLength (0) > 0 &&
+                    methodInfo.GetCustomAttributes (typeof (System.ComponentModel.EditorAttribute), true).GetLength (0) > 0) {
+                VerifyScenario ("CheckMyMethodAttributes");
+            }
+
+            // verify property attributes
+            PropertyInfo propertyInfo = genType.GetProperty ("MyProperty");
+            if (propertyInfo != null &&
+                    propertyInfo.GetCustomAttributes (typeof (System.ObsoleteAttribute), true).GetLength (0) > 0) {
+                VerifyScenario ("CheckMyPropertyAttributes");
+            }
+
+            // verify constructor attributes
+            ConstructorInfo[] constructorInfo = genType.GetConstructors ();
+            if (constructorInfo != null && constructorInfo.Length > 0 && !(provider is JScriptCodeProvider) &&
+                    constructorInfo[0].GetCustomAttributes (typeof (System.ObsoleteAttribute), true).GetLength (0) > 0) {
+                VerifyScenario ("CheckConstructorAttributes");
+            }
+            // verify field attributes
+            FieldInfo fieldInfo = genType.GetField("myField");
+            if (fieldInfo != null &&
+                    fieldInfo.GetCustomAttributes (typeof (System.Xml.Serialization.XmlElementAttribute), true).GetLength (0) > 0) {
+                VerifyScenario ("CheckMyFieldAttributes");
+            }
+        }
+
+        // verify event attributes
+        if (Supports (provider, GeneratorSupport.DeclareEvents) && FindType ("MyNamespace.Test", asm, out genType)) {
+            EventInfo eventInfo = genType.GetEvent ("MyEvent");
+            if (eventInfo != null &&
+                    eventInfo.GetCustomAttributes (typeof (System.CLSCompliantAttribute), true).GetLength (0) > 0) {
+                VerifyScenario ("CheckEventAttributes");
+            }
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/subsetbinaryoperatorstest.cs b/workyard/tests/codedom/tests/subsetbinaryoperatorstest.cs
new file mode 100755
index 0000000..7ab3caf
--- /dev/null
+++ b/workyard/tests/codedom/tests/subsetbinaryoperatorstest.cs
@@ -0,0 +1,225 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class SubsetBinaryOperatorsTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "SubsetBinaryOperatorsTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests binary operators while staying within the subset spec.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        // GENERATES (C#):
+        //  namespace Namespace1 {
+        //      using System;
+        //      
+        //      
+        //      public class Class1 : object {
+        //          
+        //          public int ReturnMethod(int intInput) {
+
+        AddScenario ("ReturnMethod", "Verifies binary operators in a series of operations.");
+        CodeNamespace ns = new CodeNamespace ("Namespace1");
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (ns);
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "Class1";
+        class1.BaseTypes.Add (new CodeTypeReference (typeof (object)));
+        ns.Types.Add (class1);
+
+        CodeMemberMethod retMethod = new CodeMemberMethod ();
+        retMethod.Name = "ReturnMethod";
+        retMethod.Attributes = (retMethod.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        retMethod.ReturnType = new CodeTypeReference (typeof (int));
+        retMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "intInput"));
+
+        // GENERATES (C#):
+        //              int x1;
+        //              x1 = 6 - 4;
+        //              double x1d = x1;
+        //              x1d = 18 / x1d;
+        //              x1 = (int) x1d;
+        //              x1 = x1 * intInput;
+
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "x1"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("x1", 6, CodeBinaryOperatorType.Subtract, 4));
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (double), "x1d", new CodeVariableReferenceExpression ("x1")));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("x1d", 18, CodeBinaryOperatorType.Divide, "x1d"));
+        retMethod.Statements.Add (new CodeAssignStatement (new CodeVariableReferenceExpression ("x1"),
+                    new CodeCastExpression (typeof (int), new CodeVariableReferenceExpression ("x1d"))));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("x1", "x1", CodeBinaryOperatorType.Multiply,
+                    new CodeArgumentReferenceExpression ("intInput")));
+
+        // GENERATES (C#):
+        //              int x2;
+        //              x2 = (19 % 8);
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "x2"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("x2", 19, CodeBinaryOperatorType.Modulus, 8));
+
+        // GENERATES (C#):
+        //              int x3;
+        //              x3 = 15 & 35;
+        //              x3 = x3 | 129;
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "x3"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("x3", 15, CodeBinaryOperatorType.BitwiseAnd, 35));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("x3", "x3", CodeBinaryOperatorType.BitwiseOr, 129));
+
+        // GENERATES (C#):
+        //              int x4 = 0;
+        retMethod.Statements.Add (
+            new CodeVariableDeclarationStatement (
+            typeof (int),
+            "x4",
+            new CodePrimitiveExpression (0)));
+
+        // GENERATES (C#):
+        //              bool res1;
+        //              res1 = x2 == 3;
+        //              bool res2;
+        //              res2 = x3 < 129;
+        //              bool res3;
+        //              res3 = res1 || res2;
+        //              if (res3) {
+        //                  x4 = (x4 + 1);
+        //              }
+        //              else {
+        //                  x4 = (x4 + 2);
+        //              }
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (bool), "res1"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("res1", "x2", CodeBinaryOperatorType.ValueEquality, 3));
+
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (bool), "res2"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("res2", "x3", CodeBinaryOperatorType.LessThan, 129));
+
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (bool), "res3"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("res3", "res1", CodeBinaryOperatorType.BooleanOr, "res2"));
+
+        retMethod.Statements.Add (
+            new CodeConditionStatement (new CodeVariableReferenceExpression ("res3"),
+            new CodeStatement [] { CDHelper.CreateIncrementByStatement ("x4", 1) },
+            new CodeStatement [] { CDHelper.CreateIncrementByStatement ("x4", 2) }));
+
+        // GENERATES (C#):
+        //              bool res4;
+        //              res4 = x2 > -1;
+        //              bool res5;
+        //              res5 = x3 > 5000;
+        //              bool res6;
+        //              res6 = res4 && res5;
+        //              if (res6) {
+        //                  x4 = (x4 + 4);
+        //              }
+        //              else {
+        //                  x4 = (x4 + 8);
+        //              }
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (bool), "res4"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("res4", "x2", CodeBinaryOperatorType.GreaterThan, -1));
+
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (bool), "res5"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("res5", "x3", CodeBinaryOperatorType.GreaterThanOrEqual, 5000));
+
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (bool), "res6"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("res6", "res4", CodeBinaryOperatorType.BooleanAnd, "res5"));
+
+        retMethod.Statements.Add (
+            new CodeConditionStatement (
+            new CodeVariableReferenceExpression ("res6"),
+            new CodeStatement [] { CDHelper.CreateIncrementByStatement ("x4", 4) },
+            new CodeStatement [] { CDHelper.CreateIncrementByStatement ("x4", 8) }));
+
+        // GENERATES (C#):
+        //              bool res7;
+        //              res7 = x2 < 3;
+        //              bool res8;
+        //              res8 = x3 != 1;
+        //              bool res9;
+        //              res9 = res7 && res8;
+        //              if (res9) {
+        //                  x4 = (x4 + 16);
+        //              }
+        //              else {
+        //                  x4 = (x4 + 32);
+        //              }
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (bool), "res7"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("res7", "x2", CodeBinaryOperatorType.LessThanOrEqual, 3));
+
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (bool), "res8"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("res8", "x3", CodeBinaryOperatorType.IdentityInequality, 1));
+
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (bool), "res9"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("res9", "res7", CodeBinaryOperatorType.BooleanAnd, "res8"));
+
+        retMethod.Statements.Add (
+            new CodeConditionStatement (
+            new CodeVariableReferenceExpression ("res9"),
+            new CodeStatement [] { CDHelper.CreateIncrementByStatement ("x4", 16) },
+            new CodeStatement [] { CDHelper.CreateIncrementByStatement ("x4", 32) }));
+
+
+        // GENERATES (C#):
+        //              int theSum;
+        //              theSum = x1 + x2;
+        //              theSum = theSum + x3;
+        //              theSum = theSum + x4;
+        //              return theSum;
+        //          }
+        //
+        retMethod.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "theSum"));
+        retMethod.Statements.Add (CDHelper.CreateBinaryOperatorStatement ("theSum", "x1", CodeBinaryOperatorType.Add, "x2"));
+        retMethod.Statements.Add (CDHelper.CreateIncrementByStatement ("theSum", "x3"));
+        retMethod.Statements.Add (CDHelper.CreateIncrementByStatement ("theSum", "x4"));
+
+        retMethod.Statements.Add (new CodeMethodReturnStatement (
+                    new CodeVariableReferenceExpression ("theSum")));
+        class1.Members.Add (retMethod);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateClass1", "Find and instantiate Namespace1.Class1.");
+        if (!FindAndInstantiate ("Namespace1.Class1", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClass1");
+
+        // Verify Return value from function
+        if (VerifyMethod (genType, genObject, "ReturnMethod", new object[] {5}, 204))
+            VerifyScenario ("ReturnMethod");
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/subsetfieldstest.cs b/workyard/tests/codedom/tests/subsetfieldstest.cs
new file mode 100755
index 0000000..77c6a29
--- /dev/null
+++ b/workyard/tests/codedom/tests/subsetfieldstest.cs
@@ -0,0 +1,146 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class SubsetFieldsTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "SubsetFieldsTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Subset compatible test of calling fields.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        nspace.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (nspace);
+
+
+        // declare class with fields
+
+        // GENERATES (C#):
+        //    public class ClassWithFields {
+        //        public int NonStaticPublicField = 6;
+        //        private int PrivateField = 7;
+        //        public int UsePrivateField(int i) {
+        //            this.PrivateField = i;
+        //            return this.PrivateField;
+        //        }
+        //    }
+        CodeTypeDeclaration cd = new CodeTypeDeclaration ("ClassWithFields");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        CodeMemberField field = new CodeMemberField ();
+        field.Name = "NonStaticPublicField";
+        field.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (6);
+        cd.Members.Add (field);
+
+        field = new CodeMemberField ();
+        field.Name = "PrivateField";
+        field.Attributes = MemberAttributes.Private | MemberAttributes.Final;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (7);
+        cd.Members.Add (field);
+
+        // create a method to test access to private field
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "UsePrivateField";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Final;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+        cmm.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "PrivateField"), new CodeArgumentReferenceExpression ("i")));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "PrivateField")));
+        cd.Members.Add (cmm);
+
+        // GENERATES (C#):
+        //    public class TestFields {
+        //        public int UseFields(int i) {
+        //            ClassWithFields number = new ClassWithFields();
+        //            int someSum;
+        //            int privateField;
+        //            someSum = number.NonStaticPublicField;
+        //            privateField = number.UsePrivateField (i);
+        //            return someSum + privateField;
+        //        }
+        //    }
+        cd = new CodeTypeDeclaration ("TestFields");
+        cd.IsClass = true;
+        nspace.Types.Add (cd);
+
+        AddScenario ("CheckTestFields");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "UseFields";
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference ("ClassWithFields"), "number",
+                    new CodeObjectCreateExpression ("ClassWithFields")));
+
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int),
+                    "someSum"));
+        cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int),
+                    "privateField"));
+
+        cmm.Statements.Add (new CodeAssignStatement (new CodeVariableReferenceExpression ("someSum"),
+                    CDHelper.CreateFieldRef ("number", "NonStaticPublicField")));
+
+        cmm.Statements.Add (new CodeAssignStatement (new CodeVariableReferenceExpression ("privateField"),
+                    CDHelper.CreateMethodInvoke (new CodeVariableReferenceExpression ("number"),
+                        "UsePrivateField", new CodeArgumentReferenceExpression ("i"))));
+
+        cmm.Statements.Add (new CodeMethodReturnStatement (CDHelper.CreateBinaryOperatorExpression ("someSum",
+                        CodeBinaryOperatorType.Add, "privateField")));
+        cd.Members.Add (cmm);
+
+
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateTestFields", "Find and instantiate TestFields.");
+        if (!FindAndInstantiate ("NSPC.TestFields", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateTestFields");
+
+        // verify method return value for method which references public, static field
+        if (VerifyMethod (genType, genObject, "UseFields", new object[]{3}, 9))
+            VerifyScenario ("CheckTestFields");
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/trycatchtest.cs b/workyard/tests/codedom/tests/trycatchtest.cs
new file mode 100755
index 0000000..0a35941
--- /dev/null
+++ b/workyard/tests/codedom/tests/trycatchtest.cs
@@ -0,0 +1,245 @@
+using System;
+using System.IO;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class TryCatchTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "TryCatchTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests try/catch/finally statements.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+        // create a namespace
+        CodeNamespace ns = new CodeNamespace ("NS");
+        ns.Imports.Add (new CodeNamespaceImport ("System"));
+        cu.Namespaces.Add (ns);
+
+        // create a class
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ();
+        class1.Name = "Test";
+        class1.IsClass = true;
+        ns.Types.Add (class1);
+
+        if (Supports (provider, GeneratorSupport.TryCatchStatements)) {
+
+            // try catch statement with just finally
+            // GENERATE (C#):
+            //       public static int FirstScenario(int a) {
+            //            try {
+            //            }
+            //            finally {
+            //                a = (a + 5);
+            //            }
+            //            return a;
+            //        }
+            AddScenario ("CheckFirstScenario");
+            CodeMemberMethod cmm = new CodeMemberMethod ();
+            cmm.Name = "FirstScenario";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (param);
+
+            CodeTryCatchFinallyStatement tcfstmt = new CodeTryCatchFinallyStatement ();
+            tcfstmt.FinallyStatements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"), new
+                CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("a"), CodeBinaryOperatorType.Add,
+                new CodePrimitiveExpression (5))));
+            cmm.Statements.Add (tcfstmt);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            class1.Members.Add (cmm);
+
+            // in VB (a = a/a) generates an warning if a is integer. Cast the expression just for VB language. 
+            CodeBinaryOperatorExpression cboExpression   = new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("a"), CodeBinaryOperatorType.Divide, new CodeArgumentReferenceExpression ("a"));
+            CodeAssignStatement          assignStatement = null;
+            if (provider is Microsoft.VisualBasic.VBCodeProvider)
+                assignStatement = new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"), new CodeCastExpression (typeof (int), cboExpression));
+            else
+                assignStatement = new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"), cboExpression);
+
+            // try catch statement with just catch
+            // GENERATE (C#):
+            //        public static int SecondScenario(int a, string exceptionMessage) {
+            //            try {
+            //                a = (a / a);
+            //            }
+            //            catch (System.Exception e) {
+            //                a = 3;
+            //                exceptionMessage = e.ToString();
+            //            }
+            //            finally {
+            //                a = (a + 1);
+            //            }
+            //            return a;
+            //        }
+            AddScenario ("CheckSecondScenario");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "SecondScenario";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            param = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (param);
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (String), "exceptionMessage"));
+
+            tcfstmt = new CodeTryCatchFinallyStatement ();
+            CodeCatchClause catchClause = new CodeCatchClause ("e");
+            tcfstmt.TryStatements.Add (assignStatement);
+            catchClause.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"),
+                new CodePrimitiveExpression (3)));
+            catchClause.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("exceptionMessage"),
+                new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("e"), "ToString")));
+            tcfstmt.CatchClauses.Add (catchClause);
+            tcfstmt.FinallyStatements.Add (CDHelper.CreateIncrementByStatement (new CodeArgumentReferenceExpression ("a"), 1));
+
+            cmm.Statements.Add (tcfstmt);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+
+            class1.Members.Add (cmm);
+
+            // try catch statement with multiple catches
+            // GENERATE (C#):
+            //        public static int ThirdScenario(int a, string exceptionMessage) {
+            //            try {
+            //                a = (a / a);
+            //            }
+            //            catch (System.ArgumentNullException e) {
+            //                a = 10;
+            //                exceptionMessage = e.ToString();
+            //            }
+            //            catch (System.DivideByZeroException f) {
+            //                exceptionMessage = f.ToString();
+            //                a = 9;
+            //            }
+            //            return a;
+            //        }
+            AddScenario ("CheckThirdScenario");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "ThirdScenario";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            param = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (param);
+            cmm.Parameters.Add (new CodeParameterDeclarationExpression (typeof (String), "exceptionMessage"));
+
+            tcfstmt = new CodeTryCatchFinallyStatement ();
+            catchClause = new CodeCatchClause ("e", new CodeTypeReference (typeof (ArgumentNullException)));
+            tcfstmt.TryStatements.Add (assignStatement);
+            catchClause.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"),
+                new CodePrimitiveExpression (9)));
+            catchClause.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("exceptionMessage"),
+                new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("e"), "ToString")));
+            tcfstmt.CatchClauses.Add (catchClause);
+
+            // add a second catch clause
+            catchClause = new CodeCatchClause ("f", new CodeTypeReference (typeof (Exception)));
+            catchClause.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("exceptionMessage"),
+                new CodeMethodInvokeExpression (new CodeVariableReferenceExpression ("f"), "ToString")));
+            catchClause.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"),
+                new CodePrimitiveExpression (9)));
+            tcfstmt.CatchClauses.Add (catchClause);
+
+            cmm.Statements.Add (tcfstmt);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            class1.Members.Add (cmm);
+
+            // catch throws exception
+            // GENERATE (C#):
+            //        public static int FourthScenario(int a) {
+            //            try {
+            //                a = (a / a);
+            //            }
+            //            catch (System.Exception e) {
+            //                // Error handling
+            //                throw e;
+            //            }
+            //            return a;
+            //        }
+            AddScenario ("CheckFourthScenario");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "FourthScenario";
+            cmm.ReturnType = new CodeTypeReference (typeof (int));
+            cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+            param = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (param);
+
+            tcfstmt = new CodeTryCatchFinallyStatement ();
+            catchClause = new CodeCatchClause ("e");
+            tcfstmt.TryStatements.Add (assignStatement);
+            catchClause.Statements.Add (new CodeCommentStatement ("Error handling"));
+            catchClause.Statements.Add (new CodeThrowExceptionStatement (new CodeArgumentReferenceExpression ("e")));
+            tcfstmt.CatchClauses.Add (catchClause);
+            cmm.Statements.Add (tcfstmt);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeArgumentReferenceExpression ("a")));
+            class1.Members.Add (cmm);
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        if (Supports (provider, GeneratorSupport.TryCatchStatements)) {
+            object genObject;
+            Type   genType;
+
+            AddScenario ("InstantiateTest", "Find and instantiate Test.");
+            if (!FindAndInstantiate ("NS.Test", asm, out genObject, out genType))
+                return;
+            VerifyScenario ("InstantiateTest");
+
+            // verify method return value
+            // verifying first scenario 
+            if (VerifyMethod (genType, genObject, "FirstScenario", new object[]{1}, 6) &&
+                    VerifyMethod (genType, genObject, "FirstScenario", new object[]{10}, 15)) {
+                VerifyScenario ("CheckFirstScenario");
+            }
+
+            // verify second scenario return method
+            if (VerifyMethod (genType, genObject, "SecondScenario", new object[]{0, "hi"}, 4) &&
+                    VerifyMethod (genType, genObject, "SecondScenario", new object[]{10, "hi"}, 2)) {
+                VerifyScenario ("CheckSecondScenario");
+            }
+
+            // verify third scenario return method
+            if (VerifyMethod (genType, genObject, "ThirdScenario", new object[]{0, "hi"}, 9)) {
+                VerifyScenario ("CheckThirdScenario");
+            }
+
+            // verify fourth scenario return method
+            if (VerifyException (genType, genObject, "FourthScenario", new object[]{0},
+                        new System.Reflection.TargetInvocationException (new DivideByZeroException ())) &&
+                    VerifyMethod (genType, genObject, "FourthScenario", new object[]{10}, 1)) {
+                VerifyScenario ("CheckFourthScenario");
+            }
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/typeoftest.cs b/workyard/tests/codedom/tests/typeoftest.cs
new file mode 100755
index 0000000..4327650
--- /dev/null
+++ b/workyard/tests/codedom/tests/typeoftest.cs
@@ -0,0 +1,168 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using System.Windows.Forms;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class TypeOfTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Subset;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+
+    public override string Name {
+        get {
+            return "TypeOfTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests typeof statements.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+
+        // GENERATES (C#):
+        //
+        //  namespace NSPC {
+        //      using System;
+        //      using System.Windows.Forms;
+        //      
+        //      
+        //      public class ClassToTest {
+        //          
+        //          public string Primitives() {
+        //              return typeof(int).ToString();
+        //          }
+        //          
+        //          public string ArraysOfPrimitives() {
+        //              return typeof(int[]).ToString();
+        //          }
+        //          
+        //          public string NonPrimitives() {
+        //              return typeof(System.ICloneable).ToString();
+        //          }
+        //          
+        //          public string ArraysOfNonPrimitives() {
+        //              return typeof(System.ICloneable[]).ToString();
+        //          }
+        //          
+        //          public string GetSomeClass() {
+        //              return typeof(SomeClass).ToString();
+        //          }
+        //      }
+        //      
+        //      public class SomeClass {
+        //      }
+        //  }
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        nspace.Imports.Add (new CodeNamespaceImport ("System"));
+        nspace.Imports.Add (new CodeNamespaceImport ("System.Windows.Forms"));
+        cu.Namespaces.Add (nspace);
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ("ClassToTest");
+        class1.IsClass = true;
+        nspace.Types.Add (class1);
+
+        AddScenario ("CheckPrimitives");
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "Primitives";
+        cmm.ReturnType = new CodeTypeReference (typeof (string));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (
+            new CodeTypeOfExpression (typeof (int)), "ToString")));
+        class1.Members.Add (cmm);
+
+        AddScenario ("CheckArraysOfPrimitives");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "ArraysOfPrimitives";
+        cmm.ReturnType = new CodeTypeReference (typeof (string));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (
+            new CodeTypeOfExpression (typeof (int[])), "ToString")));
+        class1.Members.Add (cmm);
+
+        AddScenario ("CheckNonPrimitives");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "NonPrimitives";
+        cmm.ReturnType = new CodeTypeReference (typeof (string));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (
+            new CodeTypeOfExpression (typeof (System.ICloneable)), "ToString")));
+        class1.Members.Add (cmm);
+
+        AddScenario ("CheckArraysOfNonPrimitives");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "ArraysOfNonPrimitives";
+        cmm.ReturnType = new CodeTypeReference (typeof (string));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (
+            new CodeTypeOfExpression (typeof (System.ICloneable[])), "ToString")));
+        class1.Members.Add (cmm);
+
+        AddScenario ("CheckGetSomeClass");
+        cmm = new CodeMemberMethod ();
+        cmm.Name = "GetSomeClass";
+        cmm.ReturnType = new CodeTypeReference (typeof (string));
+        cmm.Attributes = MemberAttributes.Public;
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (
+            new CodeTypeOfExpression ("SomeClass"), "ToString")));
+        class1.Members.Add (cmm);
+
+        CodeTypeDeclaration ce = new CodeTypeDeclaration ("SomeClass");
+        ce.IsClass = true;
+        ce.Attributes = MemberAttributes.Public;
+        nspace.Types.Add (ce);
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+
+        AddScenario ("InstantiateClassToTest", "Find and instantiate ClassToTest.");
+        if (!FindAndInstantiate ("NSPC.ClassToTest", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClassToTest");
+
+        if (VerifyMethod (genType, genObject, "Primitives", new object[] {}, typeof (int).ToString ())) {
+            VerifyScenario ("CheckPrimitives");
+        }
+        if (VerifyMethod (genType, genObject, "ArraysOfPrimitives", new object[] {}, typeof (int[]).ToString ())) {
+            VerifyScenario ("CheckArraysOfPrimitives");
+        }
+        if (VerifyMethod (genType, genObject, "NonPrimitives", new object[] {}, typeof (System.ICloneable).ToString ())) {
+            VerifyScenario ("CheckNonPrimitives");
+        }
+        if (VerifyMethod (genType, genObject, "ArraysOfNonPrimitives", new object[] {}, typeof (System.ICloneable[]).ToString ())) {
+            VerifyScenario ("CheckArraysOfNonPrimitives");
+        }
+        if (VerifyMethod (genType, genObject, "GetSomeClass", new object[] {}, "SomeClass") ||
+                    VerifyMethod (genType, genObject, "GetSomeClass", new object[] {}, "NSPC.SomeClass")) {
+            VerifyScenario ("CheckGetSomeClass");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/typetest.cs b/workyard/tests/codedom/tests/typetest.cs
new file mode 100755
index 0000000..af7f68f
--- /dev/null
+++ b/workyard/tests/codedom/tests/typetest.cs
@@ -0,0 +1,207 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.VisualBasic;
+
+public class TypeTest : CodeDomTestTree {
+
+    public override string Comment
+    {
+        get { return "public static fields not allowed in F#"; }
+    }
+
+    public override TestTypes TestType
+    {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return true;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "TypeTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests generating and using objects of different types.";
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        CodeNamespace nspace = new CodeNamespace ("NSPC");
+        cu.Namespaces.Add (nspace);
+
+        CodeTypeDeclaration class1 = new CodeTypeDeclaration ("ClassWithField");
+        class1.IsClass = true;
+        nspace.Types.Add (class1);
+
+        // internal modifier
+        //		public class ClassWithField {
+        //			/*FamANDAssem*/ internal static int InternalField = 0;
+        //		}
+        CodeMemberField field = new CodeMemberField ();
+        field.Name = "InternalField";
+        field.Attributes = MemberAttributes.Assembly | MemberAttributes.Static;
+        field.Type = new CodeTypeReference (typeof (int));
+        field.InitExpression = new CodePrimitiveExpression (0);
+        class1.Members.Add (field);
+
+        class1 = new CodeTypeDeclaration ("ClassToTest");
+        class1.IsClass = true;
+        nspace.Types.Add (class1);
+
+        // test internal field
+        //      public static int UseInternalField(int i) {
+        //			ClassWithField.InternalField = i;
+        //			return ClassWithField.InternalField;
+        //		}
+        AddScenario ("CheckUseInternalField");
+        CodeMemberMethod cmm = new CodeMemberMethod ();
+        cmm.Name = "UseInternalField";
+        cmm.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+        cmm.ReturnType = new CodeTypeReference (typeof (int));
+        cmm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (int)), "i"));
+        cmm.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (new
+            CodeTypeReferenceExpression ("ClassWithField"), "InternalField"),
+            new CodeArgumentReferenceExpression ("i")));
+        cmm.Statements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new
+            CodeTypeReferenceExpression ("ClassWithField"), "InternalField")));
+        class1.Members.Add (cmm);
+
+        // nested array reference
+        //        public int MoreArrayTests(int i) {
+        //			int[][] arrayOfArrays = new int[][] {
+        //					new int[] {
+        //							3,
+        //							4},
+        //					new int[1],
+        //					new int[0]};
+        //			return (arrayOfArrays[0][1] + i);
+        //		}
+        // VB code provider doesn't support array of array initialization
+        if (Supports (provider, GeneratorSupport.ArraysOfArrays) && !(provider is VBCodeProvider)) {
+            AddScenario ("CheckMoreArrayTests");
+            CodeMemberMethod secondMethod = new CodeMemberMethod ();
+            secondMethod.Name = "MoreArrayTests";
+            secondMethod.Attributes = (secondMethod.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+            secondMethod.ReturnType = new CodeTypeReference (typeof (int));
+            secondMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof (int), "i"));
+            // array of arrays
+            secondMethod.Statements.Add (new CodeVariableDeclarationStatement (new CodeTypeReference (typeof (int[][])),
+                "arrayOfArrays", new CodeArrayCreateExpression (typeof (int[][]),
+                new CodeArrayCreateExpression (typeof (int[]), new CodePrimitiveExpression (3), new CodePrimitiveExpression (4)),
+                new CodeArrayCreateExpression (typeof (int[]), new CodePrimitiveExpression (1)), new CodeArrayCreateExpression (typeof (int[])))));
+            secondMethod.Statements.Add (new CodeMethodReturnStatement (
+                new CodeBinaryOperatorExpression (new CodeArrayIndexerExpression (
+                new CodeArrayIndexerExpression (new CodeVariableReferenceExpression ("arrayOfArrays"), new CodePrimitiveExpression (0))
+                , new CodePrimitiveExpression (1)),
+                CodeBinaryOperatorType.Add, new CodeArgumentReferenceExpression ("i"))));
+            class1.Members.Add (secondMethod);
+        }
+        // value and reference
+        if (Supports (provider, GeneratorSupport.ReferenceParameters)) {
+            //    GENERATE (C#):      
+            //    static void Work(ref int i, out int j) {
+            //             i = (i + 4);
+            //             j = 5;
+            //   }
+
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "Work";
+            cmm.ReturnType = new CodeTypeReference ("System.void");
+            cmm.Attributes = MemberAttributes.Static;
+            // add parameter with ref direction
+            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression (typeof (int), "i");
+            param.Direction = FieldDirection.Ref;
+            cmm.Parameters.Add (param);
+            // add parameter with out direction
+            param = new CodeParameterDeclarationExpression (typeof (int), "j");
+            param.Direction = FieldDirection.Out;
+            cmm.Parameters.Add (param);
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("i"),
+                new CodeBinaryOperatorExpression (new CodeArgumentReferenceExpression ("i"),
+                CodeBinaryOperatorType.Add, new CodePrimitiveExpression (4))));
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("j"),
+                new CodePrimitiveExpression (5)));
+            class1.Members.Add (cmm);
+
+            // add a method that calls method work to verify that ref and out are working properly 
+            // GENERATE (C#):
+            //       public static int CallingWork(int a) {
+            //          a = 10;
+            //          int b;
+            //          TEST.Work(ref a, out b);
+            //          return (a + b);
+            //       }
+            AddScenario ("CheckCallingWork");
+            cmm = new CodeMemberMethod ();
+            cmm.Name = "CallingWork";
+            cmm.Attributes = MemberAttributes.Public;
+            CodeParameterDeclarationExpression parames = new CodeParameterDeclarationExpression (typeof (int), "a");
+            cmm.Parameters.Add (parames);
+            cmm.ReturnType = new CodeTypeReference ("System.Int32");
+            cmm.Statements.Add (new CodeAssignStatement (new CodeArgumentReferenceExpression ("a"),
+                new CodePrimitiveExpression (10)));
+            cmm.Statements.Add (new CodeVariableDeclarationStatement (typeof (int), "b"));
+            // invoke the method called "work"
+            CodeMethodInvokeExpression methodinvoked = new CodeMethodInvokeExpression (new CodeMethodReferenceExpression
+                (new CodeTypeReferenceExpression ("ClassToTest"), "Work"));
+            // add parameter with ref direction
+            CodeDirectionExpression parameter = new CodeDirectionExpression (FieldDirection.Ref,
+                new CodeArgumentReferenceExpression ("a"));
+            methodinvoked.Parameters.Add (parameter);
+            // add parameter with out direction
+            parameter = new CodeDirectionExpression (FieldDirection.Out, new CodeVariableReferenceExpression ("b"));
+            methodinvoked.Parameters.Add (parameter);
+            cmm.Statements.Add (methodinvoked);
+            cmm.Statements.Add (new CodeMethodReturnStatement (new CodeBinaryOperatorExpression
+                (new CodeArgumentReferenceExpression ("a"), CodeBinaryOperatorType.Add, new CodeVariableReferenceExpression ("b"))));
+            class1.Members.Add (cmm);
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+        object genObject;
+        Type   genType;
+        
+        AddScenario ("InstantiateClassToTest", "Find and instantiate ClassToTest.");
+        if (!FindAndInstantiate ("NSPC.ClassToTest", asm, out genObject, out genType))
+            return;
+        VerifyScenario ("InstantiateClassToTest");
+
+        // verify internal field
+        if (VerifyMethod (genType, genObject, "UseInternalField", new object[] {2}, 2)) {
+            VerifyScenario ("CheckUseInternalField");
+        }
+        if (Supports (provider, GeneratorSupport.ReferenceParameters) &&
+                VerifyMethod (genType, genObject, "CallingWork", new object[] {7}, 19)) {
+            VerifyScenario ("CheckCallingWork");
+        }
+        if (Supports (provider, GeneratorSupport.ArraysOfArrays) && !(provider is VBCodeProvider) &&
+                VerifyMethod (genType, genObject, "MoreArrayTests", new object[] {19}, 23)) {
+            VerifyScenario ("CheckMoreArrayTests");
+        }
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/unicodecharescapetest.cs b/workyard/tests/codedom/tests/unicodecharescapetest.cs
new file mode 100755
index 0000000..446e156
--- /dev/null
+++ b/workyard/tests/codedom/tests/unicodecharescapetest.cs
@@ -0,0 +1,78 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using Microsoft.Samples.CodeDomTestSuite;
+
+using Microsoft.JScript;
+
+public class UnicodeCharEscapeTest : CodeDomTestTree {
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Everett;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "UnicodeCharEscapeTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Test All the Unicode characters for escaping";
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return false;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+
+        if (!(provider is JScriptCodeProvider)) {
+            // GENERATES (C#):
+            //
+            //  namespace Namespace1 {
+            //      
+            //      public class TEST {
+            //          
+            //          public static void Main() {
+            //              // the following is repeated Char.MaxValue times
+            //              System.Console.WriteLine(/* character value goes here */);
+            //          }
+            //      }
+            //  }
+            CodeNamespace ns = new CodeNamespace ("Namespace1");
+            ns.Imports.Add (new CodeNamespaceImport ("System"));
+            cu.Namespaces.Add (ns);
+
+            CodeTypeDeclaration cd = new CodeTypeDeclaration ("TEST");
+            cd.IsClass = true;
+            ns.Types.Add (cd);
+            CodeEntryPointMethod methodMain = new CodeEntryPointMethod ();
+
+            for (int i = 0; i < Char.MaxValue; i+=50)
+                methodMain.Statements.Add (CDHelper.ConsoleWriteLineStatement (new CodePrimitiveExpression (System.Convert.ToChar (i))));
+
+            cd.Members.Add (methodMain);
+        }
+    }
+
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm)  {
+    }
+}
+
diff --git a/workyard/tests/codedom/tests/verbatimorderingtest.cs b/workyard/tests/codedom/tests/verbatimorderingtest.cs
new file mode 100755
index 0000000..6ff1135
--- /dev/null
+++ b/workyard/tests/codedom/tests/verbatimorderingtest.cs
@@ -0,0 +1,332 @@
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.IO;
+using System.Reflection;
+using System.Globalization;
+using System.Text.RegularExpressions;
+using Microsoft.Samples.CodeDomTestSuite;
+
+public class VerbatimOrderingTest : CodeDomTestTree {
+		public override string Comment
+		{
+			get { return "order is irelevant - this test is odd"; }
+		}		
+
+    public override TestTypes TestType {
+        get {
+            return TestTypes.Whidbey;
+        }
+    }
+
+    public override string Name {
+        get {
+            return "VerbatimOrderingTest";
+        }
+    }
+
+    public override string Description {
+        get {
+            return "Tests if types and members are generated in the order they are specified in the tree.";
+        }
+    }
+
+    public override bool ShouldSearch {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldCompile {
+        get {
+            return true;
+        }
+    }
+
+    public override bool ShouldVerify {
+        get {
+            return false;
+        }
+    }
+
+    public override CodeGeneratorOptions GetGeneratorOptions (CodeDomProvider provider) {
+        CodeGeneratorOptions generatorOptions = base.GetGeneratorOptions (provider);
+#if WHIDBEY
+        generatorOptions.VerbatimOrder = true;
+#endif
+        return generatorOptions;
+    }
+
+    public override CompilerParameters GetCompilerParameters (CodeDomProvider provider) {
+        CompilerParameters parms = base.GetCompilerParameters (provider);
+        parms.GenerateExecutable = true;
+        return parms;
+    }
+
+    public override void BuildTree (CodeDomProvider provider, CodeCompileUnit cu) {
+#if WHIDBEY
+        CodeNamespace ns = new CodeNamespace("Namespace1");
+
+        cu.Namespaces.Add(ns);
+
+        CodeTypeDeclaration cd = new CodeTypeDeclaration ("Class1");
+        ns.Types.Add(cd);
+
+        cd.Comments.Add(new CodeCommentStatement("Outer Type Comment"));
+
+        CodeMemberField field1 = new CodeMemberField(typeof(String), "field1");
+        CodeMemberField field2 = new CodeMemberField(typeof(String), "field2");
+        field2.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Foo"));
+        field2.EndDirectives.Add(new CodeRegionDirective (CodeRegionMode.End, String.Empty));
+        field1.Comments.Add(new CodeCommentStatement("Field 1 Comment"));
+
+        CodeMemberEvent evt1 = new CodeMemberEvent();
+        evt1.Name = "Event1";
+        evt1.Type = new CodeTypeReference(typeof(System.EventHandler));
+        evt1.Attributes = (evt1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+
+        CodeMemberEvent evt2 = new CodeMemberEvent();
+        evt2.Name = "Event2";
+        evt2.Type = new CodeTypeReference(typeof(System.EventHandler));
+        evt2.Attributes = (evt2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+
+        CodeMemberMethod method1 = new CodeMemberMethod();
+        method1.Name = "Method1";
+        method1.Attributes = (method1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;            
+        if (Supports(provider, GeneratorSupport.DeclareEvents)) {
+            method1.Statements.Add(
+                new CodeDelegateInvokeExpression(
+                    new CodeEventReferenceExpression(new CodeThisReferenceExpression(), "Event1"), 
+                    new CodeExpression[] {
+                        new CodeThisReferenceExpression(),
+                        new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("System.EventArgs"), "Empty")
+                    }));
+        }
+
+
+        CodeMemberMethod method2 = new CodeMemberMethod();
+        method2.Name = "Method2";
+        method2.Attributes = (method2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        if (Supports(provider, GeneratorSupport.DeclareEvents)) {
+            method2.Statements.Add(
+                new CodeDelegateInvokeExpression(
+                    new CodeEventReferenceExpression(new CodeThisReferenceExpression(), "Event2"), 
+                    new CodeExpression[] {
+                        new CodeThisReferenceExpression(),
+                        new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("System.EventArgs"), "Empty")
+                    }));
+        }
+        method2.LinePragma = new CodeLinePragma("MethodLinePragma.txt", 500);            
+        method2.Comments.Add(new CodeCommentStatement("Method 2 Comment"));
+
+        CodeMemberProperty property1 = new CodeMemberProperty();
+        property1.Name = "Property1";
+        property1.Type = new CodeTypeReference(typeof(string));
+        property1.Attributes = (property1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        property1.GetStatements.Add(
+            new CodeMethodReturnStatement(
+                new CodeFieldReferenceExpression(
+                    new CodeThisReferenceExpression(),
+                    "field1")));
+
+        CodeMemberProperty property2 = new CodeMemberProperty();
+        property2.Name = "Property2";
+        property2.Type = new CodeTypeReference(typeof(string));
+        property2.Attributes = (property2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        property2.GetStatements.Add(
+            new CodeMethodReturnStatement(
+                new CodeFieldReferenceExpression(
+                    new CodeThisReferenceExpression(),
+                    "field2")));
+
+
+        CodeConstructor constructor1 = new CodeConstructor();
+        constructor1.Attributes = (constructor1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        constructor1.Statements.Add(
+            new CodeAssignStatement(
+                new CodeFieldReferenceExpression(
+                    new CodeThisReferenceExpression(),
+                    "field1"),
+                new CodePrimitiveExpression("value1")));
+        constructor1.Statements.Add(
+            new CodeAssignStatement(
+                new CodeFieldReferenceExpression(
+                    new CodeThisReferenceExpression(),
+                    "field2"),
+                new CodePrimitiveExpression("value2")));
+
+        CodeConstructor constructor2 = new CodeConstructor();
+        constructor2.Attributes = (constructor2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
+        constructor2.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "value1"));
+        constructor2.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "value2"));                       
+
+        CodeTypeConstructor typeConstructor2 = new CodeTypeConstructor();
+
+        CodeEntryPointMethod methodMain =  new CodeEntryPointMethod();
+
+        CodeTypeDeclaration nestedClass1 = new CodeTypeDeclaration ("NestedClass1");
+        CodeTypeDeclaration nestedClass2 = new CodeTypeDeclaration ("NestedClass2");
+        nestedClass2.LinePragma = new CodeLinePragma("NestedTypeLinePragma.txt", 400);
+        nestedClass2.Comments.Add(new CodeCommentStatement("Nested Type Comment"));
+
+
+        CodeTypeDelegate delegate1 = new CodeTypeDelegate();
+        delegate1.Name = "nestedDelegate1";
+        delegate1.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference("System.Object"), "sender"));
+        delegate1.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference("System.EventArgs"), "e"));
+
+        CodeTypeDelegate delegate2 = new CodeTypeDelegate();
+        delegate2.Name = "nestedDelegate2";
+        delegate2.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference("System.Object"), "sender"));
+        delegate2.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference("System.EventArgs"), "e"));
+
+
+
+        cd.Members.Add(field1);
+        cd.Members.Add(method1);
+        cd.Members.Add(constructor1);
+        cd.Members.Add(property1);
+
+        if (Supports (provider, GeneratorSupport.EntryPointMethod))
+            cd.Members.Add(methodMain);
+
+        if (Supports(provider, GeneratorSupport.DeclareEvents))
+            cd.Members.Add(evt1);
+
+        if (Supports(provider, GeneratorSupport.NestedTypes)) {
+            cd.Members.Add(nestedClass1);
+            if (Supports(provider, GeneratorSupport.DeclareDelegates)) {
+                cd.Members.Add(delegate1);
+            }
+        }
+
+        cd.Members.Add(field2);
+        cd.Members.Add(method2);
+        cd.Members.Add(constructor2);
+        cd.Members.Add(property2);
+
+        if (Supports(provider, GeneratorSupport.StaticConstructors)) {
+            cd.Members.Add(typeConstructor2);
+        }
+
+        if (Supports(provider, GeneratorSupport.DeclareEvents)) {
+            cd.Members.Add(evt2);
+        }
+
+        if (Supports(provider, GeneratorSupport.NestedTypes)) {
+            cd.Members.Add(nestedClass2);
+            if (Supports(provider, GeneratorSupport.DeclareDelegates)) {
+                cd.Members.Add(delegate2);
+            }
+        }
+#endif
+    }
+
+    public override void Search (CodeDomProvider provider, String strGeneratedCode)  {
+#if WHIDBEY
+        int searchIndex = 0; 
+
+        string [] tokens = GetTokenOrder (provider);
+
+        // load up scenarios
+        for(int i = 0; i < tokens.Length; i++)
+            if (String.CompareOrdinal (tokens[i], String.Empty) != 0)
+                AddScenario ("Find" + i + ":" + tokens[i], "The first one to fail will make the rest fail.");
+
+        // attempt to find them
+        for(int i = 0; i < tokens.Length; i++) {
+            searchIndex = strGeneratedCode.IndexOf (tokens[i], searchIndex);
+            if(searchIndex > -1) {
+                //LogMessage("Expected token doesn't exists...... Search Token number...:" + i.ToString()  + "Search token string...:" + strSearchTokens[i]);
+                searchIndex += tokens[i].Length ;
+                VerifyScenario ("Find" + i + ":" + tokens[i]);
+            } else
+                break;
+        }
+#endif
+    }
+
+    private string[] GetTokenOrder (CodeDomProvider provider) {
+        ArrayList list = new ArrayList ();
+        
+        list.AddRange (new string[]{ "Namespace1",
+                "Outer Type Comment", "Class1",
+                "field1", "Method1" });
+
+        // constructor
+        if (provider is Microsoft.CSharp.CSharpCodeProvider)            
+            list.Add ("Class1");
+        else if (provider is Microsoft.VisualBasic.VBCodeProvider) 
+            list.Add ("New");
+
+        list.Add ("Property1");
+
+        if (Supports (provider, GeneratorSupport.EntryPointMethod))
+            list.Add ("Main");
+
+        if (Supports (provider, GeneratorSupport.DeclareEvents))
+            list.Add ("Event1");
+       
+        if (Supports (provider, GeneratorSupport.NestedTypes)) {
+            list.Add ("NestedClass1");
+
+            if (Supports (provider, GeneratorSupport.DeclareDelegates))
+                list.Add ("nestedDelegate1");
+        }
+
+#if WHIDBEY
+        // region directive
+        if (provider is Microsoft.CSharp.CSharpCodeProvider ||
+                provider is Microsoft.VisualBasic.VBCodeProvider)
+            list.Add ("Foo");
+#endif
+        list.AddRange (new string [] {
+            "field2", "Method 2 Comment",
+            "MethodLinePragma.txt", "Method2" });
+
+        // line pragma extras
+        if (provider is Microsoft.CSharp.CSharpCodeProvider)            
+            list.Add ("default");
+        else if (provider is Microsoft.VisualBasic.VBCodeProvider) 
+            list.Add ("ExternalSource");
+
+        // constructor
+        if (provider is Microsoft.CSharp.CSharpCodeProvider)            
+            list.Add ("Class1");
+        else if (provider is Microsoft.VisualBasic.VBCodeProvider) 
+            list.Add ("New");
+
+        list.Add ("Property2");
+
+        // static constructor
+        if (provider is Microsoft.CSharp.CSharpCodeProvider &&
+                Supports (provider, GeneratorSupport.StaticConstructors))
+            list.Add ("Class1");
+        else if (provider is Microsoft.VisualBasic.VBCodeProvider &&
+                Supports (provider, GeneratorSupport.StaticConstructors))
+            list.Add ("New");
+
+        if (Supports (provider, GeneratorSupport.DeclareEvents))
+            list.Add ("Event2");
+                    
+        if (Supports (provider, GeneratorSupport.NestedTypes))
+            list.AddRange (new string [] { "Nested Type Comment",
+                "NestedTypeLinePragma.txt", "NestedClass2" });
+
+        // line pragma extras
+        if (provider is Microsoft.CSharp.CSharpCodeProvider)            
+            list.Add ("default");
+        else if (provider is Microsoft.VisualBasic.VBCodeProvider) 
+            list.Add ("ExternalSource");
+
+        if (Supports (provider, GeneratorSupport.DeclareDelegates))
+            list.Add ("nestedDelegate2");
+
+        return (string[]) list.ToArray (typeof (string));
+    }
+    
+    public override void VerifyAssembly (CodeDomProvider provider, Assembly asm) {
+    }
+}	
+
diff --git a/workyard/tests/fshtmldoc/build.bat b/workyard/tests/fshtmldoc/build.bat
new file mode 100755
index 0000000..0ef248f
--- /dev/null
+++ b/workyard/tests/fshtmldoc/build.bat
@@ -0,0 +1,48 @@
+ at if "%_echo%"=="" echo off
+setlocal
+if EXIST build.ok DEL /f /q build.ok
+
+call %~d0%~p0..\..\..\config.bat
+
+del /s /q namespaces.html > NUL 2>&1
+del /s /q FSharp.Core > NUL 2>&1
+del /s /q Test.PowerPack > NUL 2>&1
+del /s /q Test.PowerPack.Linq > NUL 2>&1
+del /s /q dummy > NUL 2>&1
+
+REM devenv /debugexe 
+REM Check the generation of basic team docs
+fshtmldoc.exe --locallinks %FSCBinPath%\FSharp.Core.dll %FSCBinPath%\Test.PowerPack.dll %FSCBinPath%\Test.PowerPack.Linq.dll %FSCBinPath%\Test.PowerPack.Metadata.dll
+if ERRORLEVEL 1 goto Error
+
+REM Check all the command line options
+mkdir dummy
+fshtmldoc.exe --outdir dummy --cssfile dummy.css --namespacefile nsp.html %FSCBinPath%\Test.PowerPack.Metadata.dll
+if ERRORLEVEL 1 goto Error
+
+REM devenv /debugexe 
+REM Check the generation of docs against a local DLL
+fsc.exe -a test.fs
+if ERRORLEVEL 1 goto Error
+
+fshtmldoc.exe test.dll
+if ERRORLEVEL 1 goto Error
+
+
+:Ok
+echo Built fsharp %~f0 ok.
+echo. > build.ok
+endlocal
+exit /b 0
+
+:Skip
+echo Skipped %~f0
+endlocal
+exit /b 0
+
+
+:Error
+call %SCRIPT_ROOT%\ChompErr.bat %ERRORLEVEL% %~f0
+endlocal
+exit /b %ERRORLEVEL%
+
diff --git a/workyard/tests/fshtmldoc/msdn.css b/workyard/tests/fshtmldoc/msdn.css
new file mode 100755
index 0000000..7e8ea7f
--- /dev/null
+++ b/workyard/tests/fshtmldoc/msdn.css
@@ -0,0 +1,229 @@
+body
+{
+	width: 100%;
+	margin: 0px 0px 0px 0px;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 70%;
+}
+
+h1, h3, h4
+{
+	margin-bottom: .4em;
+	margin-top: 1em;
+}
+
+h1
+{
+	font-size: 120%;
+	margin-top: 0em;
+}
+
+h3
+{
+	font-size: 115%;
+}
+
+h4
+{
+	font-size: 100%;
+}
+
+div.table
+{
+	text-align: center;
+}
+
+table
+{
+	font-size: 100%;
+	border-collapse: collapse;
+	width: 93%;
+}
+
+th
+{
+	background-color: #cccccc;
+	color: #000000;
+	font-weight: bolder;
+	padding: 5px;
+	border: 1px solid #999999;
+}
+
+tr
+{
+	background-color: #ffffff;
+	padding: 5px;
+	text-align: left;
+	border: 1px solid #999999;
+}
+
+td
+{
+	border: 1px solid #999999;
+	padding: 5px;
+}
+
+p
+{
+	margin: .5em 0em .5em 0em;
+}
+
+pre
+{
+	margin-top: .5em;
+	margin-bottom: .5em;
+}
+
+pre.code
+{
+    font: Monospace, Courier New, Courier;
+    color: #000066;
+    font-size: 100%;
+	margin-left: 20px;
+}
+
+.syntax
+{
+	font: Monospace, Courier New, Courier;
+	letter-spacing: .1em;
+	background-color: #cccccc;
+	color: #000000;
+	font-size: 100%;
+	font-weight: bolder;
+	padding: 5px;
+	border: 1px solid #999999;
+	margin-left: 20px;
+	padding: 4px 8px;
+	margin-top: 1em;
+	margin-bottom: 1em;
+	width: 96%;
+}
+.comment
+{
+	color:Green;
+	font-weight:lighter;	
+}
+.i1
+{
+	margin-left: 20px;
+}
+
+.i2
+{
+	margin-left: 40px;
+}
+
+.i3
+{
+	margin-left: 60px;
+}
+
+.missing
+{
+	color: Red;
+}
+
+div#banner
+{
+	width: 100%;
+	margin: 0px 0px 0px 0px;
+	border-width: 0px;
+	border-bottom: 1px solid #999999;
+	padding: 0px 0px 0px 0px;
+	background-color: #99ccff;
+}
+
+div#header
+{
+	margin: 0px 0px 0px 0px;
+	border-width: 0px;
+	padding: .4em .4em 0 .4em;
+	background-color: #99ccff;
+	font-style: italic;
+}
+
+div#footer
+{
+	font-size: 100%;
+	font-style:italic;
+	border-top: 1px solid #999999;
+	margin-left: 20px;
+	margin-top: 1em;
+	margin-bottom: 1em;
+	width: 96%;
+}
+
+div#banner h1
+{
+	margin: 0px 0px 0px 0px;
+	border-width: 0px;
+	padding: 0 .4em .3em .4em;
+	background-color: #99ccff;
+}
+
+div#content
+{
+	margin: 0px 0px 0px 0px;
+	padding: 4px 4px 4px 4px;
+}
+
+code.ce
+{
+	font-style: italic;
+}
+
+pre.syntax span.lang
+{
+	margin: 0;
+	font-weight: normal;
+}
+
+pre.syntax span.meta
+{
+	margin: 0;
+	font-weight: normal;
+	font-style: italic;
+}
+
+.permissions
+{
+	margin-top: 6px;
+}
+
+blockquote.dtBlock
+{
+	margin: .5em 1.5em .5em 1.5em;
+}
+
+a:link
+{
+	color: #0000ff;
+}
+
+a:visited
+{
+	color: #0000ff;
+}
+
+a:hover
+{
+	color: #3366ff;
+}
+
+a.typeLink
+{
+	text-decoration:none;
+}
+a:link.typeLink
+{
+	text-decoration:none;
+}
+a:visited.typeLink;
+{
+	text-decoration:none;
+}
+a:hover.typeLink
+{
+	font-style:italic;
+	text-decoration:underline;
+}
diff --git a/workyard/tests/fshtmldoc/test.fs b/workyard/tests/fshtmldoc/test.fs
new file mode 100755
index 0000000..76b6223
--- /dev/null
+++ b/workyard/tests/fshtmldoc/test.fs
@@ -0,0 +1,33 @@
+
+namespace MyNamespace
+
+module M1 = 
+    // This is f
+    let f (x:int) = x
+
+// This is type C
+type C() = 
+   /// This is P
+   member x.MyProperty = 3
+   /// This is M
+   member x.MyMethod(y:int) = 3 + y
+   [<CLIEvent>]
+   member x.MyEvent = (new Event<int>()).Publish
+
+module Nexted = 
+    module M1 = 
+        // This is f
+        let f (x:int) = x
+
+    // This is type C
+    type C() = 
+       /// This is P
+       member x.MyProperty = 3
+       /// This is M
+       member x.MyMethod(y:int) = 3 + y
+       [<CLIEvent>]
+       member x.MyEvent = (new Event<int>()).Publish
+
+
+
+   
\ No newline at end of file
diff --git a/workyard/tests/fsyacc/build.bat b/workyard/tests/fsyacc/build.bat
new file mode 100755
index 0000000..9393d58
--- /dev/null
+++ b/workyard/tests/fsyacc/build.bat
@@ -0,0 +1,123 @@
+setlocal
+if EXIST build.ok DEL /f /q build.ok
+
+call %~d0%~p0..\..\config.bat
+ at if ERRORLEVEL 1 goto Error
+
+if NOT "%FSC:NOTAVAIL=X%" == "%FSC%" ( 
+  REM Skipping test for FSI.EXE
+  goto Skip
+)
+
+
+REM UNICODE test1-unicode
+
+REM Regression test for FSB 1885
+"%FSLEX%" repro1885.fsl
+ at if ERRORLEVEL 1 goto Error
+
+"%FSLEX%" --light-off -o test1lex.fs test1lex.mll
+ at if ERRORLEVEL 1 goto Error
+
+"%FSYACC%" --light-off --module TestParser -o test1.fs test1.mly
+ at if ERRORLEVEL 1 goto Error
+
+"%FSC%" %fsc_flags% -g -o:test1%ILX_SUFFIX%.exe tree.ml test1.fsi test1.fs test1lex.fs main.ml
+ at if ERRORLEVEL 1 goto Error
+
+"%PEVERIFY%" test1%ILX_SUFFIX%.exe 
+ at if ERRORLEVEL 1 goto Error
+
+"%FSYACC%" --light-off --module TestParser -o test2.fs test2.mly
+ at if ERRORLEVEL 1 goto Error
+
+"%FSC%" %fsc_flags% -g -o:test2%ILX_SUFFIX%.exe tree.ml test2.fsi test2.fs test1lex.fs main.ml
+ at if ERRORLEVEL 1 goto Error
+
+"%PEVERIFY%" test2%ILX_SUFFIX%.exe
+ at if ERRORLEVEL 1 goto Error
+
+"%FSLEX%" --light-off --unicode -o test1-unicode-lex.fs test1-unicode-lex.mll
+ at if ERRORLEVEL 1 goto Error
+
+"%FSYACC%" --light-off --module TestParser -o test1-unicode.fs test1-unicode.mly
+ at if ERRORLEVEL 1 goto Error
+
+"%FSC%" %fsc_flags% -g -o:test1-unicode%ILX_SUFFIX%.exe tree.ml test1-unicode.fsi test1-unicode.fs test1-unicode-lex.fs main-unicode.ml
+ at if ERRORLEVEL 1 goto Error
+
+"%PEVERIFY%" test1-unicode%ILX_SUFFIX%.exe 
+ at if ERRORLEVEL 1 goto Error
+
+
+
+"%FSLEX%" -o test1lex.ml test1lex.mll
+ at if ERRORLEVEL 1 goto Error
+
+"%FSYACC%" --module TestParser -o test1.ml test1.mly
+ at if ERRORLEVEL 1 goto Error
+
+"%FSC%" %fsc_flags% -g -o:test1%ILX_SUFFIX%.exe tree.ml test1.mli test1.ml test1lex.ml main.ml
+ at if ERRORLEVEL 1 goto Error
+
+"%PEVERIFY%" test1%ILX_SUFFIX%.exe 
+ at if ERRORLEVEL 1 goto Error
+
+"%FSYACC%" --module TestParser -o test1compat.ml --ml-compatibility test1.mly
+ at if ERRORLEVEL 1 goto Error
+
+"%FSC%" %fsc_flags% -g -o:test1compat%ILX_SUFFIX%.exe tree.ml test1compat.mli test1compat.ml test1lex.ml main.ml
+ at if ERRORLEVEL 1 goto Error
+
+"%PEVERIFY%" test1compat%ILX_SUFFIX%.exe
+ at if ERRORLEVEL 1 goto Error
+
+"%FSYACC%" --module TestParser -o test2.ml test2.mly
+ at if ERRORLEVEL 1 goto Error
+
+"%FSC%" %fsc_flags% -g -o:test2%ILX_SUFFIX%.exe tree.ml test2.mli test2.ml test1lex.ml main.ml
+ at if ERRORLEVEL 1 goto Error
+
+"%PEVERIFY%" test2%ILX_SUFFIX%.exe
+ at if ERRORLEVEL 1 goto Error
+
+"%FSYACC%" --module TestParser -o test2compat.ml --ml-compatibility test2.mly
+ at if ERRORLEVEL 1 goto Error
+
+"%FSC%" %fsc_flags% -g -o:test2compat%ILX_SUFFIX%.exe tree.ml test2compat.mli test2compat.ml test1lex.ml main.ml
+ at if ERRORLEVEL 1 goto Error
+
+"%PEVERIFY%" test2compat%ILX_SUFFIX%.exe
+ at if ERRORLEVEL 1 goto Error
+
+"%FSLEX%" --unicode -o test1-unicode-lex.ml test1-unicode-lex.mll
+ at if ERRORLEVEL 1 goto Error
+
+"%FSYACC%" --module TestParser -o test1-unicode.ml test1-unicode.mly
+ at if ERRORLEVEL 1 goto Error
+
+"%FSC%" %fsc_flags% -g -o:test1-unicode%ILX_SUFFIX%.exe tree.ml test1-unicode.mli test1-unicode.ml test1-unicode-lex.ml main-unicode.ml
+ at if ERRORLEVEL 1 goto Error
+
+"%PEVERIFY%" test1-unicode%ILX_SUFFIX%.exe 
+ at if ERRORLEVEL 1 goto Error
+
+
+
+:Ok
+echo Passed fsharp %~f0 ok.
+echo. > build.ok
+endlocal
+exit /b 0
+
+
+:Skip
+echo Skipped %~f0
+endlocal
+exit /b 0
+
+
+:Error
+call %SCRIPT_ROOT%\ChompErr.bat %ERRORLEVEL% %~f0
+endlocal
+exit /b %ERRORLEVEL%
diff --git a/workyard/tests/fsyacc/example1.fsy b/workyard/tests/fsyacc/example1.fsy
new file mode 100755
index 0000000..d767087
--- /dev/null
+++ b/workyard/tests/fsyacc/example1.fsy
@@ -0,0 +1,14 @@
+%{
+
+%} 
+
+%type <int> ntS
+%token Tc Td
+%start ntS
+
+%%	
+
+ntS: ntC ntC { } 
+ntC: Tc ntC { }
+ntC: Td { } 
+
diff --git a/workyard/tests/fsyacc/example2.fsy b/workyard/tests/fsyacc/example2.fsy
new file mode 100755
index 0000000..9d93a9e
--- /dev/null
+++ b/workyard/tests/fsyacc/example2.fsy
@@ -0,0 +1,14 @@
+%{
+
+%} 
+
+%type <int> a b
+%token A B
+%start a 
+%start b
+
+%%	
+
+a: A { } 
+b: B { }
+
diff --git a/workyard/tests/fsyacc/main-unicode.ml b/workyard/tests/fsyacc/main-unicode.ml
new file mode 100755
index 0000000..d0bcccc
--- /dev/null
+++ b/workyard/tests/fsyacc/main-unicode.ml
@@ -0,0 +1,90 @@
+#light
+
+open Tree
+open System.IO
+let tokenize = ref false
+
+let usage =
+  [ "--tokens", Arg.Set tokenize, "tokenize the first file and exit" ]
+
+let inputs = ref []
+
+let _ = Arg.parse usage (fun x -> inputs := !inputs @ [x]) "test... <filename> <filename>\nTests that all inputs give equivalent syntac trees"
+
+open Microsoft.FSharp.Text.Lexing
+open Microsoft.FSharp.Compatibility.OCaml.Lexing
+
+type UnicodeLexbuf =  LexBuffer<char>
+  
+/// Create a Unicode LexBuffer
+///
+/// F# 1.9.3.6 doesn't have convenient support for creating Unicode Lexbuffers.
+/// This function creates such a buffer and instruments it with the standard support
+/// to update the start/end positions based on character count.
+///
+/// One small annoyance is that LexBuffers and not IDisposable. This means 
+/// we can't just return the LexBuffer object, since the file it wraps wouldn't
+/// get closed when we're finished with the LexBuffer. Hence we return the stream,
+/// the reader and the LexBuffer. The caller should dispose the first two when done.
+let UnicodeFileAsCharLexbuf (filename,codePage : int option) =
+    // Use the .NET functionality to auto-detect the unicode encoding
+    // It also uses Lexing.from_text_reader to present the bytes read to the lexer in UTF8 decoded form
+    let stream  = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read) in
+    let reader = 
+        match codePage with 
+        | None -> new  StreamReader(stream,true)
+        | Some n -> new  StreamReader(stream,System.Text.Encoding.GetEncoding(n)) in
+    let dummyPos = {Lexing.pos_fname=""; Lexing.pos_lnum= 0; Lexing.pos_bol= 0; Lexing.pos_cnum=0 } in
+    let lexbuf = LexBuffer.FromCharFunction((fun buf n -> reader.Read(buf,0,n))) in
+    stream, reader, lexbuf
+
+
+let main() = 
+  if !inputs = [] then
+    Printf.eprintf "at least one input should be given\n";
+  try 
+    let results = 
+      !inputs |> List.map (fun filename -> 
+          let dummyPos = {Lexing.pos_fname=""; Lexing.pos_lnum= 0; Lexing.pos_bol= 0; Lexing.pos_cnum=0 } in
+          let stream,reader,lexbuf = UnicodeFileAsCharLexbuf(filename,None) in 
+          use stream = stream
+          use reader = reader
+          if !tokenize then begin 
+            while true do 
+              Printf.eprintf "tokenize - getting one token\n";
+              let t = TestLexer.token lexbuf in 
+              Printf.eprintf "tokenize - got %s, now at char %d\n" (TestParser.token_to_string t) lexbuf.StartPos.AbsoluteOffset;
+              match t with 
+              | TestParser.EOF -> exit 0;
+              | TestParser.IDENT s -> 
+                  for c in s do
+                      Printf.eprintf "   ident char = %d\n" (Char.code c)
+                  done;
+              | _ -> ()
+                      
+            done;
+          end;
+          let tree = 
+            try TestParser.start TestLexer.token lexbuf 
+            with e -> 
+              Printf.eprintf "%s(%d,%d): error: %s\n" filename lexbuf.StartPos.Line lexbuf.StartPos.Column (match e with Failure s -> s | _ -> Printexc.to_string e);
+              exit 1 in 
+          Printf.eprintf "parsed %s ok\n" filename;
+          (filename,tree)) in 
+    for (filename1,tree1) in results do
+        for (filename2,tree2) in results do
+            if filename1 > filename2 then 
+              if tree1 <> tree2 then 
+                  Printf.eprintf "file %s and file %s parsed to different results!\n" filename1 filename2;
+                  let rec ptree os (Node(n,l)) = Printf.fprintf os "(%s %a)" n ptrees l
+                  and ptrees os l = match l with [] -> () | [h] -> ptree os h | h::t -> Printf.fprintf os "%a %a" ptree h ptrees t in 
+                  Printf.eprintf "file %s = %a\n" filename1 ptree tree1;
+                  Printf.eprintf "file %s = %a\n" filename2 ptree tree2;
+                  exit 1
+  with e -> 
+    Printf.eprintf "Error: %s\n" (match e with Failure s -> s | e -> e.ToString());
+    exit 1
+   
+
+let _ = main ()
+
diff --git a/workyard/tests/fsyacc/main.ml b/workyard/tests/fsyacc/main.ml
new file mode 100755
index 0000000..b5cf2de
--- /dev/null
+++ b/workyard/tests/fsyacc/main.ml
@@ -0,0 +1,59 @@
+open Tree
+let tokenize = ref false
+
+let usage =
+  [ "--tokens", Arg.Set tokenize, "tokenize the first file and exit" ]
+
+let inputs = ref []
+
+let _ = Arg.parse usage (fun x -> inputs := !inputs @ [x]) "test... <filename> <filename>\nTests that all inputs give equivalent syntac trees"
+
+let main() = 
+  if !inputs = [] then
+    Printf.eprintf "at least one input should be given\n";
+  try 
+    let results = 
+      List.map
+        (fun filename -> 
+          let is = open_in filename in
+          let lexbuf = Lexing.from_channel is in 
+          if !tokenize then begin 
+            while true do 
+              Printf.eprintf "tokenize - getting one token\n";
+              let t = TestLexer.token lexbuf in 
+              Printf.eprintf "tokenize - got %s, now at char %d\n" (TestParser.token_to_string t) (Lexing.lexeme_start_p lexbuf).pos_cnum;
+              if t = TestParser.EOF then exit 0;
+            done;
+          end;
+          let tree = 
+            try TestParser.start TestLexer.token lexbuf 
+            with e -> 
+              Printf.eprintf "%s(%d,%d): error: %s\n" filename (Lexing.lexeme_start_p lexbuf).pos_lnum ((Lexing.lexeme_start_p lexbuf).pos_cnum -  (Lexing.lexeme_start_p lexbuf).pos_bol) (match e with Failure s -> s | _ -> Printexc.to_string e);
+              exit 1 in 
+          Printf.eprintf "parsed %s ok\n" filename;
+          close_in is;
+          (filename,tree))
+        !inputs in 
+    List.iter 
+      (fun (filename1,tree1) -> 
+        List.iter 
+          (fun (filename2,tree2) -> 
+            if filename1 > filename2 then 
+              if tree1 <> tree2 then 
+                begin 
+                  Printf.eprintf "file %s and file %s parsed to different results!\n" filename1 filename2;
+                  let rec ptree os (Node(n,l)) = Printf.fprintf os "(%s %a)" n ptrees l
+                  and ptrees os l = match l with [] -> () | [h] -> ptree os h | h::t -> Printf.fprintf os "%a %a" ptree h ptrees t in 
+                  Printf.eprintf "file %s = %a\n" filename1 ptree tree1;
+                  Printf.eprintf "file %s = %a\n" filename2 ptree tree2;
+                  exit 1;
+                end)
+        results)
+      results;
+  with e -> 
+    Printf.eprintf "Error: %s\n" (match e with Failure s -> s | e -> e.ToString());
+    exit 1
+   
+
+let _ = main ()
+
diff --git a/workyard/tests/fsyacc/repro1885.fsl b/workyard/tests/fsyacc/repro1885.fsl
new file mode 100755
index 0000000..9a2de16
--- /dev/null
+++ b/workyard/tests/fsyacc/repro1885.fsl
@@ -0,0 +1,61 @@
+{
+(*
+	Repro of FSharp Bugs 1885, "FSLex doesn't ignore strings in comments"
+*)
+
+open System
+
+(*
+Testcase "                                                                      <--------------------------
+*)
+
+(*
+Testcase "asdfasdfasdf"                                                         <--------------------------
+*)
+
+// Opens methods related to fslex.exe
+open Lexing
+
+// All of our token types are now generated by fsYacc
+open Parser
+
+
+let inc_lnum bol pos = 
+  let lnum = pos.pos_lnum in 
+  {pos with pos_lnum =  lnum+1; pos_bol = bol }
+
+let newline lexbuf = 
+  lexbuf_set_curr_p lexbuf 
+    ( inc_lnum (lexeme_end lexbuf) (lexeme_end_p lexbuf))
+
+// Convert a string such as "\"c:\\windows\\\"" into "c:\windows\"             <--------------------------
+// "another testcase"                                                          <--------------------------
+// "and another                                                                <--------------------------
+let normalizeString (str : string) =
+    let str = str.Replace("\\\"", "\"")
+    let str = str.Replace("\\\\", "\\")
+    if str.[0] = '\"' && str.[str.Length - 1] = '\"' then
+        str.Substring(1, str.Length - 2)
+    else
+        str
+
+}
+
+// Regular expressions
+let whitespace = [' ' '\t' ]
+let newline = ('\n' | '\r' '\n')
+let str = '\"' [^ '\"']* '\"'
+
+rule tokenstream = parse
+// --------------------------
+| "{"		{ LCURLY }
+| "}"		{ RCURLY }
+| "=" 		{ EQUALS }
+// --------------------------
+|  str		{ STR(lexeme lexbuf) }
+// --------------------------
+| whitespace	{ tokenstream lexbuf }
+| newline	{ newline lexbuf; tokenstream lexbuf }
+// --------------------------
+| _    		{ STR("ParseError" + (lexeme lexbuf)) }
+| eof   	{ EOF }
\ No newline at end of file
diff --git a/workyard/tests/fsyacc/run.bat b/workyard/tests/fsyacc/run.bat
new file mode 100755
index 0000000..41647bc
--- /dev/null
+++ b/workyard/tests/fsyacc/run.bat
@@ -0,0 +1,96 @@
+ at if "%_echo%"=="" echo off
+
+setlocal 
+dir build.ok > NUL ) || (
+  @echo 'build.ok' not found.
+  goto :ERROR
+)
+
+call %~d0%~p0..\..\config.bat
+if ERRORLEVEL 1 goto Error
+
+
+for /f  %%i in ("%FSDIFF%") do (
+ dir %%i% > NUL
+ if ERRORLEVEL 1 goto Error
+)
+
+%CLIX% .\test1.exe --tokens .\test1.input1 2> test1.input1.tokens.err
+if ERRORLEVEL 1 goto Error
+
+%CLIX% .\test1.exe .\test1.input1 2> test1.input1.err
+if ERRORLEVEL 1 goto Error
+
+%CLIX% .\test1.exe .\test1.input2.variation1  .\test1.input2.variation2 2> test1.input2.err
+if ERRORLEVEL 1 goto Error
+
+
+%CLIX% .\test1-unicode.exe --tokens .\test1.input1 2> test1-unicode.input1.tokens.err
+if ERRORLEVEL 1 goto Error
+
+%CLIX% .\test1-unicode.exe .\test1.input1 2> test1-unicode.input1.err
+if ERRORLEVEL 1 goto Error
+
+%CLIX% .\test1-unicode.exe .\test1.input2.variation1  .\test1.input2.variation2 2> test1-unicode.input2.err
+if ERRORLEVEL 1 goto Error
+
+%CLIX% .\test1-unicode.exe --tokens .\test1-unicode.input3.utf8 2> test1-unicode.input3.tokens.err
+if ERRORLEVEL 1 goto Error
+
+
+
+%CLIX% .\test1compat.exe --tokens .\test1.input1 2> test1compat.input1.tokens.err
+if ERRORLEVEL 1 goto Error
+
+%CLIX% .\test1compat.exe .\test1.input1 2> test1comapt.input1.err
+if ERRORLEVEL 1 goto Error
+
+%CLIX% .\test1compat.exe .\test1.input2.variation1  .\test1.input2.variation2 2> test1compat.input2.err
+if ERRORLEVEL 1 goto Error
+
+
+%CLIX% .\test2.exe --tokens .\test2.input1 2> test2.input1.tokens.err
+if ERRORLEVEL 1 goto Error
+
+%CLIX% .\test2.exe --tokens .\test2.badInput 2> test1.badInput.tokens.err
+if ERRORLEVEL 1 goto Error
+
+%CLIX% .\test2.exe .\test2.input1 2> test2.input1.err
+if ERRORLEVEL 1 goto Error
+
+%CLIX% .\test2.exe .\test2.badInput 2> test1.badInput.err
+if ERRORLEVEL 1 goto Error
+
+
+for /d %%f IN (test1.input1.tokens test1.input1 test1.input2 test1-unicode.input1.tokens test1-unicode.input1 test1-unicode.input2 test1-unicode.input3.tokens test1compat.input1.tokens test1comapt.input1 test1compat.input2 test2.input1.tokens test1.badInput.tokens test2.input1 test1.badInput) do (
+  echo ***** FSDIFF=%FSDIFF%, f = %%f
+  %FSDIFF% %%f.err %%f.bsl > %%f.diff
+  for /f %%c IN (%%f.diff) do (
+    echo ***** %%f.err %%f.bsl differed: a bug or baseline may neeed updating
+
+    IF DEFINED WINDIFF (start %windiff% %%f.bsl  %%f.err)
+    goto SETERROR 
+  )
+  echo Good, output %%f.err matched %%f.bsl
+)
+
+:Ok
+echo Ran fsharp %~f0 ok.
+endlocal
+exit /b 0
+
+:Skip
+echo Skipped %~f0
+endlocal
+exit /b 0
+
+
+:Error
+call %SCRIPT_ROOT%\ChompErr.bat 1 %~f0
+endlocal
+exit /b %ERRORLEVEL%
+
+
+:SETERROR
+set NonexistentErrorLevel 2> nul
+goto Error
diff --git a/workyard/tests/fsyacc/test1-unicode-lex.mll b/workyard/tests/fsyacc/test1-unicode-lex.mll
new file mode 100755
index 0000000..4225dac
--- /dev/null
+++ b/workyard/tests/fsyacc/test1-unicode-lex.mll
@@ -0,0 +1,53 @@
+
+{
+module TestLexer
+open TestParser
+} 
+
+(* These specifications follow the C# specification *)
+let digit = '\Nd'
+let letter = '\Lu' | '\Ll' | '\Lm' | '\Lo' | '\Nl'
+
+let ident_start_char = letter | ['_'] 
+
+let connecting_char = '\Pc'
+let combining_char = '\Mn' | '\Mc'
+let formatting_char = '\Cf' 
+let ident_char = letter | digit | connecting_char | combining_char | formatting_char
+
+let ident = ident_start_char ident_char*
+
+let whitespace = 
+    '\Zs' 
+  | '\u0009' (* horizontal tab *)
+  | '\u000B' (* vertical tab *)
+  | '\u000C' (* form feed *)
+  | '\u000D' (* carriage return *)
+  | '\u000A' (* line feed *)
+  | '\u0085' (* next line *)
+  | '\u2028' (* line separator *)
+  | '\u2029' (* paragraph separator *)
+
+
+rule token = parse
+ | "(" { LPAREN }
+  (* the "approx equals" symbol, just to test a random specific Unicode character *)
+ | '≈'+ { IDENT(new System.String(lexbuf.Lexeme) ) }
+ (* | '\U00002248'+ { IDENT(new System.String(lexbuf.Lexeme) ) } *)
+ 
+  (* the "not equals" symbol, just to test a random specific Unicode character *)
+ | '≠'+ { IDENT(new System.String(lexbuf.Lexeme) ) } 
+(* | '\U00002260'+ { IDENT(new System.String(lexbuf.Lexeme) ) } *)
+ | ")" { RPAREN }
+ | "*" { STAR }
+ | "+" { PLUS }
+ | "-" { MINUS }
+ | ident { let s = new System.String(lexbuf.Lexeme) in 
+           match s with 
+           |  "let" -> LET
+           | "in" -> IN
+           | "end" -> END
+           | _ -> IDENT(s) }
+ | whitespace  { token lexbuf }
+ | eof  { EOF }
+
diff --git a/workyard/tests/fsyacc/test1-unicode.input1.bsl b/workyard/tests/fsyacc/test1-unicode.input1.bsl
new file mode 100755
index 0000000..88c7622
--- /dev/null
+++ b/workyard/tests/fsyacc/test1-unicode.input1.bsl
@@ -0,0 +1 @@
+parsed .\test1.input1 ok
diff --git a/workyard/tests/fsyacc/test1-unicode.input1.tokens.bsl b/workyard/tests/fsyacc/test1-unicode.input1.tokens.bsl
new file mode 100755
index 0000000..9fb8cee
--- /dev/null
+++ b/workyard/tests/fsyacc/test1-unicode.input1.tokens.bsl
@@ -0,0 +1,12 @@
+tokenize - getting one token
+tokenize - got IDENT, now at char 2
+   ident char = 105
+   ident char = 100
+tokenize - getting one token
+tokenize - got PLUS, now at char 5
+tokenize - getting one token
+tokenize - got IDENT, now at char 7
+   ident char = 105
+   ident char = 100
+tokenize - getting one token
+tokenize - got EOF, now at char 11
diff --git a/workyard/tests/fsyacc/test1-unicode.input2.bsl b/workyard/tests/fsyacc/test1-unicode.input2.bsl
new file mode 100755
index 0000000..43661ea
--- /dev/null
+++ b/workyard/tests/fsyacc/test1-unicode.input2.bsl
@@ -0,0 +1,2 @@
+parsed .\test1.input2.variation1 ok
+parsed .\test1.input2.variation2 ok
diff --git a/workyard/tests/fsyacc/test1-unicode.input3.tokens.bsl b/workyard/tests/fsyacc/test1-unicode.input3.tokens.bsl
new file mode 100755
index 0000000..2ae2daa
--- /dev/null
+++ b/workyard/tests/fsyacc/test1-unicode.input3.tokens.bsl
@@ -0,0 +1,244 @@
+tokenize - getting one token
+tokenize - got IDENT, now at char 2
+   ident char = 110
+   ident char = 101
+   ident char = 120
+   ident char = 116
+tokenize - getting one token
+tokenize - got IDENT, now at char 7
+   ident char = 108
+   ident char = 105
+   ident char = 110
+   ident char = 101
+tokenize - getting one token
+tokenize - got IDENT, now at char 12
+   ident char = 116
+   ident char = 101
+   ident char = 115
+   ident char = 116
+   ident char = 115
+tokenize - getting one token
+tokenize - got IDENT, now at char 18
+   ident char = 111
+   ident char = 110
+   ident char = 101
+tokenize - getting one token
+tokenize - got IDENT, now at char 22
+   ident char = 117
+   ident char = 110
+   ident char = 105
+   ident char = 99
+   ident char = 111
+   ident char = 100
+   ident char = 101
+tokenize - getting one token
+tokenize - got IDENT, now at char 30
+   ident char = 99
+   ident char = 104
+   ident char = 97
+   ident char = 114
+   ident char = 97
+   ident char = 99
+   ident char = 116
+   ident char = 101
+   ident char = 114
+tokenize - getting one token
+tokenize - got IDENT, now at char 40
+   ident char = 99
+   ident char = 108
+   ident char = 97
+   ident char = 115
+   ident char = 115
+tokenize - getting one token
+tokenize - got IDENT, now at char 47
+   ident char = 196
+   ident char = 203
+   ident char = 214
+   ident char = 207
+   ident char = 220
+   ident char = 226
+   ident char = 230
+   ident char = 231
+   ident char = 241
+   ident char = 245
+   ident char = 246
+tokenize - getting one token
+tokenize - got PLUS, now at char 59
+tokenize - getting one token
+tokenize - got IDENT, now at char 61
+   ident char = 105
+   ident char = 100
+tokenize - getting one token
+tokenize - got IDENT, now at char 65
+   ident char = 110
+   ident char = 101
+   ident char = 120
+   ident char = 116
+tokenize - getting one token
+tokenize - got IDENT, now at char 70
+   ident char = 108
+   ident char = 105
+   ident char = 110
+   ident char = 101
+tokenize - getting one token
+tokenize - got IDENT, now at char 75
+   ident char = 116
+   ident char = 101
+   ident char = 115
+   ident char = 116
+   ident char = 115
+tokenize - getting one token
+tokenize - got IDENT, now at char 81
+   ident char = 115
+   ident char = 112
+   ident char = 101
+   ident char = 99
+   ident char = 105
+   ident char = 102
+   ident char = 105
+   ident char = 99
+tokenize - getting one token
+tokenize - got IDENT, now at char 90
+   ident char = 117
+   ident char = 110
+   ident char = 105
+   ident char = 99
+   ident char = 111
+   ident char = 100
+   ident char = 101
+tokenize - getting one token
+tokenize - got IDENT, now at char 98
+   ident char = 99
+   ident char = 104
+   ident char = 97
+   ident char = 114
+   ident char = 97
+   ident char = 99
+   ident char = 116
+   ident char = 101
+   ident char = 114
+   ident char = 115
+tokenize - getting one token
+tokenize - got IDENT, now at char 110
+   ident char = 8800
+tokenize - getting one token
+tokenize - got IDENT, now at char 112
+   ident char = 8800
+   ident char = 8800
+tokenize - getting one token
+tokenize - got IDENT, now at char 115
+   ident char = 8776
+   ident char = 8776
+tokenize - getting one token
+tokenize - got IDENT, now at char 118
+   ident char = 8776
+   ident char = 8776
+   ident char = 8776
+tokenize - getting one token
+tokenize - got IDENT, now at char 123
+   ident char = 105
+   ident char = 100
+tokenize - getting one token
+tokenize - got PLUS, now at char 126
+tokenize - getting one token
+tokenize - got IDENT, now at char 128
+   ident char = 105
+   ident char = 100
+tokenize - getting one token
+tokenize - got IDENT, now at char 132
+   ident char = 110
+   ident char = 101
+   ident char = 120
+   ident char = 116
+tokenize - getting one token
+tokenize - got IDENT, now at char 137
+   ident char = 108
+   ident char = 105
+   ident char = 110
+   ident char = 101
+tokenize - getting one token
+tokenize - got IDENT, now at char 142
+   ident char = 116
+   ident char = 101
+   ident char = 115
+   ident char = 116
+   ident char = 115
+tokenize - getting one token
+tokenize - got IDENT, now at char 148
+   ident char = 115
+   ident char = 111
+   ident char = 109
+   ident char = 101
+tokenize - getting one token
+tokenize - got IDENT, now at char 153
+   ident char = 109
+   ident char = 111
+   ident char = 114
+   ident char = 101
+tokenize - getting one token
+tokenize - got IDENT, now at char 158
+   ident char = 114
+   ident char = 97
+   ident char = 110
+   ident char = 100
+   ident char = 111
+   ident char = 109
+tokenize - getting one token
+tokenize - got IDENT, now at char 165
+   ident char = 117
+   ident char = 110
+   ident char = 105
+   ident char = 99
+   ident char = 111
+   ident char = 100
+   ident char = 101
+tokenize - getting one token
+tokenize - got IDENT, now at char 173
+   ident char = 99
+   ident char = 104
+   ident char = 97
+   ident char = 114
+   ident char = 97
+   ident char = 99
+   ident char = 116
+   ident char = 101
+   ident char = 114
+   ident char = 115
+tokenize - getting one token
+tokenize - got IDENT, now at char 185
+   ident char = 1052
+   ident char = 1053
+   ident char = 1054
+   ident char = 1055
+   ident char = 1056
+   ident char = 1057
+   ident char = 1058
+   ident char = 1059
+   ident char = 1060
+   ident char = 1061
+   ident char = 1062
+   ident char = 7808
+   ident char = 7809
+   ident char = 7810
+   ident char = 1116
+tokenize - getting one token
+tokenize - got IDENT, now at char 201
+   ident char = 945
+   ident char = 946
+   ident char = 923
+   ident char = 920
+   ident char = 937
+   ident char = 936
+   ident char = 935
+   ident char = 931
+   ident char = 948
+   ident char = 950
+   ident char = 538
+   ident char = 374
+   ident char = 506
+tokenize - getting one token
+tokenize - got IDENT, now at char 216
+   ident char = 105
+   ident char = 100
+tokenize - getting one token
+tokenize - got EOF, now at char 218
diff --git a/workyard/tests/fsyacc/test1-unicode.input3.utf8 b/workyard/tests/fsyacc/test1-unicode.input3.utf8
new file mode 100755
index 0000000..3581150
--- /dev/null
+++ b/workyard/tests/fsyacc/test1-unicode.input3.utf8
@@ -0,0 +1,9 @@
+
+next line tests one unicode character class
+ÄËÖÏÜâæçñõö + id
+next line tests specific unicode characters
+≠ ≠≠ ≈≈ ≈≈≈
+id + id
+next line tests some more random unicode characters
+МНОПРСТУФХЦẀẁẂќ αβΛΘΩΨΧΣδζȚŶǺ
+id
\ No newline at end of file
diff --git a/workyard/tests/fsyacc/test1-unicode.mly b/workyard/tests/fsyacc/test1-unicode.mly
new file mode 100755
index 0000000..98516b4
--- /dev/null
+++ b/workyard/tests/fsyacc/test1-unicode.mly
@@ -0,0 +1,30 @@
+%{
+//module TestParser
+
+%} 
+
+%type <Tree.tree> start
+%token MINUS STAR LPAREN RPAREN PLUS EOF LET IN END UNICODE1 UNICODE2
+%token <string> IDENT
+%start start
+
+%right MINUS
+%left PLUS
+%left STAR
+%%	
+
+start: expr EOF { $1 }
+
+decl: IDENT expr { Tree.Node("decl",[$2]) }
+
+expr:  expr MINUS expr { Tree.Node("-",[$1;$3]) } 
+|  expr PLUS expr { Tree.Node("+",[$1;$3]) } 
+|  expr STAR expr { Tree.Node("*",[$1;$3]) } 
+|  LPAREN expr RPAREN { $2 } 
+|  IDENT { Tree.Node($1,[]) } 
+|  LET decl IN expr END { $4 } 
+|  UNICODE1 {  Tree.Node("UNICODE1",[])} 
+|  UNICODE2 {  Tree.Node("UNICODE2",[])} 
+
+
+
diff --git a/workyard/tests/fsyacc/test1.badInput.bsl b/workyard/tests/fsyacc/test1.badInput.bsl
new file mode 100755
index 0000000..8af2ac6
--- /dev/null
+++ b/workyard/tests/fsyacc/test1.badInput.bsl
@@ -0,0 +1,8 @@
+invisible error recovery successful.
+Missing paren: visible recovery successful.
+invisible error recovery successful.
+invisible error recovery successful.
+invisible error recovery successful.
+Three parens is a bit rich - why not use Lisp if you like that sort of thing. Raising explicit parse error, which we will recover from.
+invisible error recovery successful.
+parsed .\test2.badInput ok
diff --git a/workyard/tests/fsyacc/test1.badInput.tokens.bsl b/workyard/tests/fsyacc/test1.badInput.tokens.bsl
new file mode 100755
index 0000000..3336741
--- /dev/null
+++ b/workyard/tests/fsyacc/test1.badInput.tokens.bsl
@@ -0,0 +1,138 @@
+tokenize - getting one token
+tokenize - got IDENT, now at char 2
+tokenize - getting one token
+tokenize - got LPAREN, now at char 5
+tokenize - getting one token
+tokenize - got LET, now at char 6
+tokenize - getting one token
+tokenize - got IDENT, now at char 10
+tokenize - getting one token
+tokenize - got IN, now at char 12
+tokenize - getting one token
+tokenize - got IDENT, now at char 15
+tokenize - getting one token
+tokenize - got END, now at char 18
+tokenize - getting one token
+tokenize - got RPAREN, now at char 21
+tokenize - getting one token
+tokenize - got IDENT, now at char 24
+tokenize - getting one token
+tokenize - got LPAREN, now at char 27
+tokenize - getting one token
+tokenize - got IDENT, now at char 28
+tokenize - getting one token
+tokenize - got PLUS, now at char 31
+tokenize - getting one token
+tokenize - got IDENT, now at char 33
+tokenize - getting one token
+tokenize - got IDENT, now at char 37
+tokenize - getting one token
+tokenize - got LPAREN, now at char 40
+tokenize - getting one token
+tokenize - got IDENT, now at char 41
+tokenize - getting one token
+tokenize - got PLUS, now at char 44
+tokenize - getting one token
+tokenize - got IDENT, now at char 46
+tokenize - getting one token
+tokenize - got PLUS, now at char 49
+tokenize - getting one token
+tokenize - got IDENT, now at char 51
+tokenize - getting one token
+tokenize - got RPAREN, now at char 53
+tokenize - getting one token
+tokenize - got IDENT, now at char 56
+tokenize - getting one token
+tokenize - got LPAREN, now at char 59
+tokenize - getting one token
+tokenize - got IDENT, now at char 60
+tokenize - getting one token
+tokenize - got PLUS, now at char 63
+tokenize - getting one token
+tokenize - got IDENT, now at char 65
+tokenize - getting one token
+tokenize - got STAR, now at char 68
+tokenize - getting one token
+tokenize - got IDENT, now at char 70
+tokenize - getting one token
+tokenize - got RPAREN, now at char 72
+tokenize - getting one token
+tokenize - got IDENT, now at char 75
+tokenize - getting one token
+tokenize - got LPAREN, now at char 78
+tokenize - getting one token
+tokenize - got LET, now at char 79
+tokenize - getting one token
+tokenize - got IDENT, now at char 83
+tokenize - getting one token
+tokenize - got PLUS, now at char 85
+tokenize - getting one token
+tokenize - got IN, now at char 87
+tokenize - getting one token
+tokenize - got IDENT, now at char 90
+tokenize - getting one token
+tokenize - got END, now at char 93
+tokenize - getting one token
+tokenize - got RPAREN, now at char 96
+tokenize - getting one token
+tokenize - got IDENT, now at char 99
+tokenize - getting one token
+tokenize - got LPAREN, now at char 102
+tokenize - getting one token
+tokenize - got LET, now at char 103
+tokenize - getting one token
+tokenize - got IDENT, now at char 107
+tokenize - getting one token
+tokenize - got PLUS, now at char 109
+tokenize - getting one token
+tokenize - got IN, now at char 111
+tokenize - getting one token
+tokenize - got IDENT, now at char 114
+tokenize - getting one token
+tokenize - got END, now at char 117
+tokenize - getting one token
+tokenize - got RPAREN, now at char 120
+tokenize - getting one token
+tokenize - got IDENT, now at char 123
+tokenize - getting one token
+tokenize - got LPAREN, now at char 126
+tokenize - getting one token
+tokenize - got LET, now at char 127
+tokenize - getting one token
+tokenize - got IDENT, now at char 131
+tokenize - getting one token
+tokenize - got PLUS, now at char 133
+tokenize - getting one token
+tokenize - got IDENT, now at char 135
+tokenize - getting one token
+tokenize - got IN, now at char 137
+tokenize - getting one token
+tokenize - got IDENT, now at char 140
+tokenize - getting one token
+tokenize - got END, now at char 143
+tokenize - getting one token
+tokenize - got RPAREN, now at char 146
+tokenize - getting one token
+tokenize - got IDENT, now at char 149
+tokenize - getting one token
+tokenize - got LPAREN, now at char 152
+tokenize - getting one token
+tokenize - got LET, now at char 153
+tokenize - getting one token
+tokenize - got IDENT, now at char 157
+tokenize - getting one token
+tokenize - got RPAREN, now at char 159
+tokenize - getting one token
+tokenize - got RPAREN, now at char 160
+tokenize - getting one token
+tokenize - got RPAREN, now at char 161
+tokenize - getting one token
+tokenize - got IN, now at char 163
+tokenize - getting one token
+tokenize - got IDENT, now at char 166
+tokenize - getting one token
+tokenize - got END, now at char 169
+tokenize - getting one token
+tokenize - got RPAREN, now at char 172
+tokenize - getting one token
+tokenize - got EOF, now at char 177
diff --git a/workyard/tests/fsyacc/test1.input1 b/workyard/tests/fsyacc/test1.input1
new file mode 100755
index 0000000..7b0ecb1
--- /dev/null
+++ b/workyard/tests/fsyacc/test1.input1
@@ -0,0 +1,2 @@
+
+id + id
diff --git a/workyard/tests/fsyacc/test1.input1.bsl b/workyard/tests/fsyacc/test1.input1.bsl
new file mode 100755
index 0000000..88c7622
--- /dev/null
+++ b/workyard/tests/fsyacc/test1.input1.bsl
@@ -0,0 +1 @@
+parsed .\test1.input1 ok
diff --git a/workyard/tests/fsyacc/test1.input1.tokens.bsl b/workyard/tests/fsyacc/test1.input1.tokens.bsl
new file mode 100755
index 0000000..366c548
--- /dev/null
+++ b/workyard/tests/fsyacc/test1.input1.tokens.bsl
@@ -0,0 +1,8 @@
+tokenize - getting one token
+tokenize - got IDENT, now at char 2
+tokenize - getting one token
+tokenize - got PLUS, now at char 5
+tokenize - getting one token
+tokenize - got IDENT, now at char 7
+tokenize - getting one token
+tokenize - got EOF, now at char 11
diff --git a/workyard/tests/fsyacc/test1.input2.bsl b/workyard/tests/fsyacc/test1.input2.bsl
new file mode 100755
index 0000000..43661ea
--- /dev/null
+++ b/workyard/tests/fsyacc/test1.input2.bsl
@@ -0,0 +1,2 @@
+parsed .\test1.input2.variation1 ok
+parsed .\test1.input2.variation2 ok
diff --git a/workyard/tests/fsyacc/test1.input2.variation1 b/workyard/tests/fsyacc/test1.input2.variation1
new file mode 100755
index 0000000..80daa28
--- /dev/null
+++ b/workyard/tests/fsyacc/test1.input2.variation1
@@ -0,0 +1,3 @@
+
+(id + id + id) + (id * id * id) + (id - id - id) + (id + id * id) + (id * id + id)
+
diff --git a/workyard/tests/fsyacc/test1.input2.variation2 b/workyard/tests/fsyacc/test1.input2.variation2
new file mode 100755
index 0000000..498f93c
--- /dev/null
+++ b/workyard/tests/fsyacc/test1.input2.variation2
@@ -0,0 +1,2 @@
+
+(((((id + id) + id) +  ((id * id) * id)) + (id - (id - id))) + (id + (id * id))) + ((id * id) + id)
diff --git a/workyard/tests/fsyacc/test1.mly b/workyard/tests/fsyacc/test1.mly
new file mode 100755
index 0000000..4cc5d9a
--- /dev/null
+++ b/workyard/tests/fsyacc/test1.mly
@@ -0,0 +1,29 @@
+%{
+//module TestParser
+//Bug1885: is about skipping // comments in the header and code sections, rather than lexing as tokens
+//Bug1885: REPRO: Convert a string such as "\"c:\\windows\\\"" into "c:\windows\" 
+%} 
+
+%type <Tree.tree> start
+%token MINUS STAR LPAREN RPAREN PLUS EOF LET IN END
+%token <string> IDENT
+%start start
+
+%right MINUS
+%left PLUS
+%left STAR
+%%      
+
+start: expr EOF { $1 }
+
+decl: IDENT expr { Tree.Node("decl",[$2]) }
+
+expr:  expr MINUS expr { Tree.Node("-",[$1;$3]) } 
+|  expr PLUS expr { Tree.Node("+",[$1;$3]) } 
+|  expr STAR expr { Tree.Node("*",[$1;$3]) } 
+|  LPAREN expr RPAREN { $2 } 
+|  IDENT { Tree.Node($1,[]) } 
+|  LET decl IN expr END { $4 } 
+
+
+
diff --git a/workyard/tests/fsyacc/test1comapt.input1.bsl b/workyard/tests/fsyacc/test1comapt.input1.bsl
new file mode 100755
index 0000000..88c7622
--- /dev/null
+++ b/workyard/tests/fsyacc/test1comapt.input1.bsl
@@ -0,0 +1 @@
+parsed .\test1.input1 ok
diff --git a/workyard/tests/fsyacc/test1compat.input1.tokens.bsl b/workyard/tests/fsyacc/test1compat.input1.tokens.bsl
new file mode 100755
index 0000000..366c548
--- /dev/null
+++ b/workyard/tests/fsyacc/test1compat.input1.tokens.bsl
@@ -0,0 +1,8 @@
+tokenize - getting one token
+tokenize - got IDENT, now at char 2
+tokenize - getting one token
+tokenize - got PLUS, now at char 5
+tokenize - getting one token
+tokenize - got IDENT, now at char 7
+tokenize - getting one token
+tokenize - got EOF, now at char 11
diff --git a/workyard/tests/fsyacc/test1compat.input2.bsl b/workyard/tests/fsyacc/test1compat.input2.bsl
new file mode 100755
index 0000000..43661ea
--- /dev/null
+++ b/workyard/tests/fsyacc/test1compat.input2.bsl
@@ -0,0 +1,2 @@
+parsed .\test1.input2.variation1 ok
+parsed .\test1.input2.variation2 ok
diff --git a/workyard/tests/fsyacc/test1lex.mll b/workyard/tests/fsyacc/test1lex.mll
new file mode 100755
index 0000000..59b1e4f
--- /dev/null
+++ b/workyard/tests/fsyacc/test1lex.mll
@@ -0,0 +1,33 @@
+
+{
+module TestLexer
+open TestParser
+} 
+
+let letter = ['A'-'Z'] | ['a'-'z']
+let digit = ['0'-'9']
+let ident_start_char = 
+    letter | ['_'] 
+let ident_char = ( ident_start_char| digit | ['\''] )
+let ident = ident_start_char ident_char*
+let whitespace = [' ' '\t' '\n' '\r']
+
+
+rule token = parse
+ | "(" { LPAREN }
+ | ")" { RPAREN }
+ | "*" { STAR }
+ | "+" { PLUS }
+ | "-" { MINUS }
+ | "let" { LET }
+ | "in" { IN }
+ | "end" { END }
+ | ident { let s = Lexing.lexeme lexbuf in 
+           match s with 
+           |  "let" -> LET
+           | "in" -> IN
+           | "end" -> END
+           | _ -> IDENT(s) }
+ | whitespace  { token lexbuf }
+ | eof  { EOF }
+
diff --git a/workyard/tests/fsyacc/test2.badInput b/workyard/tests/fsyacc/test2.badInput
new file mode 100755
index 0000000..c45d7a4
--- /dev/null
+++ b/workyard/tests/fsyacc/test2.badInput
@@ -0,0 +1,10 @@
+
+z1 (let x in id end)
+x2 (id + id
+y3 (id + id + id)
+z4 (id + id * id)
+z5 (let x + in id end)
+z6 (let x + in id end)
+z7 (let x + y in id end)
+z8 (let x ))) in id end)
+
diff --git a/workyard/tests/fsyacc/test2.input1 b/workyard/tests/fsyacc/test2.input1
new file mode 100755
index 0000000..206ef1b
--- /dev/null
+++ b/workyard/tests/fsyacc/test2.input1
@@ -0,0 +1,4 @@
+
+x (id + id)
+y (id + id + id)
+z (id + id * id)
diff --git a/workyard/tests/fsyacc/test2.input1.bsl b/workyard/tests/fsyacc/test2.input1.bsl
new file mode 100755
index 0000000..a91819a
--- /dev/null
+++ b/workyard/tests/fsyacc/test2.input1.bsl
@@ -0,0 +1 @@
+parsed .\test2.input1 ok
diff --git a/workyard/tests/fsyacc/test2.input1.tokens.bsl b/workyard/tests/fsyacc/test2.input1.tokens.bsl
new file mode 100755
index 0000000..f83e4ca
--- /dev/null
+++ b/workyard/tests/fsyacc/test2.input1.tokens.bsl
@@ -0,0 +1,46 @@
+tokenize - getting one token
+tokenize - got IDENT, now at char 2
+tokenize - getting one token
+tokenize - got LPAREN, now at char 4
+tokenize - getting one token
+tokenize - got IDENT, now at char 5
+tokenize - getting one token
+tokenize - got PLUS, now at char 8
+tokenize - getting one token
+tokenize - got IDENT, now at char 10
+tokenize - getting one token
+tokenize - got RPAREN, now at char 12
+tokenize - getting one token
+tokenize - got IDENT, now at char 15
+tokenize - getting one token
+tokenize - got LPAREN, now at char 17
+tokenize - getting one token
+tokenize - got IDENT, now at char 18
+tokenize - getting one token
+tokenize - got PLUS, now at char 21
+tokenize - getting one token
+tokenize - got IDENT, now at char 23
+tokenize - getting one token
+tokenize - got PLUS, now at char 26
+tokenize - getting one token
+tokenize - got IDENT, now at char 28
+tokenize - getting one token
+tokenize - got RPAREN, now at char 30
+tokenize - getting one token
+tokenize - got IDENT, now at char 33
+tokenize - getting one token
+tokenize - got LPAREN, now at char 35
+tokenize - getting one token
+tokenize - got IDENT, now at char 36
+tokenize - getting one token
+tokenize - got PLUS, now at char 39
+tokenize - getting one token
+tokenize - got IDENT, now at char 41
+tokenize - getting one token
+tokenize - got STAR, now at char 44
+tokenize - getting one token
+tokenize - got IDENT, now at char 46
+tokenize - getting one token
+tokenize - got RPAREN, now at char 48
+tokenize - getting one token
+tokenize - got EOF, now at char 51
diff --git a/workyard/tests/fsyacc/test2.mly b/workyard/tests/fsyacc/test2.mly
new file mode 100755
index 0000000..ee0778c
--- /dev/null
+++ b/workyard/tests/fsyacc/test2.mly
@@ -0,0 +1,45 @@
+%{
+//module TestParser
+
+/// Stephan Tolksdorf reported a bug where quotation characters in headers and semantic
+/// actions caused the parser generator to fail with an "unterminated string" comment.
+let testQuotationCharInHeader1 = '"'
+let testQuotationCharInHeader2 = '\"'
+
+%} 
+
+%type <Tree.tree> start
+%token MINUS STAR LPAREN RPAREN PLUS EOF LET IN END
+%token <string> IDENT
+%start start
+
+%right MINUS
+%left PLUS
+%left STAR
+%%	
+
+start: decls EOF { System.Console.WriteLine("#decls = {0}.", List.length $1);  Tree.Node("decls",$1) }
+
+decls: decls decl { $2 :: $1 } | decl { [$1] }
+
+
+decl: IDENT expr { 
+    /// Stephan Tolksdorf reported a bug where quotation characters in headers and semantic
+    /// actions caused the parser generator to fail with an "unterminated string" comment.
+    let testQuotationCharInHeader1 = '"' in
+    let testQuotationCharInHeader2 = '\"' in
+    Tree.Node("decl",[$2]) }
+
+expr:  expr MINUS expr { Tree.Node("-",[$1;$3]) } 
+|  expr PLUS expr { Tree.Node("+",[$1;$3]) } 
+|  expr STAR expr { Tree.Node("*",[$1;$3]) } 
+|  LPAREN expr RPAREN { $2 } 
+|  LET decl IN expr END {  $4 } 
+|  LET error IN expr END {  System.Console.Error.WriteLine("invisible error recovery successful."); $4 } 
+|  LPAREN expr error { System.Console.Error.WriteLine("Missing paren: visible recovery successful."); $2 } 
+|  RPAREN RPAREN RPAREN { System.Console.Error.WriteLine("Three parens is a bit rich - why not use Lisp if you like that sort of thing. Raising explicit parse error, which we will recover from."); 
+                          raise Microsoft.FSharp.Text.Parsing.RecoverableParseError } 
+|  IDENT { Tree.Node($1,[]) } 
+
+
+
diff --git a/workyard/tests/fsyacc/tree.ml b/workyard/tests/fsyacc/tree.ml
new file mode 100755
index 0000000..36022dd
--- /dev/null
+++ b/workyard/tests/fsyacc/tree.ml
@@ -0,0 +1,4 @@
+
+type tree = Node of string * tree list 
+type decl = Decl of string * tree
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-cli-libs/packages/powerpack.git



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